package org.teiid.designer.modelgenerator.xsd.procedures; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.xml.namespace.QName; import org.eclipse.emf.common.util.EList; import org.eclipse.xsd.XSDComplexTypeContent; import org.eclipse.xsd.XSDComplexTypeDefinition; import org.eclipse.xsd.XSDElementDeclaration; import org.eclipse.xsd.XSDModelGroup; import org.eclipse.xsd.XSDModelGroupDefinition; import org.eclipse.xsd.XSDParticle; import org.eclipse.xsd.XSDParticleContent; import org.eclipse.xsd.XSDSimpleTypeDefinition; import org.eclipse.xsd.XSDTypeDefinition; import org.eclipse.xsd.XSDWildcard; import org.teiid.core.designer.ModelerCoreException; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.core.designer.util.StringConstants; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.metamodels.relational.RelationalFactory; import org.teiid.designer.metamodels.relational.Schema; import org.teiid.designer.modelgenerator.xml.XmlImporterUiPlugin; import org.teiid.designer.schema.tools.model.schema.SchemaObject; import org.teiid.designer.schema.tools.model.schema.impl.ElementImpl; import org.teiid.designer.schema.tools.model.schema.impl.TypeDefinition; /** * @since 8.0 */ public class ProcedureBuilder { RelationalFactory factory = org.teiid.designer.metamodels.relational.RelationalPackage.eINSTANCE .getRelationalFactory(); private Set<String> procedures = new HashSet<String>(); private Schema operationSchema; private ITraversalCtxFactory traversalCtxFactory; private ModelResource modelResource; private List<TraversalContext> traversalContexts = new ArrayList(); public ProcedureBuilder(Schema schema, ModelResource resource) { operationSchema = schema; modelResource = resource; } public boolean procedureExists(String name) { return procedures.contains(name); } public boolean addProcedure(String name) { return procedures.add(name); } public void build(List<XSDElementDeclaration> elements, ITraversalCtxFactory traversalCtxFactory) throws ModelerCoreException { CoreArgCheck.isTrue(elements.size() == 1, XmlImporterUiPlugin.getDefault().getPluginUtil().getString("ProcedureBuilder.wrongNumberElementsReturnedFromXsd")); //$NON-NLS-1$ XSDElementDeclaration element = elements.get(0); this.traversalCtxFactory = traversalCtxFactory; TraversalContext ctx = this.traversalCtxFactory.getTraversalContext(element.getName(), new QName(element.getTargetNamespace(), StringConstants.EMPTY_STRING), this); traversalContexts.add(ctx); XSDTypeDefinition type = element.getType(); String name = getName(type); if (!procedureExists(name)) { addProcedure(name); if (type instanceof XSDComplexTypeDefinition) { ctx.appendToPath(element.getName()); XSDComplexTypeDefinition complexType = (XSDComplexTypeDefinition) type; addComplexTypeDefToProcedureResult(complexType, ctx); } else if (type instanceof XSDSimpleTypeDefinition) { XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition) element.getType(); addElementDeclarationToProcedureResult(element, simpleType, ctx); } } } public void build(SchemaObject sObject, ITraversalCtxFactory traversalCtxFactory) throws ModelerCoreException { this.traversalCtxFactory = traversalCtxFactory; TraversalContext ctx = this.traversalCtxFactory.getTraversalContext(sObject.getName(), new QName(sObject.getNamespace(), StringConstants.EMPTY_STRING), this); traversalContexts.add(ctx); XSDTypeDefinition type = sObject.getType(); String name = getName(type); if (!procedureExists(name)) { addProcedure(name); if (type instanceof XSDComplexTypeDefinition) { ctx.appendToPath(sObject.getName()); XSDComplexTypeDefinition complexType = (XSDComplexTypeDefinition) type; addComplexTypeDefToProcedureResult(complexType, ctx); } else if (type instanceof XSDSimpleTypeDefinition) { if(sObject instanceof TypeDefinition) { XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition) sObject.getType(); addSimpleTypeDefToProcedureResult(simpleType, ctx); } else { XSDElementDeclaration element = ((ElementImpl) sObject) .getElem(); XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition) element.getType(); addElementDeclarationToProcedureResult(element, simpleType, ctx); } } } } public void build(XSDSimpleTypeDefinition simpleType, String name, ITraversalCtxFactory traversalCtxFactory) throws ModelerCoreException { this.traversalCtxFactory = traversalCtxFactory; TraversalContext ctx = this.traversalCtxFactory.getTraversalContext(name, new QName(simpleType.getTargetNamespace(), simpleType.getName()), this); traversalContexts.add(ctx); addSimpleTypeDefToProcedureResult(simpleType, name, ctx); } public void createTransformations() { for (TraversalContext context : traversalContexts) { context.createTransformation(); } } private String getName(XSDTypeDefinition type) { String name = type.getName(); if(null == name) { name = type.getAliasName(); } return name; } private void addElementDeclarationToProcedureResult(XSDElementDeclaration element, XSDSimpleTypeDefinition type, TraversalContext ctx) throws ModelerCoreException { String name = element.getName(); if(null == name) { name = element.getAliasName(); } ctx.addColumn(name, type); } private void addComplexTypeDefToProcedureResult(XSDComplexTypeDefinition complexType, TraversalContext ctx) throws ModelerCoreException { XSDComplexTypeContent content = complexType.getContent(); if(content instanceof XSDSimpleTypeDefinition) { XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition) content; addSimpleTypeDefToProcedureResult(simpleType, ctx); } else if(content instanceof XSDParticle) { XSDParticle particle = (XSDParticle) content; addXSDParticleToProcedureResult(particle, ctx); } } private void addXSDParticleToProcedureResult(XSDParticle particle, TraversalContext ctx) throws ModelerCoreException { XSDParticleContent content = particle.getContent(); if(content instanceof XSDWildcard) { //nothing } else if (content instanceof XSDModelGroup) { XSDModelGroup group = (XSDModelGroup) content; EList<XSDParticle> contents = group.getContents(); for (XSDParticle xsdParticle : contents) { addXSDParticleToProcedureResult(xsdParticle, ctx); } } else if (content instanceof XSDElementDeclaration) { XSDElementDeclaration element = (XSDElementDeclaration) content; if(element.isElementDeclarationReference()) { element = element.getResolvedElementDeclaration(); } if(element.getType() instanceof XSDSimpleTypeDefinition) { XSDSimpleTypeDefinition type = (XSDSimpleTypeDefinition) element.getType(); addElementDeclarationToProcedureResult(element, type, ctx); } else { XSDComplexTypeDefinition type = (XSDComplexTypeDefinition) element.getType(); String name = element.getName(); if(null == name) { name = element.getAliasName(); } if(procedureExists(name)) { return; } ctx.appendToPath(name); if(particle.getMaxOccurs() > 1 || particle.getMaxOccurs() == -1 || ctx.isReachedResultNode()) { ctx = traversalCtxFactory.getTraversalContext(name, new QName(element.getTargetNamespace(), StringConstants.EMPTY_STRING), ctx, this); traversalContexts.add(ctx); if(procedureExists(getName(type))){ return; } } addComplexTypeDefToProcedureResult(type, ctx); } }else if (content instanceof XSDModelGroupDefinition) { XSDModelGroupDefinition groupDefinition = (XSDModelGroupDefinition) content; XSDModelGroup group = groupDefinition.getModelGroup(); EList<XSDParticle> contents = group.getContents(); for (XSDParticle xsdParticle : contents) { addXSDParticleToProcedureResult(xsdParticle, ctx); } } } private void addSimpleTypeDefToProcedureResult(XSDSimpleTypeDefinition simpleType, TraversalContext ctx) throws ModelerCoreException { String name = simpleType.getName(); if(null == name) { name = simpleType.getAliasName(); } ctx.addColumn(name, simpleType); ctx.setReachedResultNode(true); } private void addSimpleTypeDefToProcedureResult(XSDSimpleTypeDefinition simpleType, String name, TraversalContext ctx) throws ModelerCoreException { ctx.addColumn(name, simpleType); ctx.setReachedResultNode(true); } public Schema getSchema() { return operationSchema; } public ModelResource getModelResource() { return modelResource; } }