You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by da...@apache.org on 2005/10/31 22:15:31 UTC

svn commit: r329910 - in /cocoon/trunk/src/java/org/apache/cocoon/components/blocks: Block.java BlockManager.java BlockWiring.java InterBlockServiceManager.java

Author: danielf
Date: Mon Oct 31 13:15:23 2005
New Revision: 329910

URL: http://svn.apache.org/viewcvs?rev=329910&view=rev
Log:
Started to work on inter block component management. Also some
refactorings.

Added:
    cocoon/trunk/src/java/org/apache/cocoon/components/blocks/InterBlockServiceManager.java
Modified:
    cocoon/trunk/src/java/org/apache/cocoon/components/blocks/Block.java
    cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockManager.java
    cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockWiring.java

Modified: cocoon/trunk/src/java/org/apache/cocoon/components/blocks/Block.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/blocks/Block.java?rev=329910&r1=329909&r2=329910&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/blocks/Block.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/blocks/Block.java Mon Oct 31 13:15:23 2005
@@ -18,6 +18,7 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 
+import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.cocoon.Processor;
 
 /**
@@ -40,6 +41,13 @@
 
     // TODO: We should have a reflection friendly Map getProperties() also
 
+    /**
+     * The exported components of the block. Return null if the block doesn't export components.
+     * 
+     * @return a ServiceManager containing the blocks exported components
+     */
+    public ServiceManager getServiceManager();
+    
     /**
      * Takes the scheme specific part of a block URI (the scheme is
      * the responsibilty of the BlockSource) and resolve it with

Modified: cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockManager.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockManager.java?rev=329910&r1=329909&r2=329910&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockManager.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockManager.java Mon Oct 31 13:15:23 2005
@@ -88,35 +88,12 @@
 
         this.blockContext = new BlockContext(this.blockWiring, this);
         
-        ComponentContext newContext = new ComponentContext(context);
-        // A block is supposed to be an isolated unit so it should not have
-        // any direct access to the global root context
-        newContext.put(ContextHelper.CONTEXT_ROOT_URL, new URL(this.blockWiring.getContextURL().toExternalForm()));
-        newContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT, this.blockContext);
-        newContext.makeReadOnly();
+        Context newContext = this.getAvalonContext();
 
         // Create block a service manager with the exposed components of the block
         if (this.blockWiring.getComponentConfiguration() != null) {
-            // The source resolver must be defined in this service
-            // manager, otherwise the root path will be the one from the
-            // parent manager, we add a resolver to get it right. If the
-            // components section contain includes the CoreComponentManager
-            // use the location of the configuration an the parent SourceResolver
-            // for resolving the include.
             String confLocation = this.blockWiring.getContextURL() + "::";
-            DefaultConfiguration sourceManagerConf =
-                new DefaultConfiguration("components", confLocation);
-            DefaultConfiguration resolverConf =
-                new DefaultConfiguration("source-resolver");
-            sourceManagerConf.addChild(resolverConf);
-            ServiceManager sourceResolverSM =
-                new CoreServiceManager(this.parentServiceManager);
-            LifecycleHelper.setupComponent(
-                    sourceResolverSM,
-                    this.getLogger(),
-                    newContext,
-                    null,
-                    sourceManagerConf);
+            ServiceManager sourceResolverSM = this.createLocalSourceResolverSM(newContext, confLocation);
             
             DefaultConfiguration componentConf =
                 new DefaultConfiguration("components", confLocation);
@@ -147,6 +124,50 @@
         this.parentServiceManager = null;
     }
 
+    /**
+     * @return
+     * @throws Exception
+     */
+    protected Context getAvalonContext() throws Exception {
+        ComponentContext newContext = new ComponentContext(this.context);
+        // A block is supposed to be an isolated unit so it should not have
+        // any direct access to the global root context
+        newContext.put(ContextHelper.CONTEXT_ROOT_URL, new URL(this.blockWiring.getContextURL().toExternalForm()));
+        newContext.put(Constants.CONTEXT_ENVIRONMENT_CONTEXT, this.blockContext);
+        newContext.makeReadOnly();
+        
+        return newContext;
+    }
+
+    /**
+     * @param newContext
+     * @param confLocation
+     * @return
+     * @throws Exception
+     */
+    protected ServiceManager createLocalSourceResolverSM(Context newContext, String confLocation) throws Exception {
+        // The source resolver must be defined in this service
+        // manager, otherwise the root path will be the one from the
+        // parent manager, we add a resolver to get it right. If the
+        // components section contain includes the CoreComponentManager
+        // use the location of the configuration an the parent SourceResolver
+        // for resolving the include.
+        DefaultConfiguration sourceManagerConf =
+            new DefaultConfiguration("components", confLocation);
+        DefaultConfiguration resolverConf =
+            new DefaultConfiguration("source-resolver");
+        sourceManagerConf.addChild(resolverConf);
+        ServiceManager sourceResolverSM =
+            new CoreServiceManager(this.parentServiceManager);
+        LifecycleHelper.setupComponent(
+                sourceResolverSM,
+                this.getLogger(),
+                newContext,
+                null,
+                sourceManagerConf);
+        return sourceResolverSM;
+    }
+
     // Block methods
 
     // The blocks manager should not be available within a block so I
@@ -183,6 +204,20 @@
 
     // TODO: We should have a reflection friendly Map getProperties() also
 
+    /**
+     * The exported components of the block. Return null if the block doesn't export components.
+     * 
+     * @return a ServiceManager containing the blocks exported components
+     */
+    public ServiceManager getServiceManager() {
+        // Check that the block have a local service manager
+        if (this.serviceManager != this.parentServiceManager) {
+            return this.serviceManager;
+        } else {
+            return null;
+        }
+    }
+    
     /**
      * Takes the scheme specific part of a block URI (the scheme is
      * the responsibilty of the BlockSource) and resolve it with

Modified: cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockWiring.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockWiring.java?rev=329910&r1=329909&r2=329910&view=diff
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockWiring.java (original)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/blocks/BlockWiring.java Mon Oct 31 13:15:23 2005
@@ -20,8 +20,10 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Vector;
 
 import org.apache.avalon.framework.activity.Disposable;
 import org.apache.avalon.framework.configuration.Configurable;
@@ -54,6 +56,7 @@
     private String location;
     private Map connections = new HashMap();
     private Map properties = new HashMap();
+    private Vector connectionNames;
 
     private String mountPath;
     private String sitemapPath;
@@ -85,9 +88,11 @@
 
         Configuration[] connections =
             config.getChild("connections").getChildren("connection");
+        this.connectionNames = new Vector(connections.length);
         for (int i = 0; i < connections.length; i++) {
             Configuration connection = connections[i];
             String name = connection.getAttribute("name");
+            this.connectionNames.add(name);
             String block = connection.getAttribute("block");
             this.connections.put(name, block);
             getLogger().debug("connection: " + " name=" + name + " block=" + block);
@@ -181,6 +186,13 @@
         return contextURL;
     }
 
+    /**
+     * Get the names for the connections from this block. The name (super) of the super block is not included.
+     */
+    public Enumeration getConnectionNames() {
+        return this.connectionNames.elements();
+    }
+        
     /**
      * Get a block id from the blockname.
      */

Added: cocoon/trunk/src/java/org/apache/cocoon/components/blocks/InterBlockServiceManager.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/blocks/InterBlockServiceManager.java?rev=329910&view=auto
==============================================================================
--- cocoon/trunk/src/java/org/apache/cocoon/components/blocks/InterBlockServiceManager.java (added)
+++ cocoon/trunk/src/java/org/apache/cocoon/components/blocks/InterBlockServiceManager.java Mon Oct 31 13:15:23 2005
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2005 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.cocoon.components.blocks;
+
+import java.util.Enumeration;
+import java.util.Map;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+/**
+ * Look for a component in blocks that are connected to the current block.
+ * 
+ * @version SVN $Id$
+ */
+public class InterBlockServiceManager implements ServiceManager {
+    
+    private BlockWiring blockWiring;
+    private BlocksManager blocksManager;
+    private Map managers;
+    private boolean called;
+
+    /**
+     * @param blockWiring
+     * @param blocksManager
+     */
+    public InterBlockServiceManager(BlockWiring blockWiring, BlocksManager blocksManager) {
+        this.blockWiring = blockWiring;
+        this.blocksManager = blocksManager;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#lookup(java.lang.String)
+     */
+    public Object lookup(String role) throws ServiceException {
+        ServiceManager manager = this.findServiceManager(role);
+        if (manager == null) {
+            throw new ServiceException(role, "Could not find any manager in connected blocks that contains the role");
+        }
+        Object component = manager.lookup(role);
+        // Keep track on what manager that was used so that we can return the 
+        this.managers.put(component, manager);
+        return component;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#hasService(java.lang.String)
+     */
+    public boolean hasService(String role) {
+        ServiceManager manager = this.findServiceManager(role);
+        return manager != null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.service.ServiceManager#release(java.lang.Object)
+     */
+    public void release(Object component) {
+        if (component == null)
+            return;
+        ServiceManager manager = (ServiceManager)this.managers.get(component);
+        if (manager != null) {
+            manager.release(component);
+        }
+    }
+
+    
+    /**
+     * Find a service manager that contains a given role from one of the connected blocks. The component
+     * managers of the connected blocks are searched in the order they are declared in the block configuration.
+     * The super block, if there is one, is tried after the connected blocks. This is to make certain that
+     * a blocks connections is searched before its super blocks connections. 
+     * 
+     * @param role the role to find a service manager for
+     * @return the found service manager or null if not found
+     */
+    private ServiceManager findServiceManager(String role) {
+        // FIXME: Called is used for protection about infinite loops for blocks with circular dependencies.
+        // It must be made thread safe.
+        if (called) {
+            return null;
+        } else {
+            this.called = true;
+        }
+        ServiceManager manager = null;
+        try {
+            Enumeration connectionNames = this.blockWiring.getConnectionNames();
+            while (connectionNames.hasMoreElements()) {
+                String blockName = (String)connectionNames.nextElement();
+                String blockId = this.blockWiring.getBlockId(blockName);
+                Block block = this.blocksManager.getBlock(blockId);
+                manager = block.getServiceManager();
+                if (manager.hasService(role)) {
+                    return manager;
+                }
+            }
+            String superId = this.blockWiring.getBlockId(Block.SUPER);
+            if (superId != null) {
+                Block superBlock = this.blocksManager.getBlock(superId);
+                manager = superBlock.getServiceManager();
+                if (manager.hasService(role)) {
+                    return manager;
+                }                
+            }
+        } finally {
+            this.called = false;
+        }
+        return null;
+    }
+}