blob: 84529752de4f16eeeeb9c62aa5aa9943fa76b5e4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.tuscany.sca.databinding.jaxb;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamResult;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.databinding.XMLTypeHelper;
import org.apache.tuscany.sca.interfacedef.DataType;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
import org.apache.tuscany.sca.interfacedef.util.TypeInfo;
import org.apache.tuscany.sca.interfacedef.util.XMLType;
import org.apache.tuscany.sca.xsd.XSDFactory;
import org.apache.tuscany.sca.xsd.XSDefinition;
import org.oasisopen.sca.ServiceRuntimeException;
import org.w3c.dom.Document;
public class JAXBTypeHelper implements XMLTypeHelper {
private static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
private static final String ANYTYPE_NAME = "anyType";
private static final QName ANYTYPE_QNAME = new QName(SCHEMA_NS, ANYTYPE_NAME);
private JAXBContextHelper contextHelper;
public JAXBTypeHelper(ExtensionPointRegistry registry) {
super();
contextHelper = JAXBContextHelper.getInstance(registry);
}
public TypeInfo getTypeInfo(Class javaType, Object logical) {
QName xmlType = JavaXMLMapper.getXMLType(javaType);
if (xmlType != null) {
return new TypeInfo(xmlType, true, null);
} else if (javaType.isInterface()) {
return new TypeInfo(ANYTYPE_QNAME, true, null);
} else {
// types.add(javaType);
if (logical instanceof XMLType) {
xmlType = ((XMLType)logical).getTypeName();
}
if (xmlType == null) {
xmlType = new QName(JAXBContextHelper.jaxbDecapitalize(javaType.getSimpleName()));
}
return new TypeInfo(xmlType, false, null);
}
}
/*
public List<XSDefinition> getSchemaDefinitions(XSDFactory factory, ModelResolver resolver) {
List<XSDefinition> definitions = new ArrayList<XSDefinition>();
generateJAXBSchemas(definitions, factory);
return definitions;
}
*/
public static Map<String, String> generateSchema(JAXBContext context) throws IOException {
StringResolverImpl resolver = new StringResolverImpl();
context.generateSchema(resolver);
Map<String, String> xsds = new HashMap<String, String>();
for (Map.Entry<String, StreamResult> xsd : resolver.getResults().entrySet()) {
xsds.put(xsd.getKey(), xsd.getValue().getWriter().toString());
}
return xsds;
}
// private static class XSDResolver implements URIResolver {
// private Map<String, String> xsds;
//
// public XSDResolver(Map<String, String> xsds) {
// super();
// this.xsds = xsds;
// }
//
// public InputSource resolveEntity(java.lang.String namespace,
// java.lang.String schemaLocation,
// java.lang.String baseUri) {
// String xsd = xsds.get(schemaLocation);
// if (xsd == null) {
// return null;
// }
// return new InputSource(new StringReader(xsd));
// }
//
// }
/*
private void generateJAXBSchemas1(List<XSDefinition> definitions, XSDFactory factory) {
if (types.size() > 0) {
try {
XmlSchemaCollection collection = new XmlSchemaCollection();
Class[] typesArray = new Class[types.size()];
typesArray = types.toArray(typesArray);
JAXBContext context = JAXBContextHelper.createJAXBContext(typesArray);
Map<String, String> results = generateSchema(context);
collection.setSchemaResolver(new XSDResolver(results));
for (Map.Entry<String, String> entry : results.entrySet()) {
XSDefinition definition = factory.createXSDefinition();
int index = entry.getKey().lastIndexOf('#');
String ns = entry.getKey().substring(0, index);
String file = entry.getKey().substring(index + 1);
definition.setUnresolved(true);
definition.setNamespace(ns);
definition.setSchema(collection.read(new StringReader(entry.getValue()), null));
definition.setSchemaCollection(collection);
definition.setUnresolved(false);
definitions.add(definition);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
*/
private static class DOMResolverImpl extends SchemaOutputResolver {
private Map<String, DOMResult> results = new HashMap<String, DOMResult>();
@Override
public Result createOutput(String ns, String file) throws IOException {
DOMResult result = new DOMResult();
// TUSCANY-2498: Set the system id to "" so that the xsd:import doesn't produce
// an illegal schemaLocation attr
result.setSystemId("");
results.put(ns, result);
return result;
}
public Map<String, DOMResult> getResults() {
return results;
}
}
/*
private void generateJAXBSchemas(List<XSDefinition> definitions, XSDFactory factory) {
if (types.size() > 0) {
try {
Class<?>[] typesArray = new Class<?>[types.size()];
typesArray = types.toArray(typesArray);
JAXBContext context = JAXBContext.newInstance(typesArray);
generateSchemas(definitions, factory, context);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
*/
private void generateSchemas(List<XSDefinition> definitions, XSDFactory factory, JAXBContext context)
throws IOException {
DOMResolverImpl resolver = new DOMResolverImpl();
context.generateSchema(resolver);
Map<String, DOMResult> results = resolver.getResults();
for (Map.Entry<String, DOMResult> entry : results.entrySet()) {
XSDefinition definition = factory.createXSDefinition();
definition.setUnresolved(true);
definition.setDocument((Document)entry.getValue().getNode());
definition.setNamespace(entry.getKey());
URI location = null;
try {
location = new URI(entry.getValue().getSystemId());
} catch (URISyntaxException e) {
// ignore: use null value
}
definition.setLocation(location);
definitions.add(definition);
}
}
private static class StringResolverImpl extends SchemaOutputResolver {
private Map<String, StreamResult> results = new HashMap<String, StreamResult>();
@Override
public Result createOutput(String ns, String file) throws IOException {
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
String sysId = ns + '#' + file;
result.setSystemId(sysId);
results.put(sysId, result);
return result;
}
public Map<String, StreamResult> getResults() {
return results;
}
}
public List<XSDefinition> getSchemaDefinitions(XSDFactory factory, ModelResolver resolver, Interface intf) {
try {
JAXBContext context = contextHelper.createJAXBContext(intf, false);
List<XSDefinition> definitions = new ArrayList<XSDefinition>();
generateSchemas(definitions, factory, context);
return definitions;
} catch (Throwable e) {
throw new ServiceRuntimeException(e);
}
}
public List<XSDefinition> getSchemaDefinitions(XSDFactory factory, ModelResolver resolver, List<DataType> dataTypes) {
try {
JAXBContext context = contextHelper.createJAXBContext(dataTypes);
List<XSDefinition> definitions = new ArrayList<XSDefinition>();
generateSchemas(definitions, factory, context);
return definitions;
} catch (Throwable e) {
throw new ServiceRuntimeException(e);
}
}
}