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.parameters.Parameters;
020: import org.apache.avalon.framework.configuration.ConfigurationException;
021:
022: import org.apache.cocoon.ProcessingException;
023: import org.apache.cocoon.Constants;
024: import org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode;
025: import org.apache.cocoon.components.treeprocessor.InvokeContext;
026: import org.apache.cocoon.components.treeprocessor.ProcessingNode;
027: import org.apache.cocoon.environment.Environment;
028: import org.apache.commons.lang.SystemUtils;
029:
030: /**
031: * Handles <map:handle-errors>
032: *
033: * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
034: * @version $Id: HandleErrorsNode.java 433543 2006-08-22 06:22:54Z crossley $
035: */
036: public final class HandleErrorsNode extends
037: AbstractParentProcessingNode {
038:
039: private ProcessingNode[] children;
040: private int statusCode;
041: private boolean internal;
042: private boolean external;
043:
044: /**
045: * @param statusCode Value of the type attribute: 404 (deprecated), 500 (deprecated), or -1 (no attribute present).
046: * @param scope Value of the error handler scope attribute: external, internal, always.
047: */
048: public HandleErrorsNode(int statusCode, String scope)
049: throws ConfigurationException {
050: this .statusCode = statusCode;
051: if ("internal".equals(scope)) {
052: this .internal = true;
053: } else if ("external".equals(scope)) {
054: this .external = true;
055: } else if ("always".equals(scope)) {
056: this .internal = true;
057: this .external = true;
058: } else {
059: throw new ConfigurationException(
060: "Unrecognized value of when attribute on <handle-errors> at "
061: + getLocation());
062: }
063: }
064:
065: public int getStatusCode() {
066: return this .statusCode;
067: }
068:
069: public boolean isInternal() {
070: return this .internal;
071: }
072:
073: public boolean isExternal() {
074: return this .external;
075: }
076:
077: public void setChildren(ProcessingNode[] nodes) {
078: this .children = nodes;
079: }
080:
081: public final boolean invoke(Environment env, InvokeContext context)
082: throws Exception {
083:
084: if (getLogger().isInfoEnabled()) {
085: getLogger().info(
086: "Processing handle-errors at " + getLocation());
087: }
088:
089: if (statusCode == -1) {
090: // No 'type' attribute : new Cocoon 2.1 behaviour, no implicit generator
091: try {
092: return invokeNodes(this .children, env, context);
093:
094: } catch (ProcessingException e) {
095: // Handle the various cases related to the transition from implicit generators in handle-errors to
096: // explicit ones, in order to provide meaningful messages that will ease the migration
097: if (e.getMessage().indexOf(
098: "Must set a generator before adding") != -1) {
099:
100: env.getObjectModel().remove(
101: Constants.NOTIFYING_OBJECT);
102: throw new ProcessingException(
103: "Incomplete pipeline: 'handle-error' without a 'type' must include a generator, at "
104: + getLocation()
105: + SystemUtils.LINE_SEPARATOR
106: + "Either add a generator (preferred) or a type='500' attribute (deprecated) on 'handle-errors'");
107: }
108:
109: // Rethrow the exception
110: throw e;
111: }
112: } else {
113: // A 'type' attribute is present : add the implicit generator
114: context.getProcessingPipeline().setGenerator("<notifier>",
115: "", Parameters.EMPTY_PARAMETERS,
116: Parameters.EMPTY_PARAMETERS);
117:
118: try {
119: return invokeNodes(this .children, env, context);
120: } catch (ProcessingException e) {
121: if (e.getMessage().indexOf("Generator already set") != -1) {
122:
123: env.getObjectModel().remove(
124: Constants.NOTIFYING_OBJECT);
125: throw new ProcessingException(
126: "Error: 'handle-error' with a 'type' attribute has an implicit generator, at "
127: + getLocation()
128: + SystemUtils.LINE_SEPARATOR
129: + "Please remove the 'type' attribute on 'handle-error'");
130: }
131: // Rethrow the exception
132: throw e;
133: }
134: }
135: }
136: }
|