001 // Copyright 2005 The Apache Software Foundation
002 //
003 // Licensed under the Apache License, Version 2.0 (the "License");
004 // you may not use this file except in compliance with the License.
005 // You may obtain a copy of the License at
006 //
007 // http://www.apache.org/licenses/LICENSE-2.0
008 //
009 // Unless required by applicable law or agreed to in writing, software
010 // distributed under the License is distributed on an "AS IS" BASIS,
011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012 // See the License for the specific language governing permissions and
013 // limitations under the License.
014
015 package org.apache.hivemind.service.impl;
016
017 import java.lang.reflect.Method;
018 import java.lang.reflect.Modifier;
019 import java.util.ArrayList;
020 import java.util.HashSet;
021 import java.util.Iterator;
022 import java.util.List;
023 import java.util.Set;
024
025 import org.apache.hivemind.service.ClassFabUtils;
026 import org.apache.hivemind.service.ClassFactory;
027 import org.apache.hivemind.service.InterfaceFab;
028 import org.apache.hivemind.service.InterfaceSynthesizer;
029 import org.apache.hivemind.service.MethodSignature;
030
031 /**
032 * @author Howard M. Lewis Ship
033 */
034 public class InterfaceSynthesizerImpl implements InterfaceSynthesizer
035 {
036 private ClassFactory _classFactory;
037
038 private static class Operation
039 {
040 private Set _interfaces = new HashSet();
041
042 private Set _interfaceMethods = new HashSet();
043
044 private Set _allMethods = new HashSet();
045
046 private List _interfaceQueue = new ArrayList();
047
048 public Set getInterfaces()
049 {
050 return _interfaces;
051 }
052
053 public Set getNonInterfaceMethodSignatures()
054 {
055 Set result = new HashSet(_allMethods);
056
057 result.removeAll(_interfaceMethods);
058
059 return result;
060 }
061
062 public void processInterfaceQueue()
063 {
064 while (!_interfaceQueue.isEmpty())
065 {
066 Class interfaceClass = (Class) _interfaceQueue.remove(0);
067
068 processInterface(interfaceClass);
069 }
070 }
071
072 private void processInterface(Class interfaceClass)
073 {
074 Class[] interfaces = interfaceClass.getInterfaces();
075
076 for (int i = 0; i < interfaces.length; i++)
077 addInterfaceToQueue(interfaces[i]);
078
079 Method[] methods = interfaceClass.getDeclaredMethods();
080
081 for (int i = 0; i < methods.length; i++)
082 {
083 MethodSignature sig = new MethodSignature(methods[i]);
084
085 _interfaceMethods.add(sig);
086 }
087 }
088
089 private void addInterfaceToQueue(Class interfaceClass)
090 {
091 if (_interfaces.contains(interfaceClass))
092 return;
093
094 _interfaces.add(interfaceClass);
095 _interfaceQueue.add(interfaceClass);
096 }
097
098 public void processClass(Class beanClass)
099 {
100 Class[] interfaces = beanClass.getInterfaces();
101
102 for (int i = 0; i < interfaces.length; i++)
103 addInterfaceToQueue(interfaces[i]);
104
105 Method[] methods = beanClass.getDeclaredMethods();
106
107 for (int i = 0; i < methods.length; i++)
108 {
109 Method m = methods[i];
110 int modifiers = m.getModifiers();
111
112 if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers))
113 continue;
114
115 MethodSignature sig = new MethodSignature(m);
116
117 _allMethods.add(sig);
118 }
119 }
120
121 }
122
123 public Class synthesizeInterface(Class beanClass)
124 {
125 Operation op = new Operation();
126
127 explodeClass(beanClass, op);
128
129 return createInterface(beanClass, op);
130 }
131
132 void explodeClass(Class beanClass, Operation op)
133 {
134 Class current = beanClass;
135
136 while (current != Object.class)
137 {
138 op.processClass(current);
139
140 current = current.getSuperclass();
141 }
142
143 op.processInterfaceQueue();
144 }
145
146 Class createInterface(Class beanClass, Operation op)
147 {
148 String name = ClassFabUtils.generateClassName(beanClass);
149
150 return createInterface(name, op);
151 }
152
153 private Class createInterface(String name, Operation op)
154 {
155 InterfaceFab fab = _classFactory.newInterface(name);
156
157 Iterator i = op.getInterfaces().iterator();
158 while (i.hasNext())
159 {
160 Class interfaceClass = (Class) i.next();
161
162 fab.addInterface(interfaceClass);
163 }
164
165 i = op.getNonInterfaceMethodSignatures().iterator();
166 while (i.hasNext())
167 {
168 MethodSignature sig = (MethodSignature) i.next();
169
170 fab.addMethod(sig);
171 }
172
173 return fab.createInterface();
174 }
175
176 public void setClassFactory(ClassFactory classFactory)
177 {
178 _classFactory = classFactory;
179 }
180 }