castorregistryservice.java

来自「jetspeed源代码」· Java 代码 · 共 908 行 · 第 1/2 页

JAVA
908
字号

                registries.put(name, registry);
            }

            refresh(name);
        }

        // Start the directory watcher thread and rely on its refresh process
        // to completely load all registries
        if (this.watcher != null)
        {
            this.watcher.start();
        }

        if (logger.isDebugEnabled())
        {
            logger.debug("RegistryService: early init()....end!, this.getInit()= " + getInit());
        }

    }


    /** Late init method from Turbine Service model */
    public void init() throws InitializationException
    {
        if (logger.isDebugEnabled())
        {
            logger.debug("RegistryService: Late init called");
        }

        while (!getInit())
        {
            //Not yet...
            try
            {
                Thread.sleep(500);
                if (logger.isDebugEnabled())
                {
                    logger.debug("RegistryService: Waiting for init of Registry...");
                }
            }
            catch (InterruptedException ie)
            {
                logger.error("Exception", ie);
            }
        }

        if (logger.isDebugEnabled())
        {
            logger.debug("RegistryService: We are done");
        }
    }

    /**
     * This is the shutdown method called by the
     * Turbine <code>Service</code> framework
     */
    public void shutdown()
    {
        this.watcher.setDone();

        Iterator i = fragments.keySet().iterator();
        while (i.hasNext())
        {
            saveFragment((String) i.next());
        }
    }

    // FileRegistry interface

    /** Refresh the state of the registry implementation. Should be called
     *   whenever the underlying fragments are modified
     */
    public void refresh()
    {
        synchronized (watcher)
        {
            Enumeration en = getNames();
            while (en.hasMoreElements())
            {
                refresh((String) en.nextElement());
            }
        }
    }

    /**
     * @return a Map of all fragments keyed by file names
     */
    public Map getFragmentMap()
    {
        return (Map) fragments.clone();
    }

    /**
     * Load and unmarshal a RegistryFragment from the file
     * @param file the absolute file path storing this fragment
     */
    public void loadFragment(String file)
    {
        try
        {
            DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = dbfactory.newDocumentBuilder();
       
            Document d = builder.parse(new File(file));

            Unmarshaller unmarshaller = new Unmarshaller(this.mapping);
            RegistryFragment fragment = (RegistryFragment) unmarshaller.unmarshal((Node) d);

            //mark this fragment as changed
            fragment.setChanged(true);

            // if we get here, we successfully loaded the new fragment
            updateFragment(file, fragment);

        }
        catch (Throwable t)
        {
            logger.error("RegistryService: Could not unmarshal: " + file, t);
        }

    }

    /**
     * Read and unmarshal a fragment in memory
     * @param name the name of this fragment
     * @param reader the reader to use for creating this fragment
     * @param persistent whether this fragment should be persisted on disk in
     * the registry
     */
    public void createFragment(String name, Reader reader, boolean persistent)
    {
        String file = null;

        try
        {
            synchronized(watcher)
            {
                file = new File(directory, name + extension).getCanonicalPath();
    
                Unmarshaller unmarshaller = new Unmarshaller(this.mapping);
                RegistryFragment fragment = (RegistryFragment) unmarshaller.unmarshal(reader);
    
                fragment.setChanged(true);
    
                updateFragment(file, fragment);
    
                if (persistent)
                {
                    saveFragment(file);
                }
            }
        }
        catch (Throwable t)
        {
            logger.error("RegistryService: Could not create fragment: " + file, t);
        }
        finally
        {
            try
            {
                reader.close();
            }
            catch (Exception e)
            {
                logger.error("Exception", e);  // At least log the exception.
            }
        }
    }

    /**
     * Marshal and save a RegistryFragment to disk
     * @param file the absolute file path storing this fragment
     */
    public void saveFragment(String file)
    {
        OutputStreamWriter writer = null;
        FileOutputStream fos = null;
        String encoding = new String("UTF-8");
        RegistryFragment fragment = (RegistryFragment) fragments.get(file);

        if (fragment != null)
        {
            try
            {
            	fos = new FileOutputStream(file);
                writer = new OutputStreamWriter(fos, encoding);
                format.setEncoding(encoding);
                Serializer serializer = new XMLSerializer(writer, format);
                Marshaller marshaller = new Marshaller(serializer.asDocumentHandler());
                marshaller.setMapping(this.mapping);
                marshaller.marshal(fragment);
            }
            catch (Throwable t)
            {
                logger.error("RegistryService: Could not marshal: " + file, t);
            }
            finally
            {
                try
                {
                    writer.close();
                }
                catch (Exception e)
                {
                    logger.error("Exception", e);  // At least log the exception.
                }
                
                try
                {
                    fos.close();
                }
                catch (Exception e)
                {
                    logger.error("Exception", e);  // At least log the exception.
                }
            }
        }
    }

    /**
     * Remove a fragment from storage
     * @param file the absolute file path storing this fragment
     */
    public void removeFragment(String file)
    {
        RegistryFragment fragment = (RegistryFragment) fragments.get(file);

        if (fragment != null)
        {
            synchronized (entryIndex)
            {
                // clear the entry index
                Iterator i = entryIndex.keySet().iterator();
                while (i.hasNext())
                {
                    if (file.equals(entryIndex.get(i.next())))
                    {
                        i.remove();
                    }
                }

                // make sure the keys & entries are freed for this fragment
                // only the entries not replaced by the next registry refresh will
                // stay in memory
                fragment.clear();
                // remove the actual fragment from memory
                fragments.remove(file);
            }
        }
    }

    // Implementation specific methods

    /**
     * Updates a fragment in storage and the associated entryIndex
     */
    protected void updateFragment(String name, RegistryFragment fragment)
    {
        synchronized (entryIndex)
        {
            // remove the old keys
            Iterator i = entryIndex.keySet().iterator();
            while (i.hasNext())
            {
                if (name.equals(entryIndex.get(i.next())))
                {
                    i.remove();
                }
            }

            // store the new fragment
            fragments.put(name, fragment);

            // recreate the index entries (only this fragment)

            Enumeration enum = fragment.keys();
            while (enum.hasMoreElements())
            {
                String strReg = (String) enum.nextElement();
                Vector v = fragment.getEntries(strReg);

                for (int counter = 0; counter < v.size(); counter++)
                {
                    RegistryEntry str = (RegistryEntry) v.elementAt(counter);
                    entryIndex.put(str.getName(), name);
                }
            }
        }
    }

    /**
     * Scan all the registry fragments for new entries relevant to
     * this registry and update its definition.
     *
     * @param regName the name of the Registry to refresh
     */
    protected void refresh(String regName)
    {

        if (logger.isDebugEnabled())
        {
            logger.debug("RegistryService: Updating the " + regName + " registry");
        }

        int count = 0;
        int counDeleted = 0;
        LocalRegistry registry = (LocalRegistry) get(regName);

        Vector toDelete = new Vector();
        Iterator i = registry.listEntryNames();

        while (i.hasNext())
        {
            toDelete.add(i.next());
        }

        if (registry == null)
        {
            logger.error("RegistryService: Null " + name + " registry in refresh");
            return;
        }

        // for each fragment...
        Enumeration en = fragments.keys();
        while (en.hasMoreElements())
        {
            String location = (String) en.nextElement();
            RegistryFragment fragment = (RegistryFragment) fragments.get(location);
            int fragCount = 0;

            if (!fragment.hasChanged())
            {
                if (logger.isDebugEnabled())
                {
                    logger.debug("RegistryService: Skipping fragment " + location);
                }

                //remove this fragment entries from the delete list
                Vector entries = fragment.getEntries(regName);
                i = entries.iterator();
                while (i.hasNext())
                {
                    toDelete.remove(((RegistryEntry) i.next()).getName());
                }

                continue;
            }

            //the fragment has some changes, iterate over its entries...

            Vector entries = fragment.getEntries(regName);

            //... if it has entries related to this regsistry,
            if (entries != null)
            {
                // for all these entries
                Enumeration en2 = entries.elements();
                while (en2.hasMoreElements())
                {
                    RegistryEntry entry = (RegistryEntry) en2.nextElement();
                    // update or add the entry in the registry
                    try
                    {
                        if (registry.hasEntry(entry.getName()))
                        {
                            if (registry.getEntry(entry.getName()).equals(entry))
                            {
                                if (logger.isDebugEnabled())
                                {
                                    logger.debug("RegistryService: No changes to entry " + entry.getName());
                                }
                            }
                            else
                            {
                                if (logger.isDebugEnabled())
                                {
                                    logger.debug("RegistryService: Updating entry " + entry.getName() 
                                        + " of class " + entry.getClass() + " to registry " + name);
                                }

                                registry.setLocalEntry(entry);
                                // Initialize the entry index
                                this.entryIndex.put(entry.getName(), location);
                                ++fragCount;
                            }
                        }
                        else
                        {
                            registry.addLocalEntry(entry);
                            // Initialize the entry index
                            this.entryIndex.put(entry.getName(), location);
                            ++fragCount;

                            if (logger.isDebugEnabled())
                            {
                                logger.debug("RegistryService: Adding entry " + entry.getName() + " of class " 
                                    + entry.getClass() + " to registry " + name);
                            }
                        }
                    }
                    catch (RegistryException e)
                    {
                        logger.error("RegistryService: RegistryException while adding " + entry.getName() + "from " + location, e);
                    }

                    //remove this entry from the delete list
                    toDelete.remove(entry.getName());
                }
            }

            count += fragCount;
        }

        //now delete the entries not found in any fragment
        i = toDelete.iterator();
        while (i.hasNext())
        {
            String entryName = (String) i.next();

            if (logger.isDebugEnabled())
            {
                logger.debug("RegistryService: removing entry " + entryName);
            }

            registry.removeLocalEntry(entryName);
        }


        if (logger.isDebugEnabled())
        {
            logger.debug("RegistryService: Merged " + count + " entries and deleted " + toDelete.size() + " in " + name);
        }
    }


    /** FileFilter implementing a file extension based filter */
    class ExtFileFilter implements FileFilter
    {
        private String extension = null;

        ExtFileFilter(String extension)
        {
            this.extension = extension;
        }

        public boolean accept(File f)
        {
            return f.toString().endsWith(extension);
        }
    }

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?