Package org.apache.slide.common

Source Code of org.apache.slide.common.Namespace

/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/common/Namespace.java,v 1.56.2.2 2004/02/05 16:05:04 mholz Exp $
* $Revision: 1.56.2.2 $
* $Date: 2004/02/05 16:05:04 $
*
* ====================================================================
*
* Copyright 1999-2002 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.slide.common;

import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;

import org.apache.slide.authenticate.CredentialsToken;
import org.apache.slide.content.ContentInterceptor;
import org.apache.slide.store.ContentStore;
import org.apache.slide.store.LockStore;
import org.apache.slide.store.NodeStore;
import org.apache.slide.store.RevisionDescriptorStore;
import org.apache.slide.store.RevisionDescriptorsStore;
import org.apache.slide.store.SecurityStore;
import org.apache.slide.store.Store;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.SubjectNode;
import org.apache.slide.transaction.SlideTransactionManager;
import org.apache.slide.util.conf.Configuration;
import org.apache.slide.util.conf.ConfigurationException;
import org.apache.slide.util.logger.Logger;

/**
* A Namespace contains a hierarchically organized tree of information.
*
* <p>
*   Objects in the namespace are generally referred to as <i>Nodes</i>. Nodes
*   may have a parent, children, content and meta-data. They can also be
*   versioned (so that multiple revisions of the object's content and
*   metadata are stored) and locked (so that only specific principals are
*   allowed to read or modify the object). In addition, access control
*   information can be assigned to every node.
* </p>
* <p>
*   Nodes in the hierarchy are identified by their URI (Unique Resource
*   Identifier). A URI is analogous to a file path in traditional file
*   systems. For example:
*   <pre>
*     /users/john/documents/my_document.txt
*   </pre>
*   As you can see, the slash (&quot;/&quot;) is used to separate nodes in the path.
* </p>
* <p>
*   Client applications can not access a Namespace object directly. Instead,
*   access must be requested from the {@link Domain Domain}, which will hand
*   out a proxy object ({@link NamespaceAccessToken NamespaceAccessToken})
*   that enables the client application to access the namespace using the
*   helpers.
* </p>
* <p>
*   Namespaces are necessarily self-contained. What this means is that a
*   namespace cannot reference or contain links to another namespace. A
*   namespace is typically assigned per-application, which effectively
*   isolates it's data and security context from those of other applications.
* </p>
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @author Dirk Verbeeck
* @version $Revision: 1.56.2.2 $
*/
public final class Namespace {
   
   
    // -------------------------------------------------------------- Constants
   
   
    public static final String REFERENCE = "reference";
    public static final String NODE_STORE = "nodestore";
    public static final String SECURITY_STORE = "securitystore";
    public static final String LOCK_STORE = "lockstore";
    public static final String REVISION_DESCRIPTORS_STORE =
        "revisiondescriptorsstore";
    public static final String REVISION_DESCRIPTOR_STORE =
        "revisiondescriptorstore";
    public static final String CONTENT_STORE = "contentstore";
   
   
    /**
     * Log channel for logger
     */
    private static final String LOG_CHANNEL = Namespace.class.getName();
   
    protected static final String I_CREATESTORELISTENERCLASS         = "createStoreListenerClass";
    protected static final String I_CREATESTORELISTENERCLASS_DEFAULT = "org.apache.slide.webdav.util.UriHandler";
   
    protected static Class createStoreListenerClass;
    static {
        try {
            String createStoreListenerClassName = Domain.getParameter(I_CREATESTORELISTENERCLASS, I_CREATESTORELISTENERCLASS_DEFAULT);
            createStoreListenerClass = Class.forName( createStoreListenerClassName );
        }
        catch( Exception x ) {
            Domain.warn( "Loading of create_store_listener class failed: "+x.getMessage() );
        }
    }
   
    // ----------------------------------------------------- Instance Variables
   
   
    /**
     * Namespace name.
     */
    private String name;
   
   
    /**
     * classname of the search implementation
     */
    private String searchClassName;
   
   
    /**
     * Static Vector which holds a reference, and provides access to all
     * the services instances used by the Slide namespace.
     */
    private transient Vector connectedServices;
   
   
    /**
     * Registered DescriptorStores on this Namespace.
     */
    private transient Hashtable stores;
   
   
    /**
     * Current namespace configuration.
     */
    private NamespaceConfig config;
   
   
    /**
     * Uri cache.
     */
    private Hashtable uriCache;
   
   
    /**
     * Default descriptors store classname.
     */
    private String defaultStoreClassname =
        "org.apache.slide.store.ExtendedStore";
   
   
    /**
     * Transaction manager associated with this namespace.
     */
    private TransactionManager transactionManager =
        new SlideTransactionManager();
   
   
    /**
     * Logger.
     */
    private Logger logger;
   
   
    /**
     * Application logger.
     */
    private Logger applicationLogger;
   
   
    // ------------------------------------------------------------ Constructor
   
   
    /**
     * Constructor.
     */
    Namespace() {
        stores = new Hashtable();
        connectedServices = new Vector();
        name = new String();
        uriCache = new Hashtable();
    }
   
   
    // ------------------------------------------------------------- Properties
   
   
    /**
     * Sets the qualified name of the namespace.
     *
     * @param name Name of the namespace
     */
    public void setName(String name) {
        this.name = name;
    }
   
   
    /**
     * Gets the qulified name of the namespace.
     *
     * @return String Namespace name
     */
    public String getName() {
        return name;
    }
   
   
    /**
     * Method setSearchClassName
     *
     * @param    searchClassName     classname of the search implementation
     */
    public void setSearchClassName (String searchClassName) {
        this.searchClassName = searchClassName;
    }
   
   
    /**
     * Method getSearchClassName
     *
     * @return   classname of the search implementation
     */
    public String getSearchClassName()  {
        return searchClassName;
    }
   
   
    /**
     * Returns the namespace configuration.
     *
     * @return NamespaceConfig Namespace configuration
     */
    public NamespaceConfig getConfig() {
        return config;
    }
   
   
    /**
     * Enumerate all scopes managed by this namespace.
     *
     * @return     return an enumeration of all scopes
     */
    public Enumeration enumerateScopes() {
        return stores.keys();
    }
   
   
   
    /**
     * Transaction manager accessor.
     */
    public TransactionManager getTransactionManager() {
        return transactionManager;
    }
   
   
    /**
     * Return the current logger.
     */
    public Logger getLogger() {
        if (logger != null)
            return logger;
        else
            return Domain.getLogger();
    }
   
   
    /**
     * Set the logger used by this namespace.
     */
    public void setLogger(Logger logger) {
        this.logger = logger;
        if (transactionManager instanceof SlideTransactionManager) {
            ((SlideTransactionManager) transactionManager).setLogger(logger);
        }
    }
   
   
    /**
     * Return the current application logger.
     */
    public Logger getApplicationLogger() {
        if (applicationLogger != null)
            return applicationLogger;
        else if (logger != null)
            return logger;
        else
            return Domain.getLogger();
    }
   
   
    /**
     * Set the logger used by this namespace.
     */
    public void setApplicationLogger(Logger logger) {
        this.applicationLogger = logger;
    }
   
   
    // --------------------------------------------------------- Public Methods
   
   
    /**
     * Used to register a Store in the namespace for the specified scope.
     * First, the function instantiate the Store, then gives it
     * its init parameters. It is then stored in the stores
     * Hashtable, associated with the given scope.
     *
     * @param storeClass Class of the Data Source
     * @param parameters Init parameters for the Data Source
     * @param scope Scope for which the Data Source is registered
     * @param childStores Instances of the typed stores
     * @exception ServiceRegistrationFailed An error occured during
     * instantiation of the service
     * @exception ServiceParameterErrorException Incorrect service parameter
     * @exception ServiceParameterMissingException Service parameter missing
     */
    public void registerStore(String storeName, Class storeClass,
                              Hashtable parameters, Scope scope,
                              Hashtable childStores)
        throws ServiceRegistrationFailedException,
        ServiceParameterErrorException, ServiceParameterMissingException {
        if (!stores.containsKey(scope)) {
            try {
                Store store = (Store) storeClass.newInstance();
                store.setName(storeName);
                store.setParameters(parameters);
                stores.put(scope, store);
               
                // Now assigning the child stores
                Object nodeStore = childStores.get(NODE_STORE);
                if (nodeStore instanceof String) {
                    // Resolving reference
                    store.setNodeStore((NodeStore) childStores.get(nodeStore));
                } else {
                    store.setNodeStore((NodeStore) nodeStore);
                }
               
                Object securityStore = childStores.get(SECURITY_STORE);
                if (securityStore instanceof String) {
                    // Resolving reference
                    store.setSecurityStore
                        ((SecurityStore) childStores.get(securityStore));
                } else {
                    store.setSecurityStore
                        ((SecurityStore) securityStore);
                }
               
                Object lockStore = childStores.get(LOCK_STORE);
                if (lockStore instanceof String) {
                    store.setLockStore
                        ((LockStore) childStores.get(lockStore));
                } else {
                    store.setLockStore((LockStore) lockStore);
                }
               
                Object revisionDescriptorsStore = childStores
                    .get(REVISION_DESCRIPTORS_STORE);
                if (revisionDescriptorsStore instanceof String) {
                    store.setRevisionDescriptorsStore
                        ((RevisionDescriptorsStore) childStores
                             .get(revisionDescriptorsStore));
                } else {
                    store.setRevisionDescriptorsStore
                        ((RevisionDescriptorsStore) revisionDescriptorsStore);
                }
               
                Object revisionDescriptorStore = childStores
                    .get(REVISION_DESCRIPTOR_STORE);
                if (revisionDescriptorStore instanceof String) {
                    store.setRevisionDescriptorStore
                        ((RevisionDescriptorStore) childStores
                             .get(revisionDescriptorStore));
                } else {
                    store.setRevisionDescriptorStore
                        ((RevisionDescriptorStore) revisionDescriptorStore);
                }
               
                Object contentStore = childStores.get(CONTENT_STORE);
                if (contentStore instanceof String) {
                    // Resolving reference
                    store.setContentStore
                        ((ContentStore) childStores.get(contentStore));
                } else {
                    store.setContentStore((ContentStore) contentStore);
                }
               
                // set the scope in the father and child stores
                store.setScope(scope);
               
                // call the create_store_listener
                notifyStoreCreated( this.name, scope.toString(), storeName );
               
            } catch(InstantiationException e) {
                throw new ServiceRegistrationFailedException
                    (storeClass);
            } catch(IllegalAccessException e) {
                throw new ServiceRegistrationFailedException
                    (storeClass);
            } catch(NullPointerException e) {
                throw new ServiceRegistrationFailedException
                    (storeClass);
            } catch(ClassCastException e) {
                // TEMP
                getLogger().log(e,LOG_CHANNEL, Logger.ERROR);
                // --TEMP
                throw new ServiceRegistrationFailedException
                    (storeClass);
            }
           
        }
    }
   
   
    /**
     * At the end of the service registration, this service is called to
     * perform any required initialization task.
     *
     * @exception ServicesInitializationFailedException One or more
     * exception occured while initializing services
     */
    public void initializeServices()
        throws ServicesInitializationFailedException {
       
        // We create the nested exception which will hold all thrown exception
        // during the initialization process.
        ServicesInitializationFailedException nestedException
            = new ServicesInitializationFailedException();
       
        // Initializing DesciptorsStores
        Enumeration serviceList = stores.elements();
        while (serviceList.hasMoreElements()) {
            Service service = (Service) serviceList.nextElement();
            try {
                getLogger().log("Initializing Store " + service,LOG_CHANNEL,Logger.INFO);
                service.setNamespace(this);
                service.initialize(new NamespaceAccessTokenImpl(this));
            } catch (ServiceInitializationFailedException e) {
                // We add the exception which just occured to the
                // nested exception
                nestedException.addException(e);
            }
        }
       
        // If the nested exception is not empty, we throw it.
        if (!nestedException.isEmpty()) {
            throw nestedException;
        }
       
    }
   
   
    /**
     * Reinitialize namespace.
     */
    public void clearNamespace() {
        stores.clear();
    }
   
   
    /**
     * Connects a data source on demand.
     *
     * @param service Service on which a connection attempt will be made
     * @param token the credentials token containing e.g. the credential
     * @exception ServiceConnectionFailedException Error connecting service
     * @exception ServiceAccessException Unspecified low level service
     * access exception
     */
    public void connectService(Service service, CredentialsToken token)
        throws ServiceConnectionFailedException, ServiceAccessException {
        // Try to connect ...
        boolean newConnection = service.connectIfNeeded(token);
       
        // If successfull (ie, no exception was thrown), we add it to the list
        // of the connected components.
        if (newConnection) {
            connectedServices.addElement(service);
        }
    }
   
   
    /**
     * Disconnects all services.
     *
     * @exception ServicesShutDownFailedException Error disconnecting one or
     * more services
     */
    public void disconnectServices()
        throws ServicesShutDownFailedException {
       
        // We create the nested exception which will hold all thrown exception
        // during shut down of services.
        ServicesShutDownFailedException nestedException
            = new ServicesShutDownFailedException();
       
        for (int i=0; i<connectedServices.size(); i++) {
            try {
                Service service = (Service) connectedServices.elementAt(i);
                if (service.isConnected()) {
                    getLogger().log("Shutting down service " + service,LOG_CHANNEL,Logger.INFO);
                    service.disconnect();
                }
            } catch (ServiceDisconnectionFailedException e) {
                nestedException.addException(e);
            } catch (ServiceAccessException e) {
                nestedException.addException(e);
            }
        }
        connectedServices.removeAllElements();
       
        // If the nested exception is not empty, we throw it.
        if (!nestedException.isEmpty()) {
            throw nestedException;
        }
       
    }
   
   
    /**
     * Remove a Store from the registry.
     *
     * @param scope Scope to disconnect
     * @exception ServiceDisconnctionFailedException Error disconnecting
     * DescriptorsStore
     * @exception ServiceAccessException Unspecified error during
     * service access
     */
    public void unregisterStore(Scope scope)
        throws ServiceDisconnectionFailedException, ServiceAccessException {
        if (stores.containsKey(scope)) {
            Store store = (Store) stores.get(scope);
            if (store.isConnected()) {
                store.disconnect();
                connectedServices.removeElement(store);
            }
            stores.remove(scope);
            store = null;
        }
    }
   
   
    /**
     * Get the Data Source associated with the given scope, if any.
     * In contrary to the retrieveStore method, this methos does not
     * perform a connection.
     *
     * @param scope Scope to match
     */
    public Store getStore(Scope scope) {
        Store store = null;
        if (stores.containsKey(scope)) {
            store = (Store) stores.get(scope);
        }
        return store;
    }
   
   
    /**
     * Get the Data Source associated with the given scope, if any and
     * connect to the store.
     *
     * @param scope Scope to match
     * @param token the Credeantials token containing e.g. the credential
     * @exception ServiceConnectionFailedException Connection to Store failed
     * @exception ServiceAccessException Unspecified service access exception
     */
    public Store retrieveStore(Scope scope, CredentialsToken token)
        throws ServiceConnectionFailedException, ServiceAccessException {
        Store store = getStore(scope);
        if (store != null) {
            connectService(store, token);
        }
        return store;
    }
   
   
    /**
     * Builds a new uri object to access this namespace. This call will
     * return a Uri which doesn't have its token field set. The store should
     * accept such Uri as valid, and bypass any check that is made based on the
     * state.
     *
     * @param uri Requested Uri
     * @return Uri
     */
    public Uri getUri(String uri) {
        return getUri(null, uri);
    }
   
   
    /**
     * Builds a new uri object to access this namespace.
     *
     * @param token SlideToken
     * @param uri Requested Uri
     * @return Uri
     */
    public Uri getUri(SlideToken token, String uri) {
        return getUri(token, uri, token==null
                          ?false
                          :token.isForceStoreEnlistment());
    }
   
   
    /**
     * Builds a new uri object to access this namespace.
     *
     * @param token SlideToken
     * @param uri Requested Uri
     * @param forcedEnlistment may differ from the value set in token
     * @return Uri
     */
    public Uri getUri(SlideToken token, String uri, boolean forcedEnlistment) {
       
        Uri result = null;
        Object temp = null;
        temp = uriCache.get(uri);
        if (temp == null) {
            result = new Uri(token, this, uri);
            uriCache.put(uri, result);
            if (uriCache.size() > 10000) {
                clearUriCache();
            }
        } else {
            result = (Uri) temp;
            result = result.cloneObject();
            result.setToken(token);
            result.reconnectServices();
        }
       
        // if a different forceEnlistment value want to be used
        // wrap the used token to reflect the different value
        if (token != null && token.isForceStoreEnlistment() != forcedEnlistment) {
            result.setToken(new SlideTokenWrapper(token, forcedEnlistment));
        }
       
        return result;
       
    }
   
   
    /**
     * Clear uri cache.
     */
    void clearUriCache() {
        uriCache.clear();
    }
   
   
    /**
     * Get content interceptors associated with this namespace.
     */
    public ContentInterceptor[] getContentInterceptors() {
        return config.getContentInterceptors();
    }
   
   
    // -------------------------------------------------------- Package Methods
   
   
    /**
     * Parses the contents of the specified definition object, and uses that
     * info to initialize the namespace.
     *
     * @param definition Definiton of the scopes and stores of
     * the namespace
     * @exception SlideException Something went wrong during registry or
     * services initialization
     * @exception ConfigurationException Error parsing configuration file
     */
    void loadDefinition(Configuration definition)
        throws SlideException, ConfigurationException {
       
        getLogger().log("Loading namespace definition",LOG_CHANNEL,Logger.INFO);
       
        // Loading stores
       
        Hashtable storesClass = new Hashtable();
        Hashtable storesParameters = new Hashtable();
        Hashtable childStores = new Hashtable();
       
        Enumeration storeDefinitions =
            definition.getConfigurations("store");
       
        while (storeDefinitions.hasMoreElements()) {
            loadStoreDefinition
                ((Configuration) storeDefinitions.nextElement(),
                 storesClass, storesParameters, childStores);
        }
       
        Enumeration scopeDefinitions =
            definition.getConfigurations("scope");
       
        while (scopeDefinitions.hasMoreElements()) {
            loadScopeDefinition
                ((Configuration) scopeDefinitions.nextElement(),
                 storesClass, storesParameters, childStores);
        }
       
        // Initialize all loaded services.
        initializeServices();
       
    }
   
   
    /**
     * Parses the contents of the specified reader, and uses that info to
     * initialize the specified Slide namespace.
     *
     * @param namespaceBaseDataDefinition Namespace base data
     * @exception SlideException Something went wrong during registry or
     * services initialization
     */
    void loadBaseData(Configuration namespaceBaseDataDefinition)
        throws SlideException, ConfigurationException {
       
        getLogger().log("Loading namespace " + getName() + " base data",LOG_CHANNEL,Logger.INFO);
       
        // Load Namespace Base Data
        try {
            // start transaction for temp object creation
            getTransactionManager().begin();
           
            SlideToken slideToken = new SlideTokenImpl(new CredentialsToken(""));
            slideToken.setForceStoreEnlistment(true);

            // First, we create the root node
            Uri rootUri = getUri(slideToken, "/");
            SubjectNode rootNode = new SubjectNode("/");
            try {
                rootUri.getStore().createObject(rootUri, rootNode);
            } catch (ObjectAlreadyExistsException e) {
                // abort the failed transaction
                getTransactionManager().rollback();
                // start a new one to continue processing
                getTransactionManager().begin();
            }
           
            // end transaction for temp object creation
            getTransactionManager().commit();
           
            getLogger().log("Init namespace " + getName() + " configuration",LOG_CHANNEL,Logger.INFO);
           
            // Create the dummy configuration
            config.initializeAsDummyConfig(this);
           
            // Create the Access token
            NamespaceAccessToken token = new NamespaceAccessTokenImpl(this);
           
            // start the transaction, NOTE some operations are outside this TA
            token.begin();
           
            getLogger().log("Import data into namespace " + getName(),LOG_CHANNEL,Logger.INFO);
            token.importData(slideToken, namespaceBaseDataDefinition);
           
            // end the transaction, NOTE some operations are outside this TA
            token.commit();
           
            // start transaction for temp object removal
            getTransactionManager().begin();
           
            getLogger().log("Finish init namespace " + getName() + " configuration",LOG_CHANNEL,Logger.INFO);
           
            // And remove the all permission from the root node
            rootNode =
                (SubjectNode) rootUri.getStore().retrieveObject(rootUri);
            rootUri.getStore().storeObject(rootUri, rootNode);
           
            // end transaction for temp object removal
            getTransactionManager().commit();
           
        } catch (SlideException e) {
            // If that occurs, then most likely the base config was
            // already done before
            e.printStackTrace();
            getLogger().log("Namespace base configuration was already done before",LOG_CHANNEL,Logger.INFO);
            try {
                if (getTransactionManager().getStatus()==Status.STATUS_ACTIVE)
                    getTransactionManager().rollback();
            }
            catch (SystemException ex) {
                getLogger().log("Could not rollback namespace base configuration: " + ex.toString(),LOG_CHANNEL,Logger.WARNING);
            }
        } catch (Exception e) {
            getLogger().log("Unable to read Namespace base configuration file : ",LOG_CHANNEL,Logger.ERROR);
            getLogger().log(e,LOG_CHANNEL, Logger.ERROR);
            // Unable to load the base configuration XML file.
            // Log the event, and hope it was already done before.
            try {
                if (getTransactionManager().getStatus()==Status.STATUS_ACTIVE)
                    getTransactionManager().rollback();
            }
            catch (SystemException ex) {
                getLogger().log("Could not rollback namespace base configuration after load error: " + ex.toString(),LOG_CHANNEL,Logger.WARNING);
            }
        }
    }
   
   
    /**
     * Parses the contents of the specified reader, and uses that info to
     * initialize the specified Slide namespace.
     *
     * @param namespaceConfigurationDefinition The configuration to load.
     * @exception SlideException Something went wrong during registry or
     * services initialization
     */
    void loadConfiguration(Configuration namespaceConfigurationDefinition)
        throws SlideException {
       
        getLogger().log("Loading namespace " + getName() + " configuration",LOG_CHANNEL,Logger.INFO);
       
        // Load Namespace Config
        config = new NamespaceConfig();
        config.initializeNamespaceConfig(this,
                                         namespaceConfigurationDefinition);
       
    }
   
   
    /**
     * Parses the contents of the specified reader, and uses that info to
     * initialize the specified Slide namespace.
     *
     * @param namespaceConfigurationDefinition Namespace configuration
     * @exception SlideException Something went wrong during registry or
     * services initialization
     */
    void loadParameters(Configuration namespaceConfigurationDefinition)
        throws SlideException {
       
        getLogger().log("Loading namespace " + getName() + " parameters",LOG_CHANNEL,Logger.INFO);
       
        // Load Namespace Config
        config = new NamespaceConfig();
        config.initializeNamespaceParameters(this,
                                             namespaceConfigurationDefinition);
       
    }
   
   
    // -------------------------------------------------------- Private Methods
   
   
    /**
     * Parse the store definition.
     *
     * @param storeDefinition store definition
     * @param storesClass Class names of the stores
     * @param storesParameters Parameters of the stores
     * @param childStores Child stores
     * @exception ConfigurationException Error parsing configuration file
     * @exception SlideException Error loading the specified class
     */
    private void loadStoreDefinition
        (Configuration storeDefinition,
         Hashtable storesClass,
         Hashtable storesParameters,
         Hashtable childStores)
        throws ConfigurationException, SlideException {
       
        String storeName = storeDefinition.getAttribute("name");
        String storeClassname = defaultStoreClassname;
       
        try {
            storeClassname = storeDefinition.getAttribute("classname");
        } catch (ConfigurationException e) {
        }
       
        Enumeration storeParametersDefinitions =
            storeDefinition.getConfigurations("parameter");
       
        // Load descriptors store class
        Class storeClass = null;
        try {
            storeClass = Class.forName(storeClassname);
        } catch (Exception e) {
            getLogger().log(e,LOG_CHANNEL, Logger.ERROR);
            throw new SlideException(e.getMessage());
        }
        storesClass.put(storeName, storeClass);
       
        // Load descriptor store parameters
        Hashtable storeParameters = new Hashtable();
        while (storeParametersDefinitions.hasMoreElements()) {
            Configuration parameterDefinition = (Configuration)
                storeParametersDefinitions.nextElement();
            String parameterName = parameterDefinition.getAttribute("name");
            String parameterValue = parameterDefinition.getValue();
            storeParameters.put(parameterName, parameterValue);
        }
       
        storesParameters.put(storeName, storeParameters);
       
        // Now reading the "child" stores
       
        Hashtable currentStoreChildStores = new Hashtable();
       
        // Loading node store (if any)
        try {
            Configuration nodeStoreDefinition =
                storeDefinition.getConfiguration(NODE_STORE);
            try {
                Configuration referenceDefinition =
                    storeDefinition.getConfiguration(REFERENCE);
                currentStoreChildStores.put
                    (NODE_STORE, referenceDefinition.getAttribute("store"));
                getLogger().log("Node store references " + referenceDefinition.getAttribute("store"),LOG_CHANNEL,Logger.INFO);
            } catch (ConfigurationException ex) {
                getLogger().log("Node store: " + nodeStoreDefinition.getAttribute("classname"),LOG_CHANNEL,Logger.INFO);
                NodeStore nodeStore =
                    (NodeStore) loadChildStore(nodeStoreDefinition,
                                               storeParameters);
                if (nodeStore != null) {
                    currentStoreChildStores.put(NODE_STORE, nodeStore);
                }
            }
        } catch (Exception e) {
        }
       
        // Loading security store (if any)
        try {
            Configuration securityStoreDefinition =
                storeDefinition.getConfiguration(SECURITY_STORE);
            try {
                Configuration referenceDefinition =
                    securityStoreDefinition.getConfiguration(REFERENCE);
                currentStoreChildStores.put
                    (SECURITY_STORE,
                     referenceDefinition.getAttribute("store"));
                getLogger().log("Security store references " + referenceDefinition.getAttribute("store"),LOG_CHANNEL,Logger.INFO);
            } catch (ConfigurationException ex) {
                getLogger().log("Security store: " + securityStoreDefinition.getAttribute("classname"),LOG_CHANNEL,Logger.INFO);
                SecurityStore securityStore =
                    (SecurityStore) loadChildStore(securityStoreDefinition,
                                                   storeParameters);
                if (securityStore != null) {
                    currentStoreChildStores.put(SECURITY_STORE, securityStore);
                }
            }
        } catch (Exception e) {
        }
       
        // Loading lock store (if any)
        try {
            Configuration lockStoreDefinition =
                storeDefinition.getConfiguration(LOCK_STORE);
            try {
                Configuration referenceDefinition =
                    lockStoreDefinition.getConfiguration(REFERENCE);
                currentStoreChildStores.put
                    (LOCK_STORE, referenceDefinition.getAttribute("store"));
                getLogger().log("Lock store store references " + referenceDefinition.getAttribute("store"),LOG_CHANNEL,Logger.INFO);
            } catch (ConfigurationException ex) {
                getLogger().log("Lock store store: " + lockStoreDefinition.getAttribute("classname"),LOG_CHANNEL,Logger.INFO);
                LockStore lockStore =
                    (LockStore) loadChildStore(lockStoreDefinition,
                                               storeParameters);
                if (lockStore != null) {
                    currentStoreChildStores.put(LOCK_STORE, lockStore);
                }
            }
        } catch (Exception e) {
        }
       
        // Loading revision descriptors store (if any)
        try {
            Configuration revisionDescriptorsStoreDefinition =
                storeDefinition.getConfiguration
                (REVISION_DESCRIPTORS_STORE);
            try {
                Configuration referenceDefinition =
                    revisionDescriptorsStoreDefinition
                    .getConfiguration(REFERENCE);
                currentStoreChildStores.put
                    (REVISION_DESCRIPTORS_STORE,
                     referenceDefinition.getAttribute("store"));
                getLogger().log("Revision descriptors store references " + referenceDefinition.getAttribute("store"),LOG_CHANNEL,Logger.INFO);
            } catch (ConfigurationException ex) {
                getLogger().log("Revision descriptors store: " + revisionDescriptorsStoreDefinition.getAttribute("classname"),LOG_CHANNEL,Logger.INFO);
                RevisionDescriptorsStore revisionDescriptorsStore =
                    (RevisionDescriptorsStore) loadChildStore
                    (revisionDescriptorsStoreDefinition, storeParameters);
                if (revisionDescriptorsStore != null) {
                    currentStoreChildStores.put(REVISION_DESCRIPTORS_STORE,
                                                revisionDescriptorsStore);
                }
            }
        } catch (Exception e) {
        }
       
        // Loading revision descriptor store (if any)
        try {
            Configuration revisionDescriptorStoreDefinition =
                storeDefinition.getConfiguration(REVISION_DESCRIPTOR_STORE);
            try {
                Configuration referenceDefinition =
                    revisionDescriptorStoreDefinition
                    .getConfiguration(REFERENCE);
                currentStoreChildStores.put
                    (REVISION_DESCRIPTOR_STORE,
                     referenceDefinition.getAttribute("store"));
                getLogger().log("Revision descriptor store references " + referenceDefinition.getAttribute("store"),LOG_CHANNEL,Logger.INFO);
            } catch (ConfigurationException ex) {
                getLogger().log("Revision descriptor store: " + revisionDescriptorStoreDefinition.getAttribute("classname"),LOG_CHANNEL,Logger.INFO);
                RevisionDescriptorStore revisionDescriptorStore =
                    (RevisionDescriptorStore) loadChildStore
                    (revisionDescriptorStoreDefinition, storeParameters);
                if (revisionDescriptorStore != null) {
                    currentStoreChildStores.put(REVISION_DESCRIPTOR_STORE,
                                                revisionDescriptorStore);
                }
            }
        } catch (Exception e) {
        }
       
        // Loading content store (if any)
        try {
            Configuration contentStoreDefinition =
                storeDefinition.getConfiguration(CONTENT_STORE);
            try {
                Configuration referenceDefinition =
                    contentStoreDefinition.getConfiguration(REFERENCE);
                currentStoreChildStores.put
                    (CONTENT_STORE, referenceDefinition.getAttribute("store"));
                getLogger().log("Content store references " + referenceDefinition.getAttribute("store"),LOG_CHANNEL,Logger.INFO);
            } catch (ConfigurationException ex) {
                getLogger().log("Content store: " + contentStoreDefinition.getAttribute("classname"),LOG_CHANNEL,Logger.INFO);
                ContentStore contentStore =
                    (ContentStore) loadChildStore(contentStoreDefinition,
                                                  storeParameters);
                if (contentStore != null) {
                    currentStoreChildStores.put(CONTENT_STORE, contentStore);
                }
            }
        } catch (Exception e) {
        }
       
        childStores.put(storeName, currentStoreChildStores);
       
    }
   
   
    /**
     * Load a child descriptors store.
     *
     * @param childStoreDefinition XML definition of the child store
     * @param fatherParameters     XML parameters defined for the father
     * @return Service Instance of the child store
     * @exception ConfigurationException Error parsing configuration file
     * @exception SlideException Error loading the specified class
     */
    private Service loadChildStore(Configuration childStoreDefinition,
                                   Hashtable fatherParameters)
        throws ConfigurationException, SlideException {
       
        // Load classname
        String childStoreClassname =
            childStoreDefinition.getAttribute("classname");
       
        // Load descriptors store class
        Service childStore = null;
        try {
            Class childStoreClass =
                Class.forName(childStoreClassname);
            childStore = (Service) childStoreClass.newInstance();
        } catch (Exception e) {
            getLogger().log(e,LOG_CHANNEL, Logger.ERROR);
            return null;
        }
       
        // Retrieve parent parameters
        Hashtable childStoreParameters = new Hashtable();
        Enumeration fatherParametersKeys = fatherParameters.keys();
        while (fatherParametersKeys.hasMoreElements()) {
            Object key = fatherParametersKeys.nextElement();
            Object value = fatherParameters.get(key);
            childStoreParameters.put(key, value);
        }
       
        // Load parameters
        Enumeration childStoreParametersDefinitions =
            childStoreDefinition.getConfigurations("parameter");
        while (childStoreParametersDefinitions.hasMoreElements()) {
            Configuration parameterDefinition = (Configuration)
                childStoreParametersDefinitions.nextElement();
            String parameterName = parameterDefinition.getAttribute("name");
            String parameterValue = parameterDefinition.getValue();
            childStoreParameters.put(parameterName, parameterValue);
        }
        childStore.setParameters(childStoreParameters);
       
        return childStore;
       
    }
   
   
    /**
     * Parse the content store definition.
     *
     * @param storesClass Class names of the descriptors stores
     * @param storesParameters Parameters of the descriptors stores
     * @param childStores Child stores instances
     * @exception ConfigurationException Error parsing configuration file
     * @exception UnknownServiceDeclarationException Reference to
     * unknown service
     * @exception ServiceParameterErrorException Service parameter error
     * @exception ServiceParameterMissingException Service parameter missing
     * @exception ServiceRegistrationFailedException Error registering service
     */
    private void loadScopeDefinition(Configuration scopeDefinition,
                                     Hashtable storesClass,
                                     Hashtable storesParameters,
                                     Hashtable childStores)
        throws ConfigurationException, UnknownServiceDeclarationException,
        ServiceParameterErrorException, ServiceParameterMissingException,
        ServiceRegistrationFailedException {
       
        String match = scopeDefinition.getAttribute("match");
       
        // First, we get the correct class and parameters from the Hashtables.
        String storeName = scopeDefinition.getAttribute("store");
       
        if (storeName != null) {
            if ((!storesClass.containsKey(storeName)) ||
                    (!storesParameters.containsKey(storeName))) {
                throw new UnknownServiceDeclarationException(storeName);
            }
            registerStore(storeName,
                              (Class) storesClass.get(storeName),
                              (Hashtable) storesParameters.get(storeName),
                          new Scope(match),
                              (Hashtable) childStores.get(storeName));
            getLogger().log("Registering Store "
                                + storeName
                                + " ("
                                + storesClass.get(storeName)
                                + ") with parameters "
                                + storesParameters.get(storeName)
                                + " on scope " + match,LOG_CHANNEL,Logger.INFO);
        }
       
    }
   
    /**
     *
     */
    private void notifyStoreCreated( String namespaceName, String scope, String storeName ) {
       
        if( createStoreListenerClass != null ) {
            try {
                Method nsc = createStoreListenerClass.getMethod(
                    "notifyStoreCreated", new Class[]{String.class, String.class, String.class} );
                nsc.invoke( null, new Object[]{namespaceName, scope, storeName} ); // obj=null since method is static
            }
            catch( Exception x ) {
                Domain.warn( "Notification of store creation "+
                             "(namespace="+namespaceName+", scope="+scope+", store="+storeName+") failed: "+x.getMessage() );
            }
        }
    }
   
   
    // --------------------------------------------------------- Object Methods
   
   
    /**
     * Get a String representation of this namespace.
     */
    public String toString() {
        return getName();
    }
   
   
}

TOP

Related Classes of org.apache.slide.common.Namespace

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.