Index: .project =================================================================== RCS file: .project diff -N .project --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ .project 12 Feb 2004 05:10:35 -0000 @@ -0,0 +1,11 @@ + + + jakarta-jetspeed + + + + + + + + Index: src/java/org/apache/jetspeed/om/registry/DBRegistry.java =================================================================== RCS file: src/java/org/apache/jetspeed/om/registry/DBRegistry.java diff -N src/java/org/apache/jetspeed/om/registry/DBRegistry.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/java/org/apache/jetspeed/om/registry/DBRegistry.java 12 Feb 2004 05:10:39 -0000 @@ -0,0 +1,41 @@ +/* + * Created on Oct 20, 2003 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package org.apache.jetspeed.om.registry; +import java.util.List; +import org.apache.torque.TorqueException; +/** + * @author susinha + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public interface DBRegistry { + + /** the default database name for this class */ + public static final String DATABASE_NAME = "default"; + + /** + * Method to get data. + * + * @param criteria object used to create the SELECT statement. + * @return List of selected Objects + * @throws TorqueException Any exceptions caught during processing will be + * rethrown wrapped into a TorqueException. + */ + public List getXREGDataFromDb() throws TorqueException; + + /** + * Method to data. + * + * @param timestamp when database service ran last time. + * @return boolean if data has been modified + * @throws TorqueException Any exceptions caught during processing will be + * rethrown wrapped into a TorqueException. + */ + public boolean isModified(String lastUpdateDate ) throws TorqueException; + +} Index: src/java/org/apache/jetspeed/services/registry/DatabaseRegistryService.java =================================================================== RCS file: /home/cvspublic/jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/DatabaseRegistryService.java,v retrieving revision 1.4 diff -u -r1.4 DatabaseRegistryService.java --- src/java/org/apache/jetspeed/services/registry/DatabaseRegistryService.java 23 Jul 2003 19:50:22 -0000 1.4 +++ src/java/org/apache/jetspeed/services/registry/DatabaseRegistryService.java 12 Feb 2004 05:10:40 -0000 @@ -1,285 +1,732 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 +/* + * Created on Oct 19, 2003 * - * Copyright (c) 2000-2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache Jetspeed" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" or - * "Apache Jetspeed", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments */ - package org.apache.jetspeed.services.registry; -// Java classes -import java.util.Hashtable; -import java.util.Enumeration; -import javax.servlet.ServletConfig; +// Jetspeed stuff +import org.apache.jetspeed.om.registry.Registry; +import org.apache.jetspeed.om.registry.RegistryEntry; +import org.apache.jetspeed.om.registry.PortletEntry; +import org.apache.jetspeed.om.registry.RegistryException; +import org.apache.jetspeed.om.registry.base.BaseRegistry; +import org.apache.jetspeed.om.registry.base.LocalRegistry; +import org.apache.jetspeed.om.registry.DBRegistry; + //turbine stuff +import org.apache.turbine.util.Log; import org.apache.turbine.services.InitializationException; import org.apache.turbine.services.TurbineBaseService; import org.apache.turbine.services.TurbineServices; +import org.apache.turbine.services.servlet.ServletService; import org.apache.turbine.services.resources.ResourceService; -// Jetspeed classes -import org.apache.jetspeed.om.registry.Registry; -import org.apache.jetspeed.om.registry.RegistryEntry; -import org.apache.jetspeed.om.registry.RegistryException; -import org.apache.jetspeed.om.registry.base.BaseRegistry; -import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; -import org.apache.jetspeed.services.logging.JetspeedLogger; +//java stuff +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; +import javax.servlet.ServletConfig; +import java.util.Map; +import java.io.Reader; +import java.util.List; /** - *

This is an implementation of the RegistryService - * based on the Jetspeed Database Persistence Manager

- * - *

This service expects the following properties to be set for correct operation: - *

- *
none
+ * @author susinha * - *
- *

- * - * @author David Sean Taylor - * @version $Id: DatabaseRegistryService.java,v 1.4 2003/07/23 19:50:22 morciuch Exp $ + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments */ public class DatabaseRegistryService - extends TurbineBaseService - implements RegistryService -{ - /** - * Static initialization of the logger for this class - */ - private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(DatabaseRegistryService.class.getName()); - - /** regsitry type keyed list of entries */ - private Hashtable registries = new Hashtable(); - - - /** - * Returns a Registry object for further manipulation - * - * @param regName the name of the registry to fetch - * @return a Registry object if found by the manager or null - */ - public Registry get( String regName ) - { - return (Registry)registries.get( regName ); - } - - /** - * List all the registry currently available to this service - * - * @return an Enumeration of registry names. - */ - public Enumeration getNames() - { - return registries.keys(); - } - - /** - * Creates a new RegistryEntry instance compatible with the current - * Registry instance implementation - * - * @param regName the name of the registry to use - * @return the newly created RegistryEntry - */ - public RegistryEntry createEntry(String regName) - { + extends TurbineBaseService + implements RegistryService , FileRegistry + { + + /** The name of this service */ + public String SERVICE_NAME = "DatabaseRegistry"; + + public static final int DEFAULT_VERBOSE = 1; + + /** regsitry type keyed list of entries */ + private Hashtable registries = new Hashtable(); + + /** The list of default fragments stores for newly created objects */ + private Hashtable defaults = new Hashtable(); + + /** The Castor generated RegsitryFragment objects */ + private Hashtable fragments = new Hashtable(); + + /** Associates entries with their fragments name for quick lookup */ + private Hashtable entryIndex = new Hashtable(); + + /** the Watcher object which monitors the regsitry directory */ + private DatabaseRegistryWatcher watcher = null; + + /** Assign the default poolname */ + private final static String POOL_NAME = "database"; + + + /** controls amount of debug output, the bigger the more output will be generated */ + private int verbose = DEFAULT_VERBOSE; + + /** Base class to implement */ + private static Hashtable baseClass = new Hashtable(); + /** + * Returns a Registry object for further manipulation + * + * @param regName the name of the registry to fetch + * @return a Registry object if found by the manager or null + */ + public Registry get(String regName) { + return (Registry) registries.get(regName); + } + + /** + * List all the registry currently available to this service + * + * @return an Enumeration of registry names. + */ + public Enumeration getNames() { + return registries.keys(); + } + + /** + * Creates a new RegistryEntry instance compatible with the current + * Registry instance implementation + * + * @param regName the name of the registry to use + * @return the newly created RegistryEntry + */ + public RegistryEntry createEntry(String regName) { RegistryEntry entry = null; - Registry registry = (Registry) registries.get(regName); + Registry registry = (Registry) registries.get(regName); - if (registry != null) - { + if (registry != null) { entry = registry.createEntry(); - } + } return entry; } + /** + * Returns a RegistryEntry from the named Registry. + * This is a convenience wrapper around {@link + * org.apache.jetspeed.om.registry.Registry#getEntry } + * + * @param regName the name of the registry + * @param entryName the name of the entry to retrieve from the + * registry + * @return a RegistryEntry object if the key is found or null + */ + public RegistryEntry getEntry(String regName, String entryName) { + try { + return ((Registry) registries.get(regName)).getEntry(entryName); + } catch (RegistryException e) { + if (Log.getLogger().isInfoEnabled()) { + Log.info( + "RegistryService: Failed to retrieve " + + entryName + + " from " + + regName); + } + } catch (NullPointerException e) { + Log.error( + "DatabaseRegistryService: " + + regName + + " registry is not known "); + Log.error(e); + } - /** - * Returns a RegistryEntry from the named Registry. - * This is a convenience wrapper around {@link - * org.apache.jetspeed.om.registry.Registry#getEntry } - * - * @param regName the name of the registry - * @param entryName the name of the entry to retrieve from the - * registry - * @return a RegistryEntry object if the key is found or null - */ - public RegistryEntry getEntry( String regName, String entryName ) - { - try - { - return ((Registry)registries.get( regName )).getEntry( entryName ); - } - catch ( RegistryException e ) - { - logger.info("Failed to retrieve "+entryName+" from "+regName); - } - catch ( NullPointerException e ) - { - logger.error(regName + " registry is not known ", e); - } - - return null; - } - - /** - * Add a new RegistryEntry in the named Registry. - * This is a convenience wrapper around {@link - * org.apache.jetspeed.om.registry.Registry#addEntry } - * - * @param regName the name of the registry - * @param entry the Registry entry to add - * @exception Sends a RegistryException if the manager can't add - * the provided entry - */ - public void addEntry(String regName, RegistryEntry entry) throws RegistryException - { - if (entry == null) - { - return; - } - - BaseRegistry registry = (BaseRegistry)registries.get( regName ); - - if (registry!=null) - { - if (this.getEntry(regName, entry.getName())!=null) - { - registry.setLocalEntry(entry); - } - else - { - registry.addLocalEntry(entry); - } - } - } - - /** - * Deletes a RegistryEntry from the named Registry - * This is a convenience wrapper around {@link - * org.apache.jetspeed.om.registry.Registry#removeEntry } - * - * @param regName the name of the registry - * @param entryName the name of the entry to remove - */ - public void removeEntry( String regName, String entryName ) - { - if (entryName==null) - { - return; - } - - BaseRegistry registry = (BaseRegistry)registries.get( regName ); - - if (registry!=null) - { - // the entry is physically removed, remove the dangling reference - registry.removeLocalEntry( entryName ); - } - } - - /** - * This is the early initialization method called by the - * Turbine Service framework - */ - public void init( ServletConfig conf ) throws InitializationException - { - - ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance()) - .getResources(RegistryService.SERVICE_NAME); - - // read the configuration keys - try - { - - } - catch ( Throwable t ) - { - throw new InitializationException( "Unable to initialize DatabaseRegistryService, missing config keys"); - } - - //Mark that we are done - setInit(true); - - // load the registries - // TODO: write this - } - - - /** Late init method from Turbine Service model */ - public void init( ) throws InitializationException - { - logger.debug( "Late init for Registry called" ); - while( !getInit() ) - { - //Not yet... - try - { - Thread.sleep( 500 ); - logger.debug( "Waiting for init of Registry..." ); - } - catch (InterruptedException ie ) - { - logger.error("Exception", ie); - } - } - logger.debug( "We are done! (Registry)" ); - } - - - /** - * This is the shutdown method called by the - * Turbine Service framework - */ - public void shutdown() - { - } + return null; + } + /** + * Add a new RegistryEntry in the named Registry. + * This is a convenience wrapper around {@link + * org.apache.jetspeed.om.registry.Registry#addEntry } + * + * @param regName the name of the registry + * @param entry the Registry entry to add + * @exception Sends a RegistryException if the manager can't add + * the provided entry + */ + public void addEntry(String regName, RegistryEntry entry) + throws RegistryException { + if (entry == null) { + return; + } + + LocalRegistry registry = (LocalRegistry) registries.get(regName); + + if (registry != null) { + String fragmentName = (String) entryIndex.get(entry.getName()); + + if (fragmentName == null) { + // either the entry was deleted or it does not exist + // in both cases, use the default fragment + fragmentName = (String) defaults.get(regName); + } + + RegistryFragment fragment = + (RegistryFragment) fragments.get(fragmentName); + + //Fragment can be (and sometimes is, but should not be) null + if (fragment == null) { + fragment = new RegistryFragment(); + fragment.put(regName, new Vector()); + fragments.put(fragmentName, fragment); + } else { + Vector vectRegistry = (Vector) fragment.get(regName); + if (vectRegistry == null) { + fragment.put(regName, new Vector()); + } + } + + synchronized (entryIndex) { + if (registry.hasEntry(entry.getName())) { + fragment.setEntry(regName, entry); + registry.setLocalEntry(entry); + } else { + fragment.addEntry(regName, entry); + registry.addLocalEntry(entry); + } + + entryIndex.put(entry.getName(), fragmentName); + // mark this fragment so that it's persisted next time + // the registry watcher is running + fragment.setDirty(true); + } + } + } + /** + * Deletes a RegistryEntry from the named Registry + * This is a convenience wrapper around {@link + * org.apache.jetspeed.om.registry.Registry#removeEntry } + * + * @param regName the name of the registry + * @param entryName the name of the entry to remove + */ + public void removeEntry(String regName, String entryName) { + if (entryName == null) { + return; + } + + LocalRegistry registry = (LocalRegistry) registries.get(regName); + + if (registry != null) { + String fragmentName = (String) entryIndex.get(entryName); + + if (fragmentName != null) { + RegistryFragment fragment = + (RegistryFragment) fragments.get(fragmentName); + + synchronized (entryIndex) { + fragment.removeEntry(regName, entryName); + entryIndex.remove(entryName); + + // mark this fragment so that it's persisted next time + // the registry watcher is running + fragment.setDirty(true); + } + } + + // the entry is physically removed, remove the dangling reference + registry.removeLocalEntry(entryName); + } + } + /** + * This is the early initialization method called by the + * Turbine Service framework + */ + public synchronized void init(ServletConfig conf) + throws InitializationException { + + int refreshRate = 0; + Vector names = new Vector(); + + //Ensure that the servlet service is initialized + TurbineServices.getInstance().initService( + ServletService.SERVICE_NAME, + conf); + + ResourceService serviceConf = + ((TurbineServices) TurbineServices.getInstance()).getResources( + this.SERVICE_NAME); + + //build the map of default fragments, eahc registry must be associated + //with at least one fragment + try { + + refreshRate = serviceConf.getInt("refreshRate", DEFAULT_REFRESH); + ResourceService defaults = serviceConf.getResources("default"); + Iterator i = defaults.getKeys(); + + while (i.hasNext()) { + String name = (String) i.next(); + // add this name in the list of available registries + + names.add(name); + try { + String registryClass = + "org.apache.jetspeed.om.dbportal.BaseJetspeed" + + name + + "Peer"; + + baseClass.put( + name, + (DBRegistry) Class + .forName(registryClass) + .newInstance()); + } catch (Exception e) { + + if (Log.getLogger().isWarnEnabled()) { + Log.warn( + "DatabaseRegistryService: Class " + + name + + " not found"); + } + + } + + } + } catch (Throwable t) { + throw new InitializationException("Unable to initialize DatabaseRegistryService, missing config keys"); + } + + this.watcher = new DatabaseRegistryWatcher(); + this.watcher.setSubscriber(this); + + if (refreshRate == 0) { + this.watcher.setDone(); + } else { + this.watcher.setRefreshRate(refreshRate); + } + // changing the base will trigger a synchronous loading of the fragments + this.watcher.changeBase(names); + + //Mark that we are done + setInit(true); + + // load the registries + Enumeration en = names.elements(); + + while (en.hasMoreElements()) { + String name = (String) en.nextElement(); + Registry registry = (Registry) registries.get(name); + + if (registry == null) { + String registryClass = null; + try { + + RegistryService localeService = + (RegistryService) TurbineServices + .getInstance() + .getService( + RegistryService.SERVICE_NAME); + + registry = localeService.get(name); + + } catch (Exception e) { + if (Log.getLogger().isWarnEnabled()) { + Log.warn( + "DatabaseRegistryService: Class " + + registryClass + + " not found, reverting to default Registry"); + } + registry = new BaseRegistry(); + } + 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 (Log.getLogger().isDebugEnabled()) { + Log.debug( + "DatabaseRegistryService: early init()....end!, this.getInit()= " + + getInit()); + } + } + /** + * @return a Map of all fragments keyed by file names + */ + public Map getFragmentMap() { + return (Map) fragments.clone(); + } + + /** Late init method from Turbine Service model */ + public void init() throws InitializationException { + if (Log.getLogger().isDebugEnabled()) { + Log.debug("DatabaseRegistryService: Late init called"); + } + while (!getInit()) { + //Not yet... + try { + Thread.sleep(500); + if ((verbose > 2) && Log.getLogger().isDebugEnabled()) { + Log.debug( + "DatabaseRegistryService: Waiting for init of Registry..."); + } + } catch (InterruptedException ie) { + Log.error(ie); + } + } + + if (Log.getLogger().isDebugEnabled()) { + Log.debug("DatabaseRegistryService: We are done"); + } + } + /** + * This is the shutdown method called by the + * Turbine Service framework + */ + public void shutdown() { + + this.watcher.setDone(); + + Iterator i = fragments.keySet().iterator(); + while (i.hasNext()) { + saveFragment((String) i.next()); + } + } + /** + * 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 (Log.getLogger().isDebugEnabled()) { + Log.debug( + "DatabaseRegistryService: 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) { + Log.error( + "DatabaseRegistryService: 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 ((verbose > 2) && Log.getLogger().isDebugEnabled()) { + Log.debug( + "DatabaseRegistryService: 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 ((verbose > 2) + && Log.getLogger().isDebugEnabled()) { + Log.debug( + "DatabaseRegistryService: No changes to entry " + + entry.getName()); + } + } else { + if ((verbose > 1) + && Log.getLogger().isDebugEnabled()) { + Log.debug( + "DatabaseRegistryService: 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 ((verbose > 1) + && Log.getLogger().isDebugEnabled()) { + Log.debug( + "DatabaseRegistryService: Adding entry " + + entry.getName() + + " of class " + + entry.getClass() + + " to registry " + + name); + } + } + } catch (RegistryException e) { + Log.error( + "DatabaseRegistryService: 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 ((verbose > 1) && Log.getLogger().isDebugEnabled()) { + Log.debug( + "DatabaseRegistryService: removing entry " + entryName); + } + //TODO may be I will do it later + //it should delete only portlets which is coming from database + + //registry.removeLocalEntry(entryName); + } + + if ((verbose > 1) && Log.getLogger().isDebugEnabled()) { + Log.debug( + "DatabaseRegistryService: Merged " + + count + + " entries and deleted " + + toDelete.size() + + " in " + + name); + } + } + + // 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()); + } + } + } + + /** + * Load and unmarshal a RegistryFragment from the file + * @param file the absolute file path storing this fragment + */ + public void loadFragment(String file ) { + try { + + RegistryFragment fragment = createFragment(file); + //mark this fragment as changed + fragment.setChanged(true); + + // if we get here, we successfully loaded the new fragment + updateFragment(file, fragment); + + } catch (Throwable t) { + Log.error( + "DatabaseRegistryService: Could not unmarshal: " + file, + t); + } + + } + + /** + * Read and unmarshal a fragment in memory + * @param name the name of 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 { + } catch (Throwable t) { + Log.error( + "DatabaseRegistryService: Could not create fragment: " + file, + t); + } finally { + try { + reader.close(); + } catch (Exception e) { + Log.error(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) { + + /** + * TODO I will implement this + * should go to database + */ + + } + /** + * 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); + } + } + } + /** + * 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); + } + } + } + } + + //class specific implementation + private static List getData(String name) { + List list = null; + try { + + DBRegistry BaseClass = (DBRegistry) baseClass.get(name); + if (BaseClass != null) { + list = BaseClass.getXREGDataFromDb(); + }else{ + Log.warn( + "DatabaseRegistryService: Base class for service " + name + " not found"); + } + } catch (Exception ex) { + Log.warn( + "DatabaseRegistryService: Base class for service " + name + " not found"); + + } + return list; + } + private RegistryFragment createFragment(String regName) { + + RegistryFragment fragment = (RegistryFragment) fragments.get(regName); + + //Fragment can be (and sometimes is, but should not be) null + if (fragment == null) { + fragment = new RegistryFragment(); + fragment.put(regName, new Vector()); + } else { + Vector vectRegistry = (Vector) fragment.get(regName); + if (vectRegistry == null) { + fragment.put(regName, new Vector()); + } + } + List entries = getData(regName); + if (entries != null) { + for (int i = 0; i < entries.size(); i++) { + fragment.setEntry(regName, (RegistryEntry) entries.get(i)); + // mark this fragment so that it's persisted next time + // the registry watcher is running + fragment.setDirty(true); + } + }else{ + Log.warn( + "DatabaseRegistryService:no data fouund for service " + name ); + + } + return fragment; + + } } Index: src/java/org/apache/jetspeed/services/registry/DatabaseRegistryWatcher.java =================================================================== RCS file: src/java/org/apache/jetspeed/services/registry/DatabaseRegistryWatcher.java diff -N src/java/org/apache/jetspeed/services/registry/DatabaseRegistryWatcher.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/java/org/apache/jetspeed/services/registry/DatabaseRegistryWatcher.java 12 Feb 2004 05:10:40 -0000 @@ -0,0 +1,257 @@ +/* + * Created on Oct 20, 2003 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package org.apache.jetspeed.services.registry; + +import org.apache.turbine.util.Log; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Vector; +import java.text.SimpleDateFormat; + +/** + * @author susinha + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class DatabaseRegistryWatcher extends Thread { + /** Minimum scan rate for evaluating file refresh */ + public static final int SCAN_RATE = 10; + + /** + The files monitored by this watcher + */ + private Hashtable files = new Hashtable(); + + /** + the refresh rate, in milliseconds, to use for monitoring this file + */ + private long refreshRate = 0; + + /** + The object that relies on this RegsitryWatcher + */ + private FileRegistry subscriber = null; + + /** + * This object marks that we are done + */ + private boolean done = false; + + /** + * Creates a default RegistryWatcher + */ + public DatabaseRegistryWatcher() { + setDaemon(true); + setPriority(Thread.MIN_PRIORITY); + } + + /** Modifies the subscriber to this Watcher + * + * @param registry the new registry subscriber + */ + public void setSubscriber(FileRegistry registry) { + + synchronized (this) { + + if (subscriber != null) { + Enumeration en = files.keys(); + while (en.hasMoreElements()) { + try { + subscriber.removeFragment(((String) en.nextElement())); + } catch (Exception e) { + Log.error("RegistryWatcher: Can't remove fragment", e); + } + } + } + + this.subscriber = registry; + + if (subscriber != null) { + Enumeration en = files.keys(); + while (en.hasMoreElements()) { + try { + subscriber.loadFragment(((String) en.nextElement())); + } catch (Exception e) { + Log.error("RegistryWatcher: Can't load fragment", e); + } + } + } + } + } + /** @return the subscriber to this watcher */ + public FileRegistry getSubscriber() { + return this.subscriber; + } + + /** Sets the refresh rate for this watcher + * @param refresh the refresh rate in seconds + */ + public void setRefreshRate(long refresh) { + this.refreshRate = ((refresh > SCAN_RATE) ? refresh : SCAN_RATE) * 1000; + } + + /** @return the refresh rate, in seconds, of this watcher */ + public long getRefreshRate() { + return refreshRate / 1000; + } + + /** Change the base file to be monitored by this watcher + * + * @param f the file to monitor + */ + public void changeBase(Vector f) { + synchronized (this) { + if (this.subscriber != null) { + Enumeration en = files.keys(); + while (en.hasMoreElements()) { + try { + subscriber.removeFragment(((String) en.nextElement())); + } catch (Exception e) { + Log.error("RegistryWatcher: Can't remove fragment", e); + } + } + } + files.clear(); + findFiles(f); + } + } + + /** + * Refresh the monitored file list + * + * @param f the file or directory to monitor + */ + private void findFiles(Vector s) { + + Enumeration en = s.elements(); + while (en.hasMoreElements()) { + String f = (String) en.nextElement(); + if (f != null) { + this.files.put(f, "now"); + } + } + } + + /** + *

Main routine for the monitor which periodically checks whether + * the filex have been modified.

+ * The algorithm used does not guarantee a constant refresh rate + * between invocations. + */ + public void run() { + try { + + while (!done) { + boolean needRefresh = false; + + synchronized (this) { + Map fragments = subscriber.getFragmentMap(); + + if (Log.getLogger().isDebugEnabled()) { + Log.debug("RegistryWatcher: Saving dirty fragments."); + } + + Iterator i = fragments.keySet().iterator(); + while (i.hasNext()) { + try { + String filename = (String) i.next(); + RegistryFragment fragment = + (RegistryFragment) subscriber + .getFragmentMap() + .get( + filename); + + // if fragment has some uncommitted changes + if (fragment.isDirty()) { + + + //and update the stored timestamp + Enumeration en = files.keys(); + while (en.hasMoreElements()) { + String f = (String) en.nextElement(); + //get Current time + SimpleDateFormat sdf = new SimpleDateFormat("dd-mm-yyyy hh:mm:ss"); + java.util.Date now = new java.util.Date(); + String currentTime = sdf.format(now); + if (filename.equals(f)) { + files.put(f, currentTime); + } + } + } + } catch (Exception e) { + Log.error( + "RegistryWatcher: exception during update", + e); + } + } + + if (Log.getLogger().isDebugEnabled()) { + Log.debug( + "RegistryWatcher: Checking for updated files."); + } + + Enumeration en = files.keys(); + while (en.hasMoreElements()) { + try { + String f = (String) en.nextElement(); + String modified = (String) files.get(f); + + subscriber.loadFragment(f); + + RegistryFragment frag = + (RegistryFragment) fragments.get(f); + + if (frag != null) { + frag.setChanged(true); + } + + needRefresh = true; + + } catch (Exception e) { + Log.error( + "RegistryWatcher: exception during update", + e); + } + } + + if (needRefresh) { + subscriber.refresh(); + needRefresh = false; + } + + // make sure to reset the state of all fragments + i = fragments.keySet().iterator(); + while (i.hasNext()) { + RegistryFragment frag = + (RegistryFragment) fragments.get((String) i.next()); + frag.setDirty(false); + frag.setChanged(false); + } + } + + sleep(refreshRate); + } + } catch (InterruptedException e) { + + Log.error("RegistryWatcher: Stopping monitor: "); + Log.error(e); + return; + } + } + + /** + * Mark that the watching thread should be stopped + */ + public void setDone() { + done = true; + Log.info("RegistryWatcher: Watching thread stop requested"); + } + +} Index: src/sql/ojb/oracle-registry.sql =================================================================== RCS file: /home/cvspublic/jakarta-jetspeed/src/sql/ojb/oracle-registry.sql,v retrieving revision 1.1 diff -u -r1.1 oracle-registry.sql --- src/sql/ojb/oracle-registry.sql 1 Apr 2002 23:12:21 -0000 1.1 +++ src/sql/ojb/oracle-registry.sql 12 Feb 2004 05:10:40 -0000 @@ -36,6 +36,8 @@ -- parameters -- media types -- categories + security varchar(200), + lastupdate date, constraint uk_portlet_name unique(name) ); Index: webapp/WEB-INF/conf/JetspeedResources.properties =================================================================== RCS file: /home/cvspublic/jakarta-jetspeed/webapp/WEB-INF/conf/JetspeedResources.properties,v retrieving revision 1.112 diff -u -r1.112 JetspeedResources.properties --- webapp/WEB-INF/conf/JetspeedResources.properties 20 Nov 2003 02:51:03 -0000 1.112 +++ webapp/WEB-INF/conf/JetspeedResources.properties 12 Feb 2004 05:10:41 -0000 @@ -330,6 +330,18 @@ # Refresh rate, in seconds. 0 = no refresh. Min value = 60 services.Registry.refreshRate=300 + +######################################### +# DATABASE Registry Service # +######################################### +#services.DatabaseRegistry.classname=org.apache.jetspeed.services.registry.DatabaseRegistryService +#services.DatabaseRegistry.default.Portlet=true +#services.DatabaseRegistry.default.Skin=true + +# Refresh rate, in seconds. 0 = no refresh. Min value = 60 +#services.DatabaseRegistry.refreshRate=300 + + ######################################### # PSMLManager Service # #########################################