blob: e3ec6dc6b72f92d8ed830e8eb79b31dc8579a4da [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.sdo;
import java.beans.Introspector;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.databinding.XMLTypeHelper;
import org.apache.tuscany.sca.databinding.impl.SimpleTypeMapperImpl;
import org.apache.tuscany.sca.interfacedef.DataType;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper;
import org.apache.tuscany.sca.interfacedef.util.TypeInfo;
import org.apache.tuscany.sca.interfacedef.util.WrapperInfo;
import org.apache.tuscany.sca.interfacedef.util.XMLType;
import org.apache.tuscany.sca.xsd.XSDFactory;
import org.apache.tuscany.sca.xsd.XSDefinition;
import org.osoa.sca.ServiceRuntimeException;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSParser;
import commonj.sdo.Type;
import commonj.sdo.helper.TypeHelper;
import commonj.sdo.helper.XSDHelper;
public class SDOTypeHelper implements XMLTypeHelper {
private static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
private TypeHelper typeHelper;
private XSDHelper xsdHelper;
// private Map<String, List<Type>> xsdTypesMap = new HashMap<String, List<Type>>();
// private Map<String, List<Type>> typesMap = new HashMap<String, List<Type>>();
public SDOTypeHelper() {
super();
typeHelper = SDOContextHelper.getDefaultHelperContext().getTypeHelper();
xsdHelper = SDOContextHelper.getDefaultHelperContext().getXSDHelper();
}
public TypeInfo getTypeInfo(Class javaType, Object logical) {
QName xmlType = JavaXMLMapper.getXMLType(javaType);
if (xmlType != null) {
return new TypeInfo(xmlType, true, null);
} else if (javaType == commonj.sdo.DataObject.class) {
return new TypeInfo(SimpleTypeMapperImpl.XSD_ANYTYPE, true, null);
} else {
// introspect(javaType, xsdTypesMap, typesMap);
if (logical instanceof XMLType) {
xmlType = ((XMLType)logical).getTypeName();
}
if (xmlType == null) {
xmlType =
new QName(JavaXMLMapper.getNamespace(javaType), Introspector.decapitalize(javaType.getSimpleName()));
}
return new TypeInfo(xmlType, false, null);
}
}
private void introspect(Class javaType, Map<String, List<Type>> xsdTypesMap, Map<String, List<Type>> typesMap) {
Type type = typeHelper.getType(javaType);
if (type == null) {
return;
}
if (xsdHelper.isXSD(type)) {
addToMap(xsdTypesMap, type);
} else {
addToMap(typesMap, type);
}
}
private void addToMap(Map<String, List<Type>> map, Type type) {
List<Type> types = map.get(type.getURI());
if (types == null) {
types = new ArrayList<Type>();
map.put(type.getURI(), types);
}
if (!types.contains(type)) {
types.add(type);
}
}
/*
public List<XSDefinition> getSchemaDefinitions(XSDFactory factory, ModelResolver resolver) {
List<XSDefinition> definitions = new ArrayList<XSDefinition>();
generateSDOSchemas(definitions, factory, typesMap);
addResolvedXSDs(definitions, factory, resolver, xsdTypesMap);
return definitions;
}
*/
private void generateSDOSchemas(List<XSDefinition> definitions, XSDFactory factory, Map<String, List<Type>> map) {
for (Map.Entry<String, List<Type>> entry : map.entrySet()) {
List<Type> types = entry.getValue();
String ns = entry.getKey();
generateSchema(definitions, factory, types, ns);
}
}
private void generateSchema(List<XSDefinition> definitions, XSDFactory factory, List<Type> types, String ns) {
String schema = xsdHelper.generate(types);
DOMImplementationRegistry registry = null;
try {
registry = DOMImplementationRegistry.newInstance();
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
DOMImplementation impl = registry.getDOMImplementation("XML 3.0");
DOMImplementationLS ls = (DOMImplementationLS)impl.getFeature("LS", "3.0");
LSParser parser = ls.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, SCHEMA_NS);
LSInput input = ls.createLSInput();
input.setCharacterStream(new StringReader(schema));
Document document = parser.parse(input);
XSDefinition definition = factory.createXSDefinition();
definition.setUnresolved(true);
definition.setDocument(document);
definition.setNamespace(ns);
definitions.add(definition);
}
private void addResolvedXSDs(List<XSDefinition> definitions,
XSDFactory factory,
ModelResolver resolver,
Map<String, List<Type>> map) {
for (Map.Entry<String, List<Type>> entry : map.entrySet()) {
XSDefinition definition = factory.createXSDefinition();
definition.setUnresolved(true);
definition.setNamespace(entry.getKey());
//FIXME: set location URI
XSDefinition resolved = resolver.resolveModel(XSDefinition.class, definition);
if (resolved.getSchema() == null) {
//FIXME: create a checked exception and propagate it back up to the activator
throw new RuntimeException("No XSD found for namespace " + entry.getKey());
}
// make sure all the required types are defined in the resolved schema
for (Type type : entry.getValue()) {
String name = xsdHelper.getLocalName(type);
QName typeName = null;
if (name.endsWith("_._type")) {
// FIXME: Anonymous tyype
name = name.substring(0, name.length() - "_._type".length());
typeName = new QName(type.getURI(), name);
if (resolved.getXmlSchemaElement(typeName) == null) {
//FIXME: create a checked exception and propagate it back up to the activator
throw new RuntimeException("No XSD found for " + typeName.toString());
}
} else {
typeName = new QName(type.getURI(), name);
if (resolved.getXmlSchemaType(typeName) == null) {
//FIXME: create a checked exception and propagate it back up to the activator
throw new RuntimeException("No XSD found for " + typeName.toString());
}
}
}
definitions.add(resolved);
}
}
private static List<DataType> getDataTypes(Interface intf) {
List<DataType> dataTypes = new ArrayList<DataType>();
for (Operation op : intf.getOperations()) {
WrapperInfo inputWrapperInfo = op.getInputWrapper();
WrapperInfo outputWrapperInfo = op.getOutputWrapper();
if (inputWrapperInfo != null && outputWrapperInfo != null) {
DataType dt1 = inputWrapperInfo.getWrapperType();
if (dt1 != null) {
dataTypes.add(dt1);
}
DataType dt2 = outputWrapperInfo.getWrapperType();
if (dt2 != null) {
dataTypes.add(dt2);
}
} else {
for (DataType dt1 : op.getInputType().getLogical()) {
dataTypes.add(dt1);
}
DataType dt2 = op.getOutputType();
if (dt2 != null) {
dataTypes.add(dt2);
}
for (DataType<DataType> dt3 : op.getFaultTypes()) {
DataType dt4 = dt3.getLogical();
if (dt4 != null) {
dataTypes.add(dt4);
}
}
}
}
return dataTypes;
}
public List<XSDefinition> getSchemaDefinitions(XSDFactory factory, ModelResolver resolver, Interface intf) {
return getSchemaDefinitions(factory, resolver, getDataTypes(intf));
}
public List<XSDefinition> getSchemaDefinitions(XSDFactory factory, ModelResolver resolver, List<DataType> dataTypes) {
Map<String, List<Type>> xsdTypesMap = new HashMap<String, List<Type>>();
Map<String, List<Type>> typesMap = new HashMap<String, List<Type>>();
for (DataType d : dataTypes) {
if (SDODataBinding.NAME.equals(d.getDataBinding())) {
introspect(d.getPhysical(), xsdTypesMap, typesMap);
}
}
List<XSDefinition> definitions = new ArrayList<XSDefinition>();
generateSDOSchemas(definitions, factory, typesMap);
addResolvedXSDs(definitions, factory, resolver, xsdTypesMap);
return definitions;
}
}