001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.jaxws.builder; 019 020 import java.io.File; 021 import java.io.OutputStream; 022 import java.lang.reflect.Method; 023 import java.net.MalformedURLException; 024 import java.net.URL; 025 import java.net.URLClassLoader; 026 import java.util.ArrayList; 027 import java.util.Collection; 028 import java.util.SortedSet; 029 030 import org.apache.commons.logging.Log; 031 import org.apache.commons.logging.LogFactory; 032 import org.apache.geronimo.kernel.repository.Artifact; 033 import org.apache.geronimo.kernel.repository.ListableRepository; 034 import org.apache.geronimo.kernel.repository.Repository; 035 import org.apache.geronimo.kernel.repository.Version; 036 037 public class JAXWSTools { 038 039 private static final Log LOG = LogFactory.getLog(JAXWSTools.class); 040 041 private final static String [][] LIBS = 042 { 043 { "org.apache.axis2", "axis2-jaxws-api" }, 044 { "org.apache.geronimo.specs", "geronimo-saaj_1.3_spec" }, 045 { "javax.xml.bind", "jaxb-api" }, 046 { "com.sun.xml.bind", "jaxb-impl" }, 047 { "com.sun.xml.bind", "jaxb-xjc" }, 048 { "com.sun.xml.ws", "jaxws-tools" }, 049 { "com.sun.xml.ws", "jaxws-rt" }, 050 { "org.apache.geronimo.javamail", "geronimo-javamail_1.4_mail"}, 051 { "org.apache.geronimo.specs", "geronimo-activation_1.1_spec"}, 052 { "org.apache.geronimo.specs", "geronimo-annotation_1.0_spec"}, 053 { "org.apache.geronimo.specs", "geronimo-ws-metadata_2.0_spec"}, 054 { "org.apache.geronimo.specs", "geronimo-ejb_3.0_spec"}, 055 { "org.apache.geronimo.specs", "geronimo-interceptor_3.0_spec"}, 056 { "org.apache.geronimo.specs", "geronimo-stax-api_1.0_spec"}, 057 { "org.apache.geronimo.specs", "geronimo-jpa_3.0_spec"}, 058 { "org.apache.geronimo.specs", "geronimo-j2ee-connector_1.5_spec"}, 059 { "org.apache.geronimo.specs", "geronimo-jms_1.1_spec"}, 060 { "org.apache.geronimo.specs", "geronimo-jta_1.1_spec"}, 061 { "org.apache.geronimo.specs", "geronimo-j2ee-management_1.1_spec"}, 062 }; 063 064 private final static Artifact SUN_SAAJ_IMPL_ARTIFACT = new Artifact("com.sun.xml.messaging.saaj","saaj-impl", (Version)null, "jar"); 065 private final static Artifact AXIS2_SAAJ_IMPL_ARTIFACT = new Artifact("org.apache.axis2","axis2-saaj", (Version)null, "jar"); 066 private final static String TOOLS = "tools.jar"; 067 068 private Artifact saajImpl; 069 private boolean overrideContextClassLoader; 070 071 public JAXWSTools() { 072 } 073 074 public void setUseSunSAAJ() { 075 this.saajImpl = SUN_SAAJ_IMPL_ARTIFACT; 076 } 077 078 public void setUseAxis2SAAJ() { 079 this.saajImpl = AXIS2_SAAJ_IMPL_ARTIFACT; 080 } 081 082 public void setOverrideContextClassLoader(boolean overrideContextClassLoader) { 083 this.overrideContextClassLoader = overrideContextClassLoader; 084 } 085 086 public boolean getOverrideContextClassLoader() { 087 return this.overrideContextClassLoader; 088 } 089 090 public static URL[] toURL(File[] jars) throws MalformedURLException { 091 URL [] urls = new URL[jars.length]; 092 for (int i = 0; i < jars.length; i++) { 093 urls[i] = jars[i].toURL(); 094 } 095 return urls; 096 } 097 098 public static String toString(File [] jars) { 099 StringBuffer buf = new StringBuffer(); 100 for (int i = 0; i < jars.length; i++) { 101 buf.append(jars[i].getAbsolutePath()); 102 if (i+1 < jars.length) { 103 buf.append(File.pathSeparatorChar); 104 } 105 } 106 return buf.toString(); 107 } 108 109 public File[] getClasspath(Collection<? extends Repository> repositories) throws Exception { 110 ArrayList<File> jars = new ArrayList<File>(); 111 for (String[] lib : LIBS) { 112 Artifact artifact = new Artifact(lib[0], lib[1], (Version)null, "jar"); 113 jars.add(getLocation(repositories, artifact)); 114 } 115 if (this.saajImpl != null) { 116 jars.add(getLocation(repositories, this.saajImpl)); 117 } 118 addToolsJarLocation(jars); 119 120 return jars.toArray(new File[jars.size()]); 121 } 122 123 private static File getLocation(Collection<? extends Repository> repositories, Artifact artifactQuery) throws Exception { 124 File file = null; 125 126 for (Repository arepository : repositories) { 127 if (arepository instanceof ListableRepository) { 128 ListableRepository repository = (ListableRepository) arepository; 129 SortedSet artifactSet = repository.list(artifactQuery); 130 // if we have exactly one artifact found 131 if (artifactSet.size() == 1) { 132 file = repository.getLocation((Artifact) artifactSet.first()); 133 return file.getAbsoluteFile(); 134 } else if (artifactSet.size() > 1) {// if we have more than 1 artifacts found use the latest one. 135 file = repository.getLocation((Artifact) artifactSet.last()); 136 return file.getAbsoluteFile(); 137 } 138 } 139 } 140 141 throw new Exception("Missing artifact in repositories: " + artifactQuery.toString()); 142 } 143 144 private static void addToolsJarLocation(ArrayList<File> jars) { 145 //create a new File then check exists() 146 String jreHomePath = System.getProperty("java.home"); 147 String javaHomePath = ""; 148 int jreHomePathLength = jreHomePath.length(); 149 if (jreHomePathLength > 0) { 150 int i = jreHomePath.substring(0, jreHomePathLength -1).lastIndexOf(java.io.File.separator); 151 javaHomePath = jreHomePath.substring(0, i); 152 } 153 File jdkhomelib = new File(javaHomePath, "lib"); 154 if (!jdkhomelib.exists()) { 155 LOG.warn("Missing " + jdkhomelib.getAbsolutePath() 156 + ". This may be required for wsgen to run. "); 157 } 158 else { 159 File tools = new File(jdkhomelib, TOOLS); 160 if (!tools.exists()) { 161 LOG.warn("Missing tools.jar in" + jdkhomelib.getAbsolutePath() 162 + ". This may be required for wsgen to run. "); 163 } else { 164 jars.add(tools.getAbsoluteFile()); 165 } 166 } 167 } 168 169 public boolean invokeWsgen(URL[] jars, OutputStream os, String[] arguments) throws Exception { 170 return invoke("wsgen", jars, os, arguments); 171 172 } 173 public boolean invokeWsimport(URL[] jars, OutputStream os, String[] arguments) throws Exception { 174 return invoke("wsimport", jars, os, arguments); 175 } 176 177 private boolean invoke(String toolName, URL[] jars, OutputStream os, String[] arguments) throws Exception { 178 URLClassLoader loader = new URLClassLoader(jars, ClassLoader.getSystemClassLoader()); 179 if (this.overrideContextClassLoader) { 180 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); 181 Thread.currentThread().setContextClassLoader(loader); 182 try { 183 return invoke(toolName, loader, os, arguments); 184 } finally { 185 Thread.currentThread().setContextClassLoader(oldClassLoader); 186 } 187 } else { 188 return invoke(toolName, loader, os, arguments); 189 } 190 } 191 192 private boolean invoke(String toolName, ClassLoader loader, OutputStream os, String[] arguments) throws Exception { 193 LOG.debug("Invoking " + toolName); 194 Class clazz = loader.loadClass("com.sun.tools.ws.spi.WSToolsObjectFactory"); 195 Method method = clazz.getMethod("newInstance"); 196 Object factory = method.invoke(null); 197 Method method2 = clazz.getMethod(toolName, OutputStream.class, String[].class); 198 199 Boolean result = (Boolean) method2.invoke(factory, os, arguments); 200 201 return result; 202 } 203 204 }