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.selection;
018:
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.Map;
022:
023: import org.apache.avalon.framework.configuration.Configuration;
024: import org.apache.avalon.framework.configuration.ConfigurationException;
025: import org.apache.avalon.framework.parameters.Parameters;
026: import org.apache.commons.collections.map.LinkedMap;
027: import org.apache.commons.jxpath.CompiledExpression;
028: import org.apache.commons.jxpath.JXPathContext;
029:
030: /**
031: * Additional to the inherited functionality from its superclass ExceptionSelector,
032: * this selector allows to define xpath expressions to evaluate supplemental information
033: * given in the thrown exception.
034: * The configuration of this selector allows to map not only exceptions but also
035: * xpath expressions to symbolic names that are used in the <map:when> alternatives.
036: * <p>
037: * Example configuration :
038: * <pre>
039: * <map:selector type="error" src="....XPathExceptionSelector">
040: * <exception name="denied" class="my.comp.auth.AuthenticationFailure">
041: * <xpath name="PasswordWrong" test="authCode=10"/>
042: * <xpath name="PasswordExpired" test="errorCode=11"/>
043: * <xpath name="AccessForbidden" test="errorCode>11"/>
044: * </exception>
045: * </map:selector>
046: * </pre>
047: * This example shows several features :
048: * <li>the test is the xpath expression that will be evaluated against the exception ,</li>
049: * <li>an xpath expression can be given a name, which is used in the <map:when> tests,</li>
050: *
051: * @author <a href="mailto:juergen.seitz@basf-it-services.com">Jürgen Seitz</a>
052: * @author <a href="mailto:bluetkemeier@s-und-n.de">Björn Lütkemeier</a>
053: * @since 2.1
054: * @version CVS $Id: XPathExceptionSelector.java 433543 2006-08-22 06:22:54Z crossley $
055: */
056: public class XPathExceptionSelector extends ExceptionSelector {
057:
058: private Map exception2XPath = new HashMap();
059:
060: public void configure(Configuration conf)
061: throws ConfigurationException {
062:
063: super .configure(conf);
064:
065: Configuration[] children = conf.getChildren("exception");
066: Configuration[] xPathChildren;
067:
068: for (int i = 0; i < children.length; i++) {
069: // Check if there are XPath-Expressions configured
070: xPathChildren = children[i].getChildren("xpath");
071: Map xPathMap = new LinkedMap(11);
072:
073: for (int j = 0; j < xPathChildren.length; j++) {
074: Configuration xPathChild = xPathChildren[j];
075:
076: String xPathName = xPathChild.getAttribute("name");
077: CompiledExpression xPath = JXPathContext
078: .compile(xPathChild.getAttribute("test"));
079:
080: xPathMap.put(xPathName, xPath);
081: }
082: if (xPathMap.size() > 0) {
083: // store xpath - config if there is some
084: exception2XPath.put(children[i].getAttribute("name",
085: null), xPathMap);
086: }
087: }
088: }
089:
090: /**
091: * Compute the exception type, given the configuration and the exception stored in the object model.
092: */
093: public Object getSelectorContext(Map objectModel,
094: Parameters parameters) {
095:
096: // get exception from super class
097: FindResult selectorContext = (FindResult) super
098: .getSelectorContext(objectModel, parameters);
099:
100: if (selectorContext != null) {
101: String exceptionName = selectorContext.getName();
102: Throwable t = selectorContext.getThrowable();
103:
104: Map xPathMap = (Map) exception2XPath.get(exceptionName);
105:
106: if (xPathMap != null) {
107: // create a context for the thrown exception
108: JXPathContext context = JXPathContext.newContext(t);
109:
110: for (Iterator iterator = xPathMap.entrySet().iterator(); iterator
111: .hasNext();) {
112: Map.Entry entry = (Map.Entry) iterator.next();
113:
114: if (((CompiledExpression) entry.getValue())
115: .getValue(context).equals(Boolean.TRUE)) {
116: // set the configured name if the expression is succesfull
117: selectorContext
118: .setName((String) entry.getKey());
119: return selectorContext;
120: }
121: }
122: }
123: }
124:
125: return selectorContext;
126: }
127: }
|