Hi,
I am working on implementing the JiBX databinding implementation for Apache
CXF and I've come across the following situation which I think could be a
possible shortcoming. I've also attached two patches as a solution for that.
I've used the following code to start up a simple service and I've used
serviceFactoryBean.setSchemaLocations() method to pass a list of schema
locations.
LibraryServiceImpl libraryServiceImpl = new LibraryServiceImpl();
ServerFactoryBean svrFactory = new ServerFactoryBean();
ArrayList<String> schemaLocations = new ArrayList<String>();
schemaLocations.add("file:///home/nilupa/Documents/experiment/types.xsd");
svrFactory.setSchemaLocations(schemaLocations);
svrFactory.setServiceClass(LibraryService.class);
svrFactory.setAddress("http://localhost:8080/LibraryService");
svrFactory.setServiceBean(libraryServiceImpl);
svrFactory.getServiceFactory().setDataBinding(new JiBXDataBinding());
svrFactory.create();
However that information is inaccessible in the service model or in the
AbstractDataBinding classes. When I looked in more deeply I found that
AbstarctDataBinding is populated with schemas that are specified
by serviceFactoryBean.setSchemaLocations() when no DataBinding is specified
and when ReflectionServiceFactoryBean.createDefaultDataBinding() is invoked.
I think AbstarctDataBinding should be populated not only when no databinding
is specified but also when particular databinding object is provided with
schemas specified by setSchemaLocations() method.
In my propose fix ReflectionServiceFactoryBean.fillDataBindingSchemas()
method does the actual filling and it is invoked before
AbstractServiceFactoryBean.initializeDataBindings() is invoked in
ReflectionServiceFactoryBean.initializeDataBindings() method. Perhaps we
should implement fillDataBindingSchemas() in AbstractServiceFactoryBean
class instead of ReflectionServiceFactoryBean class.
Any thoughts ?
Thanks & Best Regards,
Nilupa
Index: rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java
===================================================================
--- rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java (revision 946497)
+++ rt/frontend/simple/src/main/java/org/apache/cxf/service/factory/ReflectionServiceFactoryBean.java (working copy)
@@ -181,7 +181,6 @@
private Map<Method, Boolean> isRpcCache = new HashMap<Method, Boolean>();
private String styleCache;
private Boolean defWrappedCache;
- private List<String> schemaLocations;
public ReflectionServiceFactoryBean() {
getServiceConfigurations().add(0, new DefaultServiceConfiguration());
@@ -229,39 +228,7 @@
}
retVal = db;
}
- if (retVal instanceof AbstractDataBinding && schemaLocations != null) {
- ResourceManager rr = getBus().getExtension(ResourceManager.class);
-
- List<DOMSource> schemas = new ArrayList<DOMSource>();
- for (String l : schemaLocations) {
- URL url = rr.resolveResource(l, URL.class);
-
- if (url == null) {
- URIResolver res;
- try {
- res = new URIResolver(l);
- } catch (IOException e) {
- throw new ServiceConstructionException(new Message("INVALID_SCHEMA_URL", LOG, l), e);
- }
-
- if (!res.isResolved()) {
- throw new ServiceConstructionException(new Message("INVALID_SCHEMA_URL", LOG, l));
- }
- url = res.getURL();
- }
-
- Document d;
- try {
- d = DOMUtils.readXml(url.openStream());
- } catch (Exception e) {
- throw new ServiceConstructionException(
- new Message("ERROR_READING_SCHEMA", LOG, l), e);
- }
- schemas.add(new DOMSource(d, url.toString()));
- }
-
- ((AbstractDataBinding)retVal).setSchemas(schemas);
- }
+
return retVal;
}
public void reset() {
@@ -2041,7 +2008,14 @@
addFault(service, op, exClazz);
}
}
-
+
+ protected void initializeDataBindings() {
+ if (getDataBinding() instanceof AbstractDataBinding) {
+ initializeDataBindingSchemas();
+ }
+ super.initializeDataBindings();
+ }
+
protected void initializeDefaultInterceptors() {
super.initializeDefaultInterceptors();
@@ -2569,8 +2543,34 @@
public void setValidate(boolean validate) {
this.validate = validate;
}
-
- public void setSchemaLocations(List<String> schemaLocations) {
- this.schemaLocations = schemaLocations;
+
+ private void initializeDataBindingSchemas() {
+ if (schemaLocations != null) {
+ ResourceManager rr = getBus().getExtension(ResourceManager.class);
+ List<DOMSource> schemas = new ArrayList<DOMSource>();
+ for (String l : schemaLocations) {
+ URL url = rr.resolveResource(l, URL.class);
+ if (url == null) {
+ URIResolver res;
+ try {
+ res = new URIResolver(l);
+ } catch (IOException e) {
+ throw new ServiceConstructionException(new Message("INVALID_SCHEMA_URL", LOG, l), e);
+ }
+ if (!res.isResolved()) {
+ throw new ServiceConstructionException(new Message("INVALID_SCHEMA_URL", LOG, l));
+ }
+ url = res.getURL();
+ }
+ Document d;
+ try {
+ d = DOMUtils.readXml(url.openStream());
+ } catch (Exception e) {
+ throw new ServiceConstructionException(new Message("ERROR_READING_SCHEMA", LOG, l), e);
+ }
+ schemas.add(new DOMSource(d, url.toString()));
+ }
+ ((AbstractDataBinding)getDataBinding()).setSchemas(schemas);
+ }
}
}
Index: rt/core/src/main/java/org/apache/cxf/service/factory/AbstractServiceFactoryBean.java
===================================================================
--- rt/core/src/main/java/org/apache/cxf/service/factory/AbstractServiceFactoryBean.java (revision 946497)
+++ rt/core/src/main/java/org/apache/cxf/service/factory/AbstractServiceFactoryBean.java (working copy)
@@ -19,16 +19,30 @@
package org.apache.cxf.service.factory;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.logging.Logger;
+import javax.xml.transform.dom.DOMSource;
+
+import org.w3c.dom.Document;
+
import org.apache.cxf.Bus;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.databinding.AbstractDataBinding;
import org.apache.cxf.databinding.DataBinding;
+import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.OneWayProcessorInterceptor;
import org.apache.cxf.interceptor.OutgoingChainInterceptor;
import org.apache.cxf.interceptor.ServiceInvokerInterceptor;
+import org.apache.cxf.resource.ResourceManager;
+import org.apache.cxf.resource.URIResolver;
import org.apache.cxf.service.Service;
public abstract class AbstractServiceFactoryBean {
@@ -39,7 +53,11 @@
private Service service;
private List<FactoryBeanListener> listeners = new LinkedList<FactoryBeanListener>();
private Map<String, Object> sessionState = new HashMap<String, Object>();
+ protected List<String> schemaLocations;
+ private static final Logger LOG = LogUtils.getL7dLogger(AbstractServiceFactoryBean.class,
+ "SimpleMessages");
+
public abstract Service create();
/**
@@ -64,7 +82,6 @@
protected void initializeDataBindings() {
getDataBinding().initialize(getService());
-
service.setDataBinding(getDataBinding());
sendEvent(FactoryBeanListener.Event.DATABINDING_INITIALIZED, dataBinding);
}
@@ -106,5 +123,44 @@
protected void setService(Service service) {
this.service = service;
}
-
+
+ public void setSchemaLocations(List<String> schemaLocations) {
+ this.schemaLocations = schemaLocations;
+ }
+
+ public List<String> getSchemaLocations() {
+ return schemaLocations;
+ }
+
+ private void fillDataBindingSchemas() {
+ if (!(getDataBinding() instanceof AbstractDataBinding) || schemaLocations == null) {
+ return;
+ }
+ ResourceManager rr = getBus().getExtension(ResourceManager.class);
+ List<DOMSource> schemas = new ArrayList<DOMSource>();
+ for (String l : schemaLocations) {
+ URL url = rr.resolveResource(l, URL.class);
+ if (url == null) {
+ URIResolver res;
+ try {
+ res = new URIResolver(l);
+ } catch (IOException e) {
+ throw new ServiceConstructionException(new Message("INVALID_SCHEMA_URL", LOG, l), e);
+ }
+
+ if (!res.isResolved()) {
+ throw new ServiceConstructionException(new Message("INVALID_SCHEMA_URL", LOG, l));
+ }
+ url = res.getURL();
+ }
+ Document d;
+ try {
+ d = DOMUtils.readXml(url.openStream());
+ } catch (Exception e) {
+ throw new ServiceConstructionException(new Message("ERROR_READING_SCHEMA", LOG, l), e);
+ }
+ schemas.add(new DOMSource(d, url.toString()));
+ }
+ ((AbstractDataBinding)getDataBinding()).setSchemas(schemas);
+ }
}