This class reads a WSDL and creates a dynamic client from it.
Use
(or other overloads) to create a client.
It uses the JAXB data binding. It does not set up complex interceptors for
features such as attachments.
See
for an alternative that sets up JAX-WS endpoints.
This class may be subclassed to allow for other endpoints or behaviors.
| Method from org.apache.cxf.endpoint.dynamic.DynamicClientFactory Detail: |
static void addClasspathFromManifest(StringBuilder classPath,
File file) throws IOException, URISyntaxException {
JarFile jar = new JarFile(file);
Attributes attr = null;
if (jar.getManifest() != null) {
attr = jar.getManifest().getMainAttributes();
}
if (attr != null) {
String cp = attr.getValue("Class-Path");
while (cp != null) {
String fileName = cp;
int idx = fileName.indexOf(' ");
if (idx != -1) {
fileName = fileName.substring(0, idx);
cp = cp.substring(idx + 1).trim();
} else {
cp = null;
}
URI uri = new URI(fileName);
File f2;
if (uri.isAbsolute()) {
f2 = new File(uri);
} else {
f2 = new File(file, fileName);
}
if (f2.exists()) {
classPath.append(f2.getAbsolutePath());
classPath.append(System.getProperty("path.separator"));
}
}
}
}
|
static boolean compileJavaSrc(String classPath,
List srcList,
String dest) {
String[] javacCommand = new String[srcList.size() + 7];
javacCommand[0] = "javac";
javacCommand[1] = "-classpath";
javacCommand[2] = classPath;
javacCommand[3] = "-d";
javacCommand[4] = dest;
javacCommand[5] = "-target";
javacCommand[6] = "1.5";
int i = 7;
for (File f : srcList) {
javacCommand[i++] = f.getAbsolutePath();
}
org.apache.cxf.common.util.Compiler javaCompiler
= new org.apache.cxf.common.util.Compiler();
return javaCompiler.internalCompile(javacCommand, 7);
}
|
public Client createClient(String wsdlUrl) {
return createClient(wsdlUrl, (QName)null, (QName)null);
}
Create a new Client instance using the WSDL to be loaded
from the specified URL and using the current classloading context. |
public Client createClient(String wsdlUrl,
ClassLoader classLoader) {
return createClient(wsdlUrl, null, classLoader, null);
}
Create a new Client instance using the WSDL to be loaded
from the specified URL and with the specified ClassLoader
as parent. |
public Client createClient(String wsdlUrl,
QName service) {
return createClient(wsdlUrl, service, null);
}
|
public Client createClient(String wsdlUrl,
QName service,
QName port) {
return createClient(wsdlUrl, service, null, port);
}
|
public Client createClient(String wsdlUrl,
QName service,
ClassLoader classLoader,
QName port) {
if (classLoader == null) {
classLoader = Thread.currentThread().getContextClassLoader();
}
URL u = composeUrl(wsdlUrl);
LOG.log(Level.FINE, "Creating client from URL " + u.toString());
ClientImpl client = new ClientImpl(bus, u, service, port,
getEndpointImplFactory());
Service svc = client.getEndpoint().getService();
//all SI's should have the same schemas
Collection< SchemaInfo > schemas = svc.getServiceInfos().get(0).getSchemas();
SchemaCompiler compiler = XJC.createSchemaCompiler();
ErrorListener elForRun = new InnerErrorListener(wsdlUrl);
compiler.setErrorListener(elForRun);
addSchemas(wsdlUrl, schemas, compiler);
S2JJAXBModel intermediateModel = compiler.bind();
JCodeModel codeModel = intermediateModel.generateCode(null, elForRun);
StringBuilder sb = new StringBuilder();
boolean firstnt = false;
for (Iterator< JPackage > packages = codeModel.packages(); packages.hasNext();) {
JPackage jpackage = packages.next();
if (!isValidPackage(jpackage)) {
continue;
}
if (firstnt) {
sb.append(':");
} else {
firstnt = true;
}
sb.append(jpackage.name());
}
outputDebug(codeModel);
String packageList = sb.toString();
// our hashcode + timestamp ought to be enough.
String stem = toString() + "-" + System.currentTimeMillis();
File src = new File(tmpdir, stem + "-src");
if (!src.mkdir()) {
throw new IllegalStateException("Unable to create working directory " + src.getPath());
}
try {
FileCodeWriter writer = new FileCodeWriter(src);
codeModel.build(writer);
} catch (IOException e) {
throw new IllegalStateException("Unable to write generated Java files for schemas: "
+ e.getMessage(), e);
}
File classes = new File(tmpdir, stem + "-classes");
if (!classes.mkdir()) {
throw new IllegalStateException("Unable to create working directory " + src.getPath());
}
StringBuilder classPath = new StringBuilder();
try {
setupClasspath(classPath, classLoader);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
List< File > srcFiles = FileUtils.getFilesRecurse(src, ".+\\.java$");
if (!compileJavaSrc(classPath.toString(), srcFiles, classes.toString())) {
LOG.log(Level.SEVERE , new Message("COULD_NOT_COMPILE_SRC", LOG, wsdlUrl).toString());
}
FileUtils.removeDir(src);
URLClassLoader cl;
try {
cl = new URLClassLoader(new URL[] {classes.toURI().toURL()}, classLoader);
} catch (MalformedURLException mue) {
throw new IllegalStateException("Internal error; a directory returns a malformed URL: "
+ mue.getMessage(), mue);
}
JAXBContext context;
Map< String, Object > contextProperties = jaxbContextProperties;
if (contextProperties == null) {
contextProperties = Collections.emptyMap();
}
try {
if (StringUtils.isEmpty(packageList)) {
context = JAXBContext.newInstance(new Class[0], contextProperties);
} else {
context = JAXBContext.newInstance(packageList, cl, contextProperties);
}
} catch (JAXBException jbe) {
throw new IllegalStateException("Unable to create JAXBContext for generated packages: "
+ jbe.getMessage(), jbe);
}
JAXBDataBinding databinding = new JAXBDataBinding();
databinding.setContext(context);
svc.setDataBinding(databinding);
ServiceInfo svcfo = client.getEndpoint().getEndpointInfo().getService();
// Setup the new classloader!
Thread.currentThread().setContextClassLoader(cl);
TypeClassInitializer visitor = new TypeClassInitializer(svcfo, intermediateModel);
visitor.walk();
// delete the classes files
FileUtils.removeDir(classes);
return client;
}
|
protected EndpointImplFactory getEndpointImplFactory() {
return SimpleEndpointImplFactory.getSingleton();
}
|
public Map getJaxbContextProperties() {
return jaxbContextProperties;
}
Return the map of JAXB context properties used at the time that we create new contexts. |
public boolean isSimpleBindingEnabled() {
return simpleBindingEnabled;
}
|
public static DynamicClientFactory newInstance() {
Bus bus = CXFBusFactory.getThreadDefaultBus();
return new DynamicClientFactory(bus);
}
Create a new instance using a default Bus. |
public static DynamicClientFactory newInstance(Bus b) {
return new DynamicClientFactory(b);
}
Create a new instance using a specific Bus. |
public void setJaxbContextProperties(Map jaxbContextProperties) {
this.jaxbContextProperties = jaxbContextProperties;
}
Set the map of JAXB context properties used at the time that we create new contexts. |
public void setSimpleBindingEnabled(boolean simpleBindingEnabled) {
this.simpleBindingEnabled = simpleBindingEnabled;
}
|
public void setTemporaryDirectory(String dir) {
tmpdir = dir;
}
|
static void setupClasspath(StringBuilder classPath,
ClassLoader classLoader) throws IOException, URISyntaxException {
ClassLoader scl = ClassLoader.getSystemClassLoader();
ClassLoader tcl = classLoader;
do {
if (tcl instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader)tcl).getURLs();
if (urls == null) {
urls = new URL[0];
}
for (URL url : urls) {
if (url.getProtocol().startsWith("file")) {
File file;
try {
file = new File(url.toURI().getPath());
} catch (URISyntaxException urise) {
file = new File(url.getPath());
}
if (file.exists()) {
classPath.append(file.getAbsolutePath())
.append(System
.getProperty("path.separator"));
if (file.getName().endsWith(".jar")) {
addClasspathFromManifest(classPath, file);
}
}
}
}
}
tcl = tcl.getParent();
if (null == tcl) {
break;
}
} while(!tcl.equals(scl.getParent()));
}
|