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 org.apache.avalon.framework.configuration.Configurable;
020: import org.apache.avalon.framework.configuration.Configuration;
021: import org.apache.avalon.framework.configuration.ConfigurationException;
022: import org.apache.cocoon.components.flow.Interpreter;
023: import org.apache.cocoon.components.treeprocessor.AbstractProcessingNodeBuilder;
024: import org.apache.cocoon.components.treeprocessor.CategoryNode;
025: import org.apache.cocoon.components.treeprocessor.CategoryNodeBuilder;
026: import org.apache.cocoon.components.treeprocessor.LinkedProcessingNodeBuilder;
027: import org.apache.cocoon.components.treeprocessor.ProcessingNode;
028: import org.apache.cocoon.components.treeprocessor.variables.VariableResolverFactory;
029:
030: /**
031: *
032: * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
033: * @author <a href="mailto:ovidiu@apache.org">Ovidiu Predescu</a>
034: * @version CVS $Id: CallNodeBuilder.java 433543 2006-08-22 06:22:54Z crossley $
035: */
036: public class CallNodeBuilder extends AbstractProcessingNodeBuilder
037: implements LinkedProcessingNodeBuilder {
038:
039: protected ProcessingNode node;
040: protected String resourceName;
041: protected String functionName;
042: protected String continuationId;
043:
044: public ProcessingNode buildNode(Configuration config)
045: throws Exception {
046: resourceName = config.getAttribute("resource", null);
047: functionName = config.getAttribute("function", null);
048: continuationId = config.getAttribute("continuation", null);
049:
050: if (resourceName == null) {
051: // Building a CallFunction node
052: if (functionName == null && continuationId == null) {
053: throw new ConfigurationException(
054: "<map:call> must have either a 'resource', 'function' or 'continuation' attribute, at "
055: + config.getLocation());
056: }
057:
058: node = new CallFunctionNode(VariableResolverFactory
059: .getResolver(functionName, this .manager),
060: VariableResolverFactory.getResolver(continuationId,
061: this .manager));
062:
063: } else {
064: // Building a Call(Resource)Node
065: if (functionName != null || continuationId != null) {
066: throw new ConfigurationException(
067: "<map:call> cannot have both a 'resource' and a 'function' or 'continuation' attribute, at "
068: + config.getLocation());
069: }
070: node = new CallNode();
071: }
072:
073: this .treeBuilder.setupNode(this .node, config);
074: if (node instanceof Configurable) {
075: ((Configurable) this .node).configure(config);
076: }
077:
078: return this .node;
079: }
080:
081: public void linkNode() throws Exception {
082: if (resourceName != null) {
083: // We have a <map:call resource="..."/>
084: CategoryNode resources = CategoryNodeBuilder
085: .getCategoryNode(treeBuilder, "resources");
086:
087: if (resources == null)
088: throw new ConfigurationException(
089: "This sitemap contains no resources. Cannot call at "
090: + node.getLocation());
091:
092: ((CallNode) this .node).setResource(resources,
093: this .resourceName);
094: } else {
095: // We have a <map:call> with either "function" or
096: // "continuation", or both specified
097:
098: // Check to see if a flow has been defined in this sitemap
099: FlowNode flow = (FlowNode) treeBuilder
100: .getRegisteredNode("flow");
101: if (flow == null)
102: throw new ConfigurationException(
103: "This sitemap contains no control flows defined, cannot call at "
104: + node.getLocation()
105: + ". Define a control flow using <map:flow>, with embedded <map:script> elements.");
106:
107: // Get the Interpreter instance and set it up in the
108: // CallFunctionNode function
109: Interpreter interpreter = flow.getInterpreter();
110: ((CallFunctionNode) node).setInterpreter(interpreter);
111: }
112: }
113: }
|