001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.components.treeprocessor.sitemap;
018:
019: import java.util.HashMap;
020: import java.util.Map;
021:
022: import org.apache.avalon.framework.parameters.Parameters;
023: import org.apache.cocoon.components.treeprocessor.InvokeContext;
024: import org.apache.cocoon.components.treeprocessor.NamedProcessingNode;
025: import org.apache.cocoon.components.treeprocessor.ProcessingNode;
026: import org.apache.cocoon.components.treeprocessor.SimpleSelectorProcessingNode;
027: import org.apache.cocoon.environment.Environment;
028:
029: /**
030: *
031: * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
032: * @version CVS $Id: ActionSetNode.java 433543 2006-08-22 06:22:54Z crossley $
033: */
034:
035: public class ActionSetNode extends SimpleSelectorProcessingNode
036: implements NamedProcessingNode {
037:
038: public static final String CALLER_PARAMETERS = ActionSetNode.class
039: .getName()
040: + "/CallerParameters";
041: public static final String ACTION_RESULTS = ActionSetNode.class
042: .getName()
043: + "/ActionResults";
044:
045: /** The action nodes */
046: private ProcessingNode[] nodes;
047:
048: /** The 'action' attribute for each action */
049: private String[] actionNames;
050:
051: public ActionSetNode(String name, ProcessingNode[] nodes,
052: String[] actionNames) {
053: super (name);
054: this .nodes = nodes;
055: this .actionNames = actionNames;
056: }
057:
058: public final boolean invoke(Environment env, InvokeContext context)
059: throws Exception {
060:
061: // Perform any common invoke functionalty
062: // super.invoke(env, context);
063: String msg = "An action-set cannot be invoked, at "
064: + this .getLocation();
065: throw new UnsupportedOperationException(msg);
066: }
067:
068: /**
069: * Call the actions composing the action-set and return the combined result of
070: * these actions.
071: */
072: public final Map call(Environment env, InvokeContext context,
073: Parameters params) throws Exception {
074:
075: String cocoonAction = env.getAction();
076:
077: // Store the parameters from the caller into the environment so that they can be merged with
078: // each action's parameters.
079:
080: Map result = null;
081:
082: // Call each action that either has no cocoonAction, or whose cocoonAction equals
083: // the one from the environment.
084: env.setAttribute(CALLER_PARAMETERS, params);
085:
086: for (int i = 0; i < nodes.length; i++) {
087:
088: String actionName = actionNames[i];
089: if (actionName == null || actionName.equals(cocoonAction)) {
090:
091: this .nodes[i].invoke(env, context);
092:
093: // Get action results. They're passed back through the environment since action-sets
094: // "violate" the tree hierarchy (the returned Map is visible outside of the node)
095: Map actionResult = (Map) env
096: .getAttribute(ACTION_RESULTS);
097: // Don't forget to clear it
098: env.removeAttribute(ACTION_RESULTS);
099:
100: if (actionResult != null) {
101: // Merge the result in the global result, creating it if necessary.
102: if (result == null) {
103: result = new HashMap(actionResult);
104: } else {
105: result.putAll(actionResult);
106: }
107: }
108:
109: } // if (actionName...
110: } // for (int i...
111:
112: return result;
113: }
114:
115: /**
116: * Implementation of <code>NamedProcessingNode</code>.
117: */
118:
119: public String getName() {
120: return this.componentName;
121: }
122: }
|