1 16 package org.apache.cocoon.selection; 17 18 import java.util.Map ; 19 20 import org.apache.avalon.framework.configuration.Configurable; 21 import org.apache.avalon.framework.configuration.Configuration; 22 import org.apache.avalon.framework.configuration.ConfigurationException; 23 import org.apache.avalon.framework.parameters.Parameters; 24 import org.apache.cocoon.environment.ObjectModelHelper; 25 import org.apache.cocoon.util.ClassUtils; 26 import org.apache.commons.lang.exception.ExceptionUtils; 27 28 57 58 public class ExceptionSelector extends AbstractSwitchSelector implements Configurable { 59 60 61 private Class [] clazz; 62 63 64 private String [] name; 65 66 67 private boolean[] unroll; 68 69 public void configure(Configuration conf) throws ConfigurationException { 70 71 Configuration[] children = conf.getChildren("exception"); 72 73 this.clazz = new Class [children.length]; 74 this.name = new String [children.length]; 75 this.unroll = new boolean[children.length]; 76 77 for (int i = 0; i < children.length; i++) { 78 Configuration child = children[i]; 79 80 String childClassName = child.getAttribute("class"); 81 Class childClass = null; 82 try { 83 childClass = ClassUtils.loadClass(childClassName); 84 } 85 catch (Exception e) { 86 throw new ConfigurationException("Cannot load class '" + childClassName + "' at " + child.getLocation()); 87 } 88 89 for (int j = 0; j < i; j++) { 91 if (this.clazz[j].isAssignableFrom(childClass)) { 92 throw new ConfigurationException("Class '" + this.clazz[j].getName() + "' hides its subclass '" + 93 childClassName + "' at " + child.getLocation()); 94 } 95 } 96 97 this.clazz[i] = childClass; 98 this.name[i] = child.getAttribute("name", null); 99 this.unroll[i] = child.getAttributeAsBoolean("unroll", false); 100 101 if (this.name[i] == null && !this.unroll[i]) { 102 throw new ConfigurationException("Must specify one of 'name' or 'unroll' at " + child.getLocation()); 103 } 104 } 105 } 106 107 112 public Object getSelectorContext(Map objectModel, Parameters parameters) { 113 Throwable thr = ObjectModelHelper.getThrowable(objectModel); 115 if (thr == null) { 116 throw new IllegalStateException ("No exception in object model. ExceptionSelector can only be used in <map:handle-errors>"); 117 } 118 119 return find(thr); 120 } 121 122 private FindResult find(Throwable thr) { 123 for (int i = 0; i < this.clazz.length; i++) { 125 if (this.clazz[i].isInstance(thr)) { 126 127 if (this.unroll[i]) { 130 Throwable cause = ExceptionUtils.getCause(thr); 131 if (cause != null) { 132 FindResult result = find(cause); 133 if (result != null) { 134 return result; 135 } 136 } 137 } 138 139 return new FindResult(this.name[i], thr); 141 } 142 } 143 144 return null; 146 } 147 148 public boolean select(String expression, Object selectorContext) { 149 if ( selectorContext == null ) { 150 return false; 151 } 152 boolean result = expression.equals(((FindResult)selectorContext).getName()); 154 155 if (result) { 156 if (getLogger().isDebugEnabled()) 157 getLogger().debug("select succesfull for condition " + selectorContext.toString()); 158 } 159 160 return result; 161 } 162 163 static class FindResult { 164 private String name; 165 private Throwable throwable; 166 167 public FindResult(String name, Throwable throwable) { 168 this.name = name; 169 this.throwable = throwable; 170 } 171 172 public String getName() { 173 return this.name; 174 } 175 176 public void setName(String name) { 177 this.name = name; 178 } 179 180 public Throwable getThrowable() { 181 return this.throwable; 182 } 183 184 public void setThrowable(Throwable throwable) { 185 this.throwable = throwable; 186 } 187 188 public String toString() { 189 return this.name; 190 } 191 } 192 193 } 194 | Popular Tags |