1 package org.objectweb.celtix.jbi.se; 2 3 import java.io.File ; 4 import java.lang.reflect.Modifier ; 5 import java.net.MalformedURLException ; 6 import java.net.URL ; 7 import java.net.URLClassLoader ; 8 import java.util.ArrayList ; 9 import java.util.Collection ; 10 import java.util.List ; 11 import java.util.logging.Level ; 12 import java.util.logging.Logger ; 13 14 import javax.jbi.component.ComponentContext; 15 import javax.jws.WebService; 16 import javax.xml.namespace.QName ; 17 import javax.xml.parsers.DocumentBuilder ; 18 import javax.xml.parsers.DocumentBuilderFactory ; 19 20 import org.w3c.dom.Document ; 21 import org.w3c.dom.Element ; 22 import org.w3c.dom.Node ; 23 import org.w3c.dom.NodeList ; 24 25 import org.objectweb.celtix.Bus; 26 import org.objectweb.celtix.bus.jaxws.EndpointImpl; 27 import org.objectweb.celtix.jbi.ServiceConsumer; 28 29 32 public class CeltixServiceUnit { 33 34 private static final Logger LOG = Logger.getLogger(CeltixServiceUnit.class.getName()); 35 36 private final Bus bus; 37 38 private Object serviceImplementation; 39 private ServiceConsumer serviceConsumer; 40 private EndpointImpl endpoint; 41 private final String rootPath; 42 private final ClassLoader parentLoader; 43 private boolean isProvider; 44 private QName serviceName; 45 private String endpointName; 46 47 public CeltixServiceUnit(Bus b, String path, ComponentClassLoader parent) { 48 49 URL url = null; 50 try { 51 url = new File (path + File.separator).toURL(); 52 53 } catch (MalformedURLException ex) { 54 LOG.log(Level.SEVERE, "failed to initialize service unit", ex); 55 } 56 bus = b; 57 rootPath = path; 58 parent.addResource(url); 59 parentLoader = parent; 60 parseJbiDescriptor(); 61 } 62 63 public boolean isServiceProvider() { 64 return isProvider; 65 } 66 67 public void stop() { 68 if (endpoint != null) { 69 endpoint.stop(); 70 } else { 71 serviceConsumer.stop(); 72 } 73 } 74 75 76 public QName getServiceName() { 77 78 QName ret = null; 79 80 if (isServiceProvider()) { 81 if (serviceName == null) { 82 WebService ws = (WebService)serviceImplementation.getClass().getAnnotation(WebService.class); 83 serviceName = new QName (ws.targetNamespace(), ws.serviceName()); 84 } 85 ret = serviceName; 86 } 87 return ret; 88 } 89 90 public String getEndpointName() { 91 return endpointName; 92 } 93 94 public void prepare(ComponentContext ctx) { 95 96 try { 97 WebServiceClassFinder finder = new WebServiceClassFinder(rootPath, parentLoader); 98 Collection <Class <?>> classes = finder.findWebServiceClasses(); 99 if (classes.size() > 0) { 100 LOG.info("publishing endpoint"); 101 isProvider = true; 102 Class <?> clz = classes.iterator().next(); 103 serviceImplementation = clz.newInstance(); 104 endpoint = new EndpointImpl(bus, serviceImplementation, null); 105 endpoint.publish("http://foo/bar/baz"); 107 } else { 108 LOG.info("starting consumer"); 109 classes = finder.findServiceConsumerClasses(); 110 Class <?> clz = classes.iterator().next(); 111 LOG.fine("starting consumer: " + clz); 112 serviceConsumer = (ServiceConsumer)clz.newInstance(); 113 serviceConsumer.setComponentContext(ctx); 114 new Thread (serviceConsumer).start(); 115 } 116 } catch (Exception ex) { 117 if (ex.getCause() != null) { 118 ex = (Exception )ex.getCause(); 119 } 120 LOG.log(Level.SEVERE, "failed to publish endpoint", ex); 121 } 124 } 125 126 127 public ClassLoader getClassLoader() { 128 return parentLoader; 129 } 130 131 132 Document getWsdlAsDocument() { 133 134 Document doc = null; 135 try { 136 WebService ws = serviceImplementation.getClass().getAnnotation(WebService.class); 137 if (ws != null) { 138 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 139 factory.setNamespaceAware(true); 140 DocumentBuilder builder = factory.newDocumentBuilder(); 141 doc = builder.parse(ws.wsdlLocation()); 142 } else { 143 LOG.severe("could not get WebService annotation from " + serviceImplementation); 144 } 145 } catch (Exception ex) { 146 ex.printStackTrace(); 147 } 148 return doc; 149 } 150 151 152 153 static class WebServiceClassFinder { 154 private final String rootPath; 155 private final ClassLoader parent; 156 157 public WebServiceClassFinder(String argRootPath, ClassLoader loader) { 158 if (argRootPath.endsWith(File.separator)) { 159 argRootPath = argRootPath.substring(0, argRootPath.length() - 2); 160 } 161 rootPath = argRootPath; 162 parent = loader; 163 } 164 165 public Collection <Class <?>> findServiceConsumerClasses() throws MalformedURLException { 166 return find(new Matcher() { 167 public boolean accept(Class <?> clz) { 168 return ServiceConsumer.class.isAssignableFrom(clz) 169 && (clz.getModifiers() & Modifier.ABSTRACT) == 0; 170 } 171 }); 172 } 173 174 public Collection <Class <?>> findWebServiceClasses() throws MalformedURLException { 175 176 return find(new Matcher() { 177 public boolean accept(Class <?> clz) { 178 return clz.getAnnotation(WebService.class) != null 179 && (clz.getModifiers() & Modifier.ABSTRACT) == 0; 180 } 181 }); 182 } 183 184 private Collection <Class <?>> find(Matcher matcher) throws MalformedURLException { 185 List <Class <?>> classes = new ArrayList <Class <?>>(); 186 187 File root = new File (rootPath); 188 URL [] urls = {root.toURL()}; 189 URLClassLoader loader = new URLClassLoader (urls, parent); 190 191 find(root, loader, classes, matcher); 192 return classes; 193 } 194 195 private void find(File dir, ClassLoader loader, Collection <Class <?>> classes, 196 Matcher matcher) { 197 198 File [] files = dir.listFiles(); 199 for (File f : files) { 200 if (f.toString().endsWith(".class")) { 201 Class <?> clz = loadClass(loader, f); 202 if (matcher.accept(clz)) { 203 classes.add(clz); 204 } 205 } else if (f.isDirectory()) { 206 find(f, loader, classes, matcher); 207 } 208 } 209 } 210 211 212 private Class <?> loadClass(ClassLoader loader, File classFile) { 213 214 String fileName = classFile.toString(); 215 String className = fileName.substring(rootPath.length() + 1); 216 className = className.substring(0, className.length() - ".class".length()) 217 .replace(File.separatorChar, '.'); 218 219 try { 220 return loader.loadClass(className); 221 } catch (ClassNotFoundException ex) { 222 LOG.severe("failed to load class: " + className); 223 } 224 return null; 225 } 226 227 interface Matcher { 228 boolean accept(Class <?> clz); 229 } 230 } 231 232 private void parseJbiDescriptor() { 233 234 File metaInf = new File (rootPath, "META-INF"); 237 File jbiXml = new File (metaInf, "jbi.xml"); 238 try { 239 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 240 factory.setNamespaceAware(true); 241 DocumentBuilder builder = factory.newDocumentBuilder(); 242 Document doc = builder.parse(jbiXml.toURL().toString()); 243 244 Element providesEl = (Element )findNode(doc.getDocumentElement(), "provides"); 245 endpointName = providesEl.getAttribute("endpoint-name"); 246 } catch (Exception ex) { 247 LOG.log(Level.SEVERE, "error parsing " + jbiXml, ex); 248 } 249 250 } 251 252 253 private Node findNode(Node root, String name) { 254 255 if (name.equals(root.getNodeName())) { 256 return root; 257 } 258 259 NodeList children = root.getChildNodes(); 260 for (int i = 0; i < children.getLength(); i++) { 261 Node child = children.item(i); 262 Node found = findNode(child, name); 263 if (found != null) { 264 return found; 265 } 266 } 267 return null; 268 } 269 270 271 } 272 | Popular Tags |