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 }