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.ArrayList;
020: import java.util.List;
021:
022: import org.apache.avalon.framework.configuration.Configuration;
023: import org.apache.avalon.framework.configuration.ConfigurationException;
024: import org.apache.avalon.framework.thread.ThreadSafe;
025: import org.apache.cocoon.components.pipeline.ProcessingPipeline;
026: import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNodeBuilder;
027: import org.apache.cocoon.components.treeprocessor.ProcessingNode;
028: import org.apache.cocoon.components.treeprocessor.ProcessingNodeBuilder;
029:
030: /**
031: * Builds a <map:pipeline>
032: *
033: * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
034: * @author <a href="mailto:gianugo@apache.org">Gianugo Rabellino</a>
035: * @version $Id: PipelineNodeBuilder.java 433543 2006-08-22 06:22:54Z crossley $
036: */
037: public class PipelineNodeBuilder extends
038: AbstractParentProcessingNodeBuilder implements ThreadSafe {
039:
040: /** This builder can have parameters -- return <code>true</code> */
041: protected boolean hasParameters() {
042: return true;
043: }
044:
045: public ProcessingNode buildNode(Configuration config)
046: throws Exception {
047: String type = this .treeBuilder.getTypeForStatement(config,
048: ProcessingPipeline.ROLE + "Selector");
049: PipelineNode node = new PipelineNode(type);
050:
051: this .treeBuilder.setupNode(node, config);
052: node.setInternalOnly(config.getAttributeAsBoolean(
053: "internal-only", false));
054:
055: // Main (with no "type" attribute) error handler: new in Cocoon 2.1, must have a generator
056: ProcessingNode mainHandler = null;
057:
058: // 404 & 500 error handlers as in Cocoon 2.0.x, have an implicit generator
059: ProcessingNode error404Handler = null;
060: ProcessingNode error500Handler = null;
061:
062: Configuration[] childConfigs = config.getChildren();
063: List children = new ArrayList();
064: for (int i = 0; i < childConfigs.length; i++) {
065: Configuration childConfig = childConfigs[i];
066: if (isChild(childConfig)) {
067:
068: ProcessingNodeBuilder builder = this .treeBuilder
069: .createNodeBuilder(childConfig);
070: if (builder instanceof HandleErrorsNodeBuilder) {
071: // Error handler : check type
072: HandleErrorsNode handler = (HandleErrorsNode) builder
073: .buildNode(childConfig);
074: int status = handler.getStatusCode();
075:
076: switch (status) {
077: case -1: // main handler (needs generator)
078: if (mainHandler != null) {
079: throw new ConfigurationException(
080: "Duplicate <handle-errors> at "
081: + handler.getLocation());
082: } else if (error500Handler != null
083: || error404Handler != null) {
084: throw new ConfigurationException(
085: "Cannot mix <handle-errors> with and without 'type' attribute at "
086: + handler.getLocation());
087: } else {
088: mainHandler = handler;
089: }
090: break;
091:
092: case 404:
093: if (error404Handler != null) {
094: throw new ConfigurationException(
095: "Duplicate <handle-errors type='404' at "
096: + handler.getLocation());
097: } else if (mainHandler != null) {
098: throw new ConfigurationException(
099: "Cannot mix <handle-errors> with and without 'type' attribute at "
100: + handler.getLocation());
101: } else {
102: error404Handler = handler;
103: }
104: break;
105:
106: case 500:
107: if (error500Handler != null) {
108: throw new ConfigurationException(
109: "Duplicate <handle-errors type='500' at "
110: + handler.getLocation());
111: } else if (mainHandler != null) {
112: throw new ConfigurationException(
113: "Cannot mix <handle-errors> with and without 'type' attribute at "
114: + handler.getLocation());
115: } else {
116: error500Handler = handler;
117: }
118: break;
119:
120: default:
121: throw new ConfigurationException(
122: "Unknown handle-errors type (" + type
123: + ") at "
124: + handler.getLocation());
125: }
126: } else {
127: // Regular builder
128: children.add(builder.buildNode(childConfig));
129: }
130: }
131: }
132:
133: node.setChildren(toNodeArray(children));
134: node.set404Handler(error404Handler);
135: // Set either main or error500 handler as only one can exist
136: node.set500Handler(error500Handler == null ? mainHandler
137: : error500Handler);
138:
139: return node;
140: }
141: }
|