001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019:
020: package de.schlund.pfixcore.webservice;
021:
022: import java.lang.reflect.Method;
023: import java.lang.reflect.Modifier;
024: import java.util.ArrayList;
025: import java.util.Collections;
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030: import java.util.Set;
031:
032: import de.schlund.pfixcore.webservice.config.ServiceConfig;
033:
034: /**
035: * @author mleidig@schlund.de
036: */
037: public class ServiceDescriptor {
038:
039: Class<?> serviceClass;
040: Map<String, List<Method>> serviceMethods;
041:
042: public ServiceDescriptor(Class<?> serviceClass)
043: throws ServiceException {
044: this .serviceClass = serviceClass;
045: serviceMethods = introspect(serviceClass);
046: }
047:
048: public ServiceDescriptor(ServiceConfig serviceConfig)
049: throws ServiceException {
050: try {
051: ClassLoader cl = Thread.currentThread()
052: .getContextClassLoader();
053: Class<?> itf = Class.forName(serviceConfig
054: .getInterfaceName(), true, cl);
055: Class<?> clazz = Class.forName(serviceConfig
056: .getImplementationName(), true, cl);
057: serviceMethods = introspect(clazz, itf);
058: serviceClass = itf;
059: } catch (ClassNotFoundException x) {
060: throw new ServiceException(
061: "Can't instantiate service class.", x);
062: }
063: }
064:
065: public Class<?> getServiceClass() {
066: return serviceClass;
067: }
068:
069: private Map<String, List<Method>> introspect(Class<?> clazz,
070: Class<?> itf) throws ServiceException {
071: if (itf != null) {
072: if (!itf.isInterface())
073: throw new IllegalArgumentException("Class '"
074: + itf.getName() + "' is no interface!");
075: if (!itf.isAssignableFrom(clazz))
076: throw new IllegalArgumentException("Class '"
077: + clazz.getName()
078: + "' doesn't implement interface '"
079: + itf.getName() + "'!");
080: }
081: Map<String, List<Method>> methods = new HashMap<String, List<Method>>();
082: Method[] meths = itf.getMethods();
083: for (int i = 0; i < meths.length; i++) {
084: String name = meths[i].getName();
085: Method implMeth = null;
086: try {
087: implMeth = clazz.getMethod(name, meths[i]
088: .getParameterTypes());
089: } catch (NoSuchMethodException x) {
090: throw new IllegalArgumentException("Method '" + name
091: + "' not found!", x);
092: }
093: List<Method> ml = methods.get(name);
094: if (ml == null) {
095: ml = new ArrayList<Method>();
096: methods.put(name, ml);
097: }
098: ml.add(implMeth);
099: }
100: return methods;
101: }
102:
103: private Map<String, List<Method>> introspect(Class<?> clazz)
104: throws ServiceException {
105: Map<String, List<Method>> methods = new HashMap<String, List<Method>>();
106: Class<?> current = clazz;
107: while (current != null && !current.equals(Object.class)) {
108: Method[] meths = current.getDeclaredMethods();
109: for (int i = 0; i < meths.length; i++) {
110: int modifiers = meths[i].getModifiers();
111: if (Modifier.isPublic(modifiers)) {
112: String name = meths[i].getName();
113: List<Method> ml = methods.get(name);
114: if (ml == null) {
115: ml = new ArrayList<Method>();
116: methods.put(name, ml);
117: }
118: ml.add(meths[i]);
119: }
120: }
121: current = current.getSuperclass();
122: }
123: return methods;
124: }
125:
126: public Set<String> getMethods() {
127: return Collections.unmodifiableSet(serviceMethods.keySet());
128: }
129:
130: public List<Method> getMethods(String name) {
131: return Collections.unmodifiableList(serviceMethods.get(name));
132: }
133:
134: public String toString() {
135: StringBuffer sb = new StringBuffer();
136: Iterator<String> it = serviceMethods.keySet().iterator();
137: while (it.hasNext()) {
138: String methName = it.next();
139: sb.append(methName + "\n");
140: }
141: return sb.toString();
142: }
143:
144: }
|