1 3 package jodd.madvoc.config; 4 5 import jodd.introspector.ClassDescriptor; 6 import jodd.introspector.DefaultIntrospector; 7 import jodd.io.findfile.FindClass; 8 import jodd.madvoc.ActionConfig; 9 import jodd.madvoc.MadvocException; 10 import jodd.madvoc.WebApplication; 11 import jodd.madvoc.result.ActionResult; 12 import jodd.madvoc.interceptor.ActionInterceptor; 13 import jodd.madvoc.interceptor.ActionInterceptorStack; 14 import jodd.madvoc.interceptor.DefaultMadvocInterceptors; 15 import jodd.madvoc.meta.Action; 16 import jodd.madvoc.meta.InterceptedBy; 17 import jodd.madvoc.meta.MadvocAction; 18 import jodd.util.*; 19 20 import java.lang.reflect.Method ; 21 import java.util.*; 22 import java.net.URL ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 26 60 public class AutomagicMadvocConfig extends FindClass implements MadvocConfig { 61 62 protected WebApplication webapp; 63 protected String extension; 64 protected String actionClassSuffix; 65 protected String configClassSuffix; 66 protected String resultClassSuffix; 67 protected String jockerName; 68 protected String jockerPrefix; 69 protected long elapsed; 70 71 private Map<Class <? extends ActionInterceptor>, ActionInterceptor> interceptorsPool = new HashMap<Class <? extends ActionInterceptor>, ActionInterceptor>(); 72 private List<MadvocConfig> externalConfigs = new ArrayList<MadvocConfig>(); 73 74 public AutomagicMadvocConfig() { 75 super(); 76 extension = "html"; 77 actionClassSuffix = "Action"; 78 configClassSuffix = "Config"; 79 resultClassSuffix = "Result"; 80 elapsed = 0; 81 jockerName = "{N}"; 82 jockerPrefix = "{P}"; 83 } 84 85 89 public void configure(WebApplication webapp) { 90 configure(webapp, ClassLoaderUtil.getFullClassPath(AutomagicMadvocConfig.class)); 91 } 92 93 102 public void configure(WebApplication webapp, URL [] classpath) { 103 this.webapp = webapp; 104 elapsed = System.currentTimeMillis(); 105 106 for (URL path : classpath) { 107 try { 108 scanUrl(path); 109 } catch (IOException ioex) { 110 throw new MadvocException("Unable to scan classpath: '" + path + "'.", ioex); 111 } 112 } 113 for (MadvocConfig madvocConfig : externalConfigs) { 114 madvocConfig.configure(webapp); 115 } 116 117 ActionInterceptor[] defaultIntercetors = buildInterceptors(webapp.getDefaultInterceptors()); 119 if (defaultIntercetors != null) { 120 Map<String , ActionConfig> map = webapp.getAllActionConfigs(); 121 for (ActionConfig cfg : map.values()) { 122 if (cfg.interceptors == null) { 123 cfg.interceptors = defaultIntercetors; 124 } else { 125 if (defaultIntercetors.length > 0) { 127 for (int i = 0; i < cfg.interceptors.length; i++) { 128 ActionInterceptor interceptor = cfg.interceptors[i]; 129 if (interceptor instanceof DefaultMadvocInterceptors) { 130 cfg.interceptors = (ActionInterceptor[]) ArraysUtil.insertAt(cfg.interceptors, defaultIntercetors, i, ActionInterceptor.class); 131 } 132 } 133 } 134 } 135 } 136 } 137 138 139 elapsed = System.currentTimeMillis() - elapsed; 140 System.out.println("Madvoc configured in " + elapsed + "ms"); 141 } 142 143 144 147 @Override 148 protected void onClassName(String className, InputStream inputStream) { 149 if (StringUtil.endsWithIgnoreCase(className, actionClassSuffix) == true) { 150 onActionClass(className); 151 } else if (StringUtil.endsWithIgnoreCase(className, configClassSuffix) == true) { 152 onConfigClass(className); 153 } else if (StringUtil.endsWithIgnoreCase(className, resultClassSuffix) == true) { 154 onResultClass(className); 155 } 156 } 157 158 160 164 @SuppressWarnings ({"unchecked", "NonConstantStringShouldBeStringBuffer"}) 165 protected void onActionClass(String className) { 166 Class actionClass; 167 try { 168 actionClass = ClassLoaderUtil.loadClass(className, this.getClass()); 169 } catch (ClassNotFoundException cnfex) { 170 throw new MadvocException("Unable to load Madvoc action class '" + className + "'.", cnfex); 171 } 172 173 MadvocAction madvocActionAnnotation = (MadvocAction) actionClass.getAnnotation(MadvocAction.class); 175 if (madvocActionAnnotation == null) { 176 return; 177 } 178 String classActionPath = madvocActionAnnotation.value().trim(); 179 if (classActionPath.length() == 0) { 180 classActionPath = parseActionPath(actionClass.getName()); 181 } else { 182 classActionPath = StringUtil.replace(classActionPath, jockerName, parseActionPath(actionClass.getName())); 183 } 184 if (classActionPath.charAt(0) != '/') { 185 classActionPath = '/' + classActionPath; 186 } 187 188 189 ActionInterceptor[] classInterceptors = null; 191 InterceptedBy interceptedBy = (InterceptedBy) actionClass.getAnnotation(InterceptedBy.class); 192 if (interceptedBy != null) { 193 classInterceptors = buildInterceptors(interceptedBy.value()); 194 } 195 196 ClassDescriptor cd = DefaultIntrospector.lookup(actionClass); 197 Method [] allPublicMethods = cd.getAllMethods(); 198 for (Method method : allPublicMethods) { 199 if (ReflectUtil.isBeanProperty(method) == true) { 200 continue; 201 } 202 String actionPath = classActionPath; 204 if (actionPath.endsWith("/") == false) { 205 actionPath += '.'; 206 } 207 Action methodAnnotation = method.getAnnotation(Action.class); 208 if ((methodAnnotation != null) && (methodAnnotation.value().length() > 0)) { 209 String value = methodAnnotation.value().trim(); 210 if (value.equals(Action.IGNORE) == true) { 211 continue; 212 } 213 value = StringUtil.replace(value, jockerName, method.getName()); 214 value = StringUtil.replace(value, jockerPrefix, classActionPath); 215 if (value.charAt(0) == '/') { 216 actionPath = value; 217 } else { 218 actionPath += value; 219 } 220 } else { 221 actionPath += method.getName() + '.' + extension; 222 } 223 224 ActionInterceptor[] actionInterceptors = classInterceptors; 226 interceptedBy = (InterceptedBy) actionClass.getAnnotation(InterceptedBy.class); 227 if (interceptedBy != null) { 228 actionInterceptors = buildInterceptors(interceptedBy.value()); 229 } 230 231 ActionConfig actionConfig = new ActionConfig(actionPath, actionClass, method, actionInterceptors); 233 webapp.register(actionConfig); 234 } 235 } 236 237 238 242 protected void onConfigClass(String className) { 243 Class configClass; 244 try { 245 configClass = ClassLoaderUtil.loadClass(className, this.getClass()); 246 } catch (ClassNotFoundException cnfex) { 247 throw new MadvocException("Unable to load Madvoc config class '" + className + "'.", cnfex); 248 } 249 250 if ((configClass == this.getClass()) || (configClass == MadvocConfig.class)) { 251 return; 252 } 253 if (ReflectUtil.isSubclass(configClass, MadvocConfig.class) == true) { 254 try { 255 externalConfigs.add((MadvocConfig) configClass.newInstance()); 256 } catch (Exception ex) { 257 throw new MadvocException("Unable to use Madvoc configuration class '" + className + "'.", ex); 258 } 259 } 260 } 261 262 263 266 protected void onResultClass(String className) { 267 Class resultClass; 268 try { 269 resultClass = ClassLoaderUtil.loadClass(className, this.getClass()); 270 } catch (ClassNotFoundException cnfex) { 271 throw new MadvocException("Unable to load Madvoc result class '" + className + "'.", cnfex); 272 } 273 274 if (resultClass == ActionResult.class) { 275 return; 276 } 277 if (ReflectUtil.isSubclass(resultClass, ActionResult.class) == true) { 278 try { 279 ActionResult result = (ActionResult) resultClass.newInstance(); 280 webapp.register(result); 281 } catch (Exception ex) { 282 throw new MadvocException("Unable to use Madvoc result class '" + className + "'."); 283 } 284 } 285 } 286 287 289 290 295 @SuppressWarnings ({"unchecked"}) 296 protected ActionInterceptor[] buildInterceptors(Class <? extends ActionInterceptor>[] classes) { 297 ArrayList<ActionInterceptor> actionInterceptors = new ArrayList<ActionInterceptor>(classes.length); 298 for (int i = 0; i < classes.length; i++) { 299 Class <? extends ActionInterceptor> actionInterceptorClass = classes[i]; 300 if (ReflectUtil.isSubclass(actionInterceptorClass, ActionInterceptorStack.class) == true) { 301 ActionInterceptorStack stack = (ActionInterceptorStack) webapp.buildInterceptor(actionInterceptorClass); 302 Class <? extends ActionInterceptor>[] stackInterceptors = stack.getInterceptors(); 303 classes = (Class <? extends ActionInterceptor>[]) ArraysUtil.insert(classes, stackInterceptors, i + 1, Class .class); 304 continue; 305 } 306 ActionInterceptor interceptor = interceptorsPool.get(actionInterceptorClass); 307 if (interceptor == null) { 308 interceptor = webapp.buildInterceptor(actionInterceptorClass); 309 interceptorsPool.put(actionInterceptorClass, interceptor); 310 } 311 actionInterceptors.add(interceptor); 312 } 313 return actionInterceptors.toArray(new ActionInterceptor[actionInterceptors.size()]); 314 } 315 316 318 321 protected String parseActionPath(String className) { 322 int i = className.lastIndexOf('.'); 323 if (i != -1) { 324 className = className.substring(i + 1); 325 } 326 className = className.substring(0, className.length() - actionClassSuffix.length()); 327 return StringUtil.uncapitalize(className); 328 } 329 330 } 331 | Popular Tags |