| /* |
| * 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; |
| } |
| |
| } |