001: package org.drools.util;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.lang.reflect.Method;
020:
021: import org.drools.RuntimeDroolsException;
022: import org.drools.Visitor;
023:
024: /**
025: * Java Tip 98: Reflect on the Visitor design pattern. Implement visitors in
026: * Java, using reflection.
027: * http://www.javaworld.com/javaworld/javatips/jw-javatip98.html
028: *
029: * @author Jeremy Blosser
030: */
031: public abstract class ReflectiveVisitor implements Visitor {
032: static final String newline = System.getProperty("line.separator");
033:
034: public void visit(final Object object) {
035: Method method = null;
036: try {
037: if (object != null) {
038: method = getMethod(object.getClass());
039: method.invoke(this , new Object[] { object });
040: } else {
041: method = getClass().getMethod("visitNull",
042: (Class[]) null);
043: method.invoke(this , (Object[]) null);
044: }
045: } catch (final Exception e) {
046: throw new RuntimeDroolsException(e.toString() + " : "
047: + object, e.getCause());
048: }
049: }
050:
051: private Method getMethod(final Class clazz) {
052: Class newClazz = clazz;
053: Method method = null;
054:
055: // Try the superclasses
056: while (method == null && newClazz != Object.class) {
057: String methodName = newClazz.getName();
058: methodName = "visit"
059: + methodName
060: .substring(methodName.lastIndexOf('.') + 1);
061: try {
062: method = getClass().getMethod(methodName,
063: new Class[] { newClazz });
064: } catch (final NoSuchMethodException e) {
065: newClazz = newClazz.getSuperclass();
066: }
067: }
068:
069: // Try the interfaces.
070: if (newClazz == Object.class) {
071: final Class[] interfaces = clazz.getInterfaces();
072: for (int i = 0; i < interfaces.length; i++) {
073: String methodName = interfaces[i].getName();
074: methodName = "visit"
075: + methodName.substring(methodName
076: .lastIndexOf('.') + 1);
077: try {
078: method = getClass().getMethod(methodName,
079: new Class[] { interfaces[i] });
080: } catch (final NoSuchMethodException e) {
081: // swallow
082: }
083: }
084: }
085: if (method == null) {
086: try {
087: method = getClass().getMethod("visitObject",
088: new Class[] { Object.class });
089: } catch (final Exception e) {
090: // Shouldn't happen as long as all Visitors extend this class
091: // and this class continues to implement visitObject(Object).
092: throw new RuntimeDroolsException(e.toString() + " : "
093: + clazz, e.getCause());
094: }
095: }
096: return method;
097: }
098:
099: public void visitObject(final Object object) {
100: System.err.println("no visitor implementation for : "
101: + object.getClass() + " : " + object);
102: }
103: }
|