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;
+ }
+}