/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.modelgenerator.wsdl.ui.wizards.soap; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.emf.common.util.EList; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.osgi.util.NLS; import org.eclipse.xsd.XSDAttributeUse; 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.XSDSchema; import org.eclipse.xsd.XSDSimpleTypeDefinition; import org.eclipse.xsd.XSDTypeDefinition; import org.eclipse.xsd.XSDWildcard; import org.eclipse.xsd.impl.XSDAttributeUseImpl; import org.eclipse.xsd.impl.XSDElementDeclarationImpl; import org.eclipse.xsd.impl.XSDParticleImpl; import org.eclipse.xsd.impl.XSDSimpleTypeDefinitionImpl; import org.teiid.core.designer.ModelerCoreException; import org.teiid.designer.core.types.DatatypeConstants.RuntimeTypeNames; import org.teiid.designer.modelgenerator.wsdl.ModelGeneratorWsdlPlugin; import org.teiid.designer.modelgenerator.wsdl.model.Model; import org.teiid.designer.modelgenerator.wsdl.model.ModelGenerationException; import org.teiid.designer.modelgenerator.wsdl.model.Operation; import org.teiid.designer.modelgenerator.wsdl.model.Part; import org.teiid.designer.modelgenerator.wsdl.model.impl.ModelImpl; import org.teiid.designer.modelgenerator.wsdl.schema.extensions.SOAPSchemaProcessor; import org.teiid.designer.modelgenerator.wsdl.ui.Messages; import org.teiid.designer.modelgenerator.wsdl.ui.ModelGeneratorWsdlUiConstants; import org.teiid.designer.modelgenerator.wsdl.ui.wizards.WSDLImportWizardManager; import org.teiid.designer.modelgenerator.wsdl.ui.wizards.soap.SchemaTreeModel.SchemaNode; import org.teiid.designer.query.proc.wsdl.IWsdlConstants.ProcedureType; import org.teiid.designer.query.sql.ISQLConstants; import org.teiid.designer.schema.tools.model.schema.SchemaModel; import org.teiid.designer.schema.tools.model.schema.SchemaObject; import org.teiid.designer.schema.tools.model.schema.impl.BaseSchemaObject; import org.teiid.designer.schema.tools.processing.SchemaProcessingException; import org.teiid.designer.schema.tools.processing.SchemaProcessor; import org.teiid.designer.ui.viewsupport.DatatypeUtilities; import org.teiid.designer.ui.viewsupport.ModelUtilities; /** * @since 8.0 */ public class ImportWsdlSchemaHandler { private static final String WSDL_SCHEMA_HANDLER_RECURSIVE_DEPTH_PROPERTY = "WsdlSchemaHandlerRecursiveDepth"; //$NON-NLS-1$ private static int MAX_DEPTH = 750; private WSDLImportWizardManager importManager; private OperationsDetailsPage operationsDetailsPage; private SchemaTreeModel requestSchemaTreeModel = null; private SchemaTreeModel responseSchemaTreeModel = null; private SchemaNode rootnode = null; private SchemaModel schemaModel; private int depth = 0; static { try { String value = System .getProperty(WSDL_SCHEMA_HANDLER_RECURSIVE_DEPTH_PROPERTY); if (value != null) { MAX_DEPTH = Integer.parseInt(value); } } catch (Exception ex) { // Revert to the default but log the exception ModelGeneratorWsdlPlugin.Util.log(ex); } } boolean circularSchemaWarningTriggered = false; public ImportWsdlSchemaHandler(WSDLImportWizardManager manager, OperationsDetailsPage operationsDetailsPage) { super(); this.importManager = manager; this.operationsDetailsPage = operationsDetailsPage; } public List<SchemaNode> getSchemaForSelectedOperation(ProcedureType type, ProcedureGenerator generator) { Model wsdlModel = null; Object elementDeclaration = null; if (ProcedureType.REQUEST.equals(type)) { this.requestSchemaTreeModel = new SchemaTreeModel(); }else{ this.responseSchemaTreeModel = new SchemaTreeModel(); } try { wsdlModel = importManager.getWSDLModel(); } catch (ModelGenerationException e) { throw new RuntimeException(e); } XSDSchema[] schemas = wsdlModel.getSchemas(); Operation selectedOperation = generator.getOperation(); String partElementName = null; Part[] partArray = null; if (ProcedureType.REQUEST.equals(type)) { if (selectedOperation.getInputMessage() != null) { partArray = selectedOperation.getInputMessage().getParts(); } } else { if (selectedOperation.getOutputMessage() != null) { partArray = selectedOperation.getOutputMessage().getParts(); } } List<Object> elementArrayList = new ArrayList<Object>(); if(partArray!=null) { for (Part part : partArray) { partElementName = getPartElementName(part); String namespace = part.getElementNamespace(); if (ProcedureType.REQUEST.equals(type)) { this.requestSchemaTreeModel.setNamespace(namespace); }else{ this.responseSchemaTreeModel.setNamespace(namespace); } boolean foundElement = false; for (XSDSchema schema : schemas) { EList<XSDElementDeclaration> elements = schema .getElementDeclarations(); for (XSDElementDeclaration element : elements) { String elementName = element.getName(); if (elementName.equals(partElementName)) { if (element.getTypeDefinition() instanceof XSDSimpleTypeDefinition) { elementDeclaration = element; } else { elementDeclaration = element .getTypeDefinition(); } foundElement = true; try { if (ProcedureType.REQUEST.equals(type)) { this.requestSchemaTreeModel = describe(schema, elementName, element, requestSchemaTreeModel); } else { this.responseSchemaTreeModel = describe(schema, elementName, element, responseSchemaTreeModel); } } catch (ModelerCoreException ex) { openErrorDialog(ex.getMessage()); } catch (StackOverflowError e) { /* * Can occur if the depth threshold is set too high. * Current value should be fine for most systems but * just in case... * * Eclipse will show a nasty dialog and offer to * close the workbench which is confusing better to * exit a little more gracefully. */ String message = NLS .bind(Messages.Error_GeneratingSchemaModelCircularReferenceStackOverflow, MAX_DEPTH, WSDL_SCHEMA_HANDLER_RECURSIVE_DEPTH_PROPERTY); openErrorDialog(message); System.exit(1); } elementArrayList.add(elementDeclaration); break; } } if (foundElement == true) break; if (elementDeclaration == null) { EList<XSDTypeDefinition> types = schema.getTypeDefinitions(); for (XSDTypeDefinition xsdType : types) { String elementName = xsdType.getName(); if (elementName.equals(partElementName)) { elementDeclaration = xsdType; foundElement = true; try { if (ProcedureType.REQUEST.equals(type)){ this.requestSchemaTreeModel = describe(schema, elementName, null, requestSchemaTreeModel); }else{ this.responseSchemaTreeModel = describe(schema, elementName, null, responseSchemaTreeModel); } } catch (ModelerCoreException ex) { ErrorDialog.openError(this.operationsDetailsPage.getShell(), Messages.Error_GeneratingSchemaModelDueToCircularReferences_title, null, new Status(IStatus.WARNING, ModelGeneratorWsdlUiConstants.PLUGIN_ID, Messages.Error_GeneratingSchemaModelDueToCircularReferences)); } elementArrayList.add(elementDeclaration); break; } } } // We already found our element. No need to look through anymore // schemas if (foundElement) { foundElement = false; break; } } } } Collection<SchemaNode> nodeList = new ArrayList<SchemaNode>(); if (ProcedureType.REQUEST.equals(type)){ nodeList = this.requestSchemaTreeModel.getNodeList(); }else{ nodeList = this.responseSchemaTreeModel.getNodeList(); } List<SchemaNode> elementsArray = new ArrayList<SchemaNode>(); for (SchemaNode node : nodeList) { if (node.isRoot()){ elementsArray.add(node); } } return elementsArray; } private void openErrorDialog(String msg) { ErrorDialog .openError( operationsDetailsPage.getShell(), Messages.Error_GeneratingSchemaModelDueToCircularReferences_title, null, new Status(IStatus.WARNING, ModelGeneratorWsdlUiConstants.PLUGIN_ID, msg)); } private String getPartElementName(Part part) { String partElementName = null; partElementName = part.getTypeName(); if (partElementName == null) { partElementName = part.getElementName(); } return partElementName; } public SchemaTreeModel getResponseSchemaTreeModel() { return responseSchemaTreeModel; } public String createRequestColumn(int type, IStructuredSelection selection, ProcedureInfo requestInfo) { SchemaNode node = (SchemaNode)selection.getFirstElement(); Object obj = node.getElement(); requestInfo.setTreeModel(this.requestSchemaTreeModel); if (this.requestSchemaTreeModel.getNamespace()!=null){ try { requestInfo.addNamespace((String)((ModelImpl)importManager.getWSDLModel()).getNamespaces().get(this.requestSchemaTreeModel.getNamespace()), this.requestSchemaTreeModel.getNamespace()); } catch (ModelGenerationException ex) { throw new RuntimeException(ex); } } String name = null; String ns = null; if (obj instanceof XSDParticleImpl && ((XSDParticleImpl) obj).getContent() instanceof XSDElementDeclarationImpl) { name = ((XSDElementDeclarationImpl) ((XSDParticleImpl) obj) .getContent()).getName(); if (name==null){ name = ((XSDElementDeclarationImpl) ((XSDParticleImpl) obj) .getContent()).getResolvedElementDeclaration().getName(); } ns = ((XSDElementDeclarationImpl) ((XSDParticleImpl) obj) .getContent()).getTargetNamespace(); try { if (ns!=null)requestInfo.addNamespace((String)((ModelImpl)importManager.getWSDLModel()).getReverseNamespaces().get(ns), ns); } catch (ModelGenerationException ex) { throw new RuntimeException(ex.getMessage()); } if (type == ProcedureInfo.TYPE_BODY) { requestInfo.addBodyColumn( requestInfo.getUniqueBodyColumnName(name), false, RuntimeTypeNames.STRING, null, null, ns); } else { requestInfo.addHeaderColumn( requestInfo.getUniqueHeaderColumnName(name), false, RuntimeTypeNames.STRING, null, null, ns); } operationsDetailsPage.notifyColumnDataChanged(); return null; } else if (obj instanceof XSDElementDeclarationImpl) { name = ((XSDElementDeclarationImpl) obj).getName(); ns = ((XSDElementDeclarationImpl) obj).getTargetNamespace(); if (type == ProcedureInfo.TYPE_BODY) { requestInfo.addBodyColumn( requestInfo.getUniqueBodyColumnName(name), false, RuntimeTypeNames.STRING, null, null, ns); } else { requestInfo.addHeaderColumn( requestInfo.getUniqueHeaderColumnName(name), false, RuntimeTypeNames.STRING, null, null, ns); } operationsDetailsPage.notifyColumnDataChanged(); return null; }else if (obj instanceof XSDAttributeUseImpl) { XSDAttributeUseImpl attributeImpl = (XSDAttributeUseImpl)obj; name = attributeImpl.getAttributeDeclaration().getName(); if( name == null ) { name = attributeImpl.getAttributeDeclaration().getAliasName(); } ns = attributeImpl.getAttributeDeclaration().getTargetNamespace(); ColumnInfo columnInfo = getColumnInfoForAttribute(type, requestInfo, attributeImpl, node); columnInfo.addAttributeInfo(columnInfo.getXmlElement(), columnInfo.getUniqueAttributeName(name)); operationsDetailsPage.notifyColumnDataChanged(); return null; } return operationsDetailsPage.getSchemaLabelProvider().getText(obj); } private ColumnInfo getColumnInfoForAttribute(int type, ProcedureInfo requestInfo, XSDAttributeUse attributeUse, SchemaNode parentNode) { SchemaNode parentSchemaNode = getParentElement( parentNode); if( parentSchemaNode != null ) { Object parentElement = parentSchemaNode.getElement(); // See if columnInfo already exists for( ColumnInfo info : requestInfo.getBodyColumnInfoList() ) { if( parentElement == info.getXmlElement() ) { return info; } } String name = null; String ns = null; ColumnInfo newInfo = null; if (parentElement instanceof XSDParticleImpl && ((XSDParticleImpl) parentElement).getContent() instanceof XSDElementDeclarationImpl) { name = ((XSDElementDeclarationImpl) ((XSDParticleImpl) parentElement) .getContent()).getName(); if (name==null){ name = ((XSDElementDeclarationImpl) ((XSDParticleImpl) parentElement) .getContent()).getResolvedElementDeclaration().getName(); } ns = ((XSDElementDeclarationImpl) ((XSDParticleImpl) parentElement) .getContent()).getTargetNamespace(); if (type == ProcedureInfo.TYPE_BODY) { newInfo = requestInfo.addBodyColumn( requestInfo.getUniqueBodyColumnName(name), false, RuntimeTypeNames.STRING, null, null, ns); newInfo.setXmlElement(parentElement); } else { newInfo = requestInfo.addHeaderColumn( requestInfo.getUniqueHeaderColumnName(name), false, RuntimeTypeNames.STRING, null, null, ns); newInfo.setXmlElement(parentElement); } operationsDetailsPage.notifyColumnDataChanged(); } else if (parentElement instanceof XSDElementDeclarationImpl) { name = ((XSDElementDeclarationImpl) parentElement).getName(); ns = ((XSDElementDeclarationImpl) parentElement).getTargetNamespace(); if (type == ProcedureInfo.TYPE_BODY) { newInfo = requestInfo.addBodyColumn( requestInfo.getUniqueBodyColumnName(name), false, RuntimeTypeNames.STRING, null, null, ns); newInfo.setXmlElement(parentElement); } else { newInfo = requestInfo.addHeaderColumn( requestInfo.getUniqueHeaderColumnName(name), false, RuntimeTypeNames.STRING, null, null, ns); newInfo.setXmlElement(parentElement); } operationsDetailsPage.notifyColumnDataChanged(); } return newInfo; } return null; } public static boolean shouldCreateRequestColumn(Object obj) { if (obj instanceof XSDParticleImpl ) { Object content = ((XSDParticleImpl) obj).getContent(); if( content instanceof XSDElementDeclarationImpl ) { return ! (((XSDElementDeclaration )content).getType() instanceof XSDComplexTypeDefinition); } else if( content instanceof XSDModelGroup ) { return false; } else { return true; } } else if (obj instanceof XSDElementDeclarationImpl ) { Object type = ((XSDElementDeclarationImpl) obj).getTypeDefinition(); if( type instanceof XSDSimpleTypeDefinitionImpl ) { return true; } } else if( obj instanceof XSDAttributeUseImpl ) { return true; } return false; } public static boolean shouldCreateResponseColumn(Object obj) { if (obj instanceof XSDParticleImpl ) { Object content = ((XSDParticleImpl) obj).getContent(); if( content instanceof XSDElementDeclarationImpl ) { return ! (((XSDElementDeclaration )content).getType() instanceof XSDComplexTypeDefinition); } else if( content instanceof XSDModelGroup ) { return false; } else { return true; } } else if (obj instanceof XSDElementDeclarationImpl ) { Object type = ((XSDElementDeclarationImpl) obj).getTypeDefinition(); if( type instanceof XSDSimpleTypeDefinitionImpl ) { return true; } } else if( obj instanceof XSDAttributeUseImpl ) { return true; } return false; } public String createResponseColumn(int type, IStructuredSelection selection, ProcedureInfo responseInfo) { SchemaNode node = (SchemaNode)selection.getFirstElement(); if( node == null ) return null; Object obj = node.getElement(); responseInfo.setTreeModel(this.responseSchemaTreeModel); if( !shouldCreateResponseColumn(obj) ) { return operationsDetailsPage.getSchemaLabelProvider().getText(obj); } if (obj instanceof XSDParticleImpl && ((XSDParticleImpl) obj).getContent() instanceof XSDElementDeclarationImpl) { Model wsdlModel = null; XSDSchema[] schemas; try { wsdlModel = operationsDetailsPage.getImportManager().getWSDLModel(); } catch (ModelGenerationException e) { throw new RuntimeException(e); } SchemaProcessor processor = new SOAPSchemaProcessor(null); processor.representTypes(true); processor.setNamespaces(wsdlModel.getNamespaces()); schemas = wsdlModel.getSchemas(); try { processor.processSchemas(schemas); } catch (SchemaProcessingException e) { throw new RuntimeException(e); } schemaModel = processor.getSchemaModel(); List<SchemaObject> elements = schemaModel.getElements(); XSDElementDeclaration element = (XSDElementDeclaration)((XSDParticleImpl) obj).getContent(); XSDTypeDefinition typeDefinition = element.getType(); String name = ((XSDElementDeclarationImpl) ((XSDParticleImpl) obj).getContent()).getName(); if (name==null){ name = ((XSDElementDeclarationImpl) ((XSDParticleImpl) obj).getContent()).getResolvedElementDeclaration().getName(); } StringBuilder xpath = new StringBuilder(); String namespace = null; String prefix = null; StringBuilder parentXpath = new StringBuilder(); if (importManager.isMessageServiceMode()) { responseInfo.addNamespace(ISQLConstants.ENVELOPE_NS_ALIAS, ISQLConstants.ENVELOPE_NS); } // Add the namespace from schema tree model (if present). We need to do this in case there is a namespace used for the message, // but not a selected element. if (this.responseSchemaTreeModel.getNamespace()!=null) { responseInfo.addNamespace((String)((ModelImpl)wsdlModel).getReverseNamespaces().get(this.responseSchemaTreeModel.getNamespace()), this.responseSchemaTreeModel.getNamespace()); } getParentXpath(node, parentXpath, this.responseSchemaTreeModel); for (SchemaObject schemaObject : elements) { if (schemaObject.getName().equals(name)) { namespace = schemaObject.getNamespace(); prefix = ((BaseSchemaObject) schemaObject) .getNamespacePrefix(); if (namespace != null) { responseInfo.addNamespace(prefix, namespace); } // TODO: Make sure Root Path is set in the // responseElementsInfoPanel on Refresh // operationsDetailsPage.responseElementsInfoPanel.getRootPathText().setText(parentXpath.toString()); break; } } //Set namespace map on schemaTreeModel. This will be used for determining ns alias names to use for the root path and column paths this.responseSchemaTreeModel.setNamespaceMap(responseInfo.getNamespaceMap()); if (this.responseSchemaTreeModel.getRootPath()==null || this.responseSchemaTreeModel.getRootPath().isEmpty()){ this.responseSchemaTreeModel.setRootPath(this.responseSchemaTreeModel.determineRootPath()); } if (importManager.isMessageServiceMode()) { operationsDetailsPage.responseBodyColumnsInfoPanel.getRootPathText().setText(ResponseInfo.SOAPENVELOPE_ROOTPATH); } else { operationsDetailsPage.responseBodyColumnsInfoPanel.getRootPathText().setText(this.responseSchemaTreeModel.getRootPath()); } responseInfo.setRootPath(this.responseSchemaTreeModel.getRootPath()); getRelativeXpath(node, xpath, this.responseSchemaTreeModel); if (type == ProcedureInfo.TYPE_BODY) { String pathPrefix = ""; //$NON-NLS-1$ if (importManager.isMessageServiceMode()) { pathPrefix = ResponseInfo.SOAPBODY_ROOTPATH; //Need to fully qualify xpath at the column level for BODY in MESSAGE mode String root = this.responseSchemaTreeModel.getRootPath().replaceAll(ResponseInfo.SOAPENVELOPE_ROOTPATH, ""); //$NON-NLS-1$ xpath = new StringBuilder(root).append(xpath); } String theType = RuntimeTypeNames.STRING; if( typeDefinition != null && typeDefinition.getName() != null ) { theType = typeDefinition.getName(); } String runtimeTypeName = theType; try { runtimeTypeName = DatatypeUtilities.getRuntimeTypeName(theType); } catch (ModelerCoreException ex) { ex.printStackTrace(); } if( runtimeTypeName != null && !runtimeTypeName.equalsIgnoreCase(theType) ) { theType = runtimeTypeName; } responseInfo.addBodyColumn( responseInfo.getUniqueBodyColumnName(name), false, theType, null, pathPrefix + xpath.toString(), null); } else { String pathPrefix = ""; //$NON-NLS-1$ if (importManager.isMessageServiceMode()) { pathPrefix = ResponseInfo.SOAPHEADER_ROOTPATH; } responseInfo.addHeaderColumn( responseInfo.getUniqueHeaderColumnName(name), false, RuntimeTypeNames.STRING, null, pathPrefix + xpath.toString(), null); } operationsDetailsPage.notifyColumnDataChanged(); return null; } else if( obj instanceof XSDAttributeUseImpl ) { Model wsdlModel = null; SchemaModel schemaModel; XSDSchema[] schemas; try { wsdlModel = operationsDetailsPage.getImportManager().getWSDLModel(); } catch (ModelGenerationException e) { throw new RuntimeException(e); } //Add the namespace. String prefix = null; try { prefix = this.importManager.getWSDLModel().getNamespaces().get(this.operationsDetailsPage.getProcedureGenerator().getNamespaceURI()); } catch (ModelGenerationException ex) { throw new RuntimeException(ex); } responseInfo.addNamespace(prefix!=null&&prefix.length()>0?prefix:ResponseInfo.DEFAULT_NS, this.operationsDetailsPage.getProcedureGenerator().getNamespaceURI()); SchemaProcessor processor = new SOAPSchemaProcessor(null); processor.representTypes(true); processor.setNamespaces(wsdlModel.getNamespaces()); schemas = wsdlModel.getSchemas(); try { processor.processSchemas(schemas); } catch (SchemaProcessingException e) { throw new RuntimeException(e); } schemaModel = processor.getSchemaModel(); List<SchemaObject> elements = schemaModel.getElements(); XSDAttributeUse attributeUse = (XSDAttributeUse) obj; String name = attributeUse.getAttributeDeclaration().getName(); if( name == null ) { name = attributeUse.getAttributeDeclaration().getAliasName(); } String parentElementName = null; SchemaNode parentSchemaNode = getParentElement(node); if( parentSchemaNode != null ) { Object parentElement = parentSchemaNode.getElement(); if (parentElement instanceof XSDParticleImpl && ((XSDParticleImpl) parentElement).getContent() instanceof XSDElementDeclarationImpl) { XSDElementDeclaration content = (XSDElementDeclaration)((XSDParticleImpl) parentElement).getContent(); parentElementName = content.getName(); if (parentElementName==null){ parentElementName = ((XSDElementDeclarationImpl) ((XSDParticleImpl) parentElement).getContent()).getResolvedElementDeclaration().getName(); } } } String dTypeString = attributeUse.getAttributeDeclaration().getType().getAliasName(); String runtimeTypeName = dTypeString; try { runtimeTypeName = DatatypeUtilities.getRuntimeTypeName(dTypeString); } catch (ModelerCoreException ex) { ex.printStackTrace(); } if( runtimeTypeName != null && !runtimeTypeName.equalsIgnoreCase(dTypeString) ) { dTypeString = runtimeTypeName; } StringBuilder xpath = new StringBuilder(); String namespace = null; prefix = null; StringBuilder parentXpath = new StringBuilder(); getParentXpath(node, parentXpath, this.responseSchemaTreeModel); if (this.responseSchemaTreeModel.getRootPath()==null || this.responseSchemaTreeModel.getRootPath().isEmpty()){ this.responseSchemaTreeModel.setRootPath(this.responseSchemaTreeModel.determineRootPath()); } getRelativeXpath(node, xpath,this.responseSchemaTreeModel); xpath.append('/').append('@').append(name); if( parentElementName != null ) { for (SchemaObject schemaObject : elements) { if (schemaObject.getName().equals(parentElementName)) { namespace = schemaObject.getNamespace(); prefix = ((BaseSchemaObject) schemaObject) .getNamespacePrefix(); if (namespace != null) { responseInfo.addNamespace(prefix, namespace); } responseInfo.setRootPath(this.responseSchemaTreeModel.getRootPath()); if (importManager.isMessageServiceMode()) { operationsDetailsPage.responseBodyColumnsInfoPanel.getRootPathText().setText(ResponseInfo.SOAPENVELOPE_ROOTPATH); } else { operationsDetailsPage.responseBodyColumnsInfoPanel.getRootPathText().setText(this.responseSchemaTreeModel.getRootPath()); } // TODO: Make sure Root Path is set in the // responseElementsInfoPanel on Refresh // operationsDetailsPage.responseElementsInfoPanel.getRootPathText().setText(parentXpath.toString()); } } } if (type == ProcedureInfo.TYPE_BODY) { String pathPrefix = ""; //$NON-NLS-1$ if (importManager.isMessageServiceMode()) { pathPrefix = ResponseInfo.SOAPBODY_ROOTPATH; //Need to fully qualify xpath at the column level for BODY in MESSAGE mode String root = this.responseSchemaTreeModel.getRootPath().replaceAll(ResponseInfo.SOAPENVELOPE_ROOTPATH, ""); //$NON-NLS-1$ xpath = new StringBuilder(root).append(xpath); } responseInfo.addBodyColumn( responseInfo.getUniqueBodyColumnName(name), false, dTypeString, null, pathPrefix + xpath.toString(), null); } else { String pathPrefix = ""; //$NON-NLS-1$ if (importManager.isMessageServiceMode()) { pathPrefix = ResponseInfo.SOAPHEADER_ROOTPATH; } responseInfo.addHeaderColumn( responseInfo.getUniqueHeaderColumnName(name), false, RuntimeTypeNames.STRING, null, pathPrefix + xpath.toString(), null); } operationsDetailsPage.notifyColumnDataChanged(); return null; } return operationsDetailsPage.getSchemaLabelProvider().getText(obj); } public static String getBaseTypeString(XSDAttributeUse attribute) { XSDTypeDefinition typeDef = attribute.getAttributeDeclaration().getType().getBaseType(); while( typeDef.getBaseType() != null && !typeDef.equals(typeDef.getBaseType()) && !typeDef.getBaseType().getName().startsWith("any")) { //$NON-NLS-1$ typeDef = typeDef.getBaseType(); } return typeDef.getName(); } // ================================================= //Traverse Element to build parent-child relationships used //to determine XPath private SchemaTreeModel describe(XSDSchema schema, String element, XSDElementDeclaration elementDeclaration, SchemaTreeModel schemaTreeModel) throws ModelerCoreException { circularSchemaWarningTriggered = false; rootnode = schemaTreeModel.new SchemaNode(); depth = 0; XSDElementDeclaration xed = (elementDeclaration == null ? schema.resolveElementDeclaration(element) : elementDeclaration); XSDTypeDefinition xtd = xed.getTypeDefinition(); if (xtd instanceof XSDComplexTypeDefinition) { rootnode.setElement(xed); rootnode.setRoot(true); XSDComplexTypeDefinition complexType = (XSDComplexTypeDefinition) xtd; addComplexTypeDefToTree(complexType, rootnode, true, depth++, schemaTreeModel); } else if (xtd instanceof XSDSimpleTypeDefinition) { rootnode.setElement(xed); rootnode.setRoot(true); addAttributes(xtd, rootnode, schemaTreeModel); XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition) xtd; addSimpleTypeDefToTree(simpleType, rootnode, schemaTreeModel); } else { XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition) xed .getType(); addElementDeclarationToTree(xed, simpleType, rootnode, schemaTreeModel); } return schemaTreeModel; } private void addElementDeclarationToTree(XSDElementDeclaration element, XSDSimpleTypeDefinition type, SchemaNode node, SchemaTreeModel schemaTreeModel) throws ModelerCoreException { String name = element.getName(); if (null == name) { name = element.getAliasName(); } addToSchemaMap(node, schemaTreeModel); } private void addComplexTypeDefToTree(XSDComplexTypeDefinition complexType, SchemaNode node, boolean isRootNode, int depth, SchemaTreeModel schemaTreeModel) throws ModelerCoreException { if (depth > MAX_DEPTH) { String message = NLS .bind(Messages.Error_GeneratingSchemaModelDueToCircularReferences, MAX_DEPTH, WSDL_SCHEMA_HANDLER_RECURSIVE_DEPTH_PROPERTY); throw new ModelerCoreException(message); } XSDComplexTypeContent content = complexType.getContent(); addToSchemaMap(node, schemaTreeModel); addAttributes(complexType, node, schemaTreeModel); if (content instanceof XSDSimpleTypeDefinition) { XSDSimpleTypeDefinition simpleType = (XSDSimpleTypeDefinition) content; addSimpleTypeDefToTree(simpleType, node, schemaTreeModel); } else if (content instanceof XSDParticle) { XSDParticle particle = (XSDParticle) content; addXSDParticleToTree(particle, node, null, depth++, schemaTreeModel); } } private void addXSDParticleToTree(XSDParticle particle, SchemaNode parent, SchemaNode node, int depth, SchemaTreeModel schemaTreeModel ) 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(); node = schemaTreeModel.new SchemaNode(content, parent, null, false); if (parent!=null){ parent.addChild(node); } addToSchemaMap(node, schemaTreeModel); parent=node; for (XSDParticle xsdParticle : contents) { addXSDParticleToTree(xsdParticle, parent, node, depth++, schemaTreeModel); } } else if (content instanceof XSDElementDeclaration) { XSDElementDeclaration element = (XSDElementDeclaration) content; node = schemaTreeModel.new SchemaNode(particle, parent, null, false); if (parent!=null){ parent.addChild(node); } addToSchemaMap(node, schemaTreeModel); addAttributes(element, node, schemaTreeModel); if (element.isElementDeclarationReference()) { element = element.getResolvedElementDeclaration(); } if (element.getType() instanceof XSDSimpleTypeDefinition) { XSDSimpleTypeDefinition type = (XSDSimpleTypeDefinition) element.getType(); addElementDeclarationToTree(element, type, node, schemaTreeModel); } else { XSDComplexTypeDefinition type = (XSDComplexTypeDefinition) element.getType(); String name = element.getName(); if (null == name) { name = element.getAliasName(); } addComplexTypeDefToTree(type, node, false, depth, schemaTreeModel); } } else if (content instanceof XSDModelGroupDefinition) { XSDModelGroupDefinition groupDefinition = (XSDModelGroupDefinition) content; XSDModelGroup group = groupDefinition.getModelGroup(); EList<XSDParticle> contents = group.getContents(); for (XSDParticle xsdParticle : contents) { addXSDParticleToTree(xsdParticle, node, null, depth, schemaTreeModel); } } } private void addAttributes(Object element, SchemaNode parent, SchemaTreeModel schemaTreeModel) { Object[] result = new Object[0]; if( element instanceof XSDComplexTypeDefinition ) { result = ((XSDComplexTypeDefinition)element).getAttributeUses().toArray(); } else { result = ModelUtilities.getModelContentProvider().getChildren(element); } for( Object obj : result) { if( obj instanceof XSDAttributeUse ) { SchemaNode node = schemaTreeModel.new SchemaNode(obj, parent, null, false); if (parent!=null){ parent.addChild(node); } addToSchemaMap(node, schemaTreeModel); } } } private void addToSchemaMap(SchemaNode node, SchemaTreeModel schemaTreeModel) { schemaTreeModel.getNodeList().add(node); } private void addSimpleTypeDefToTree(XSDSimpleTypeDefinition simpleType, SchemaNode node, SchemaTreeModel schemaTreeModel) throws ModelerCoreException { addToSchemaMap(node, schemaTreeModel); } private void getParentXpath(SchemaNode node, StringBuilder parentXpath, SchemaTreeModel schemaTreeModel) { String rootPath = schemaTreeModel.getRootNodeXpath(); String parentXPath = node == null ? "" : node.getParentXpath(); //$NON-NLS-1$ parentXpath.append(rootPath).append(parentXPath); } private SchemaNode getParentElement(SchemaNode node) { if( node != null ) { return node.getParent(); } return null; } private void getRelativeXpath(SchemaNode node, StringBuilder xpath, SchemaTreeModel schemaTreeModel) { String relativeXpath = node == null ? "" : node.getRelativeXpath(); //$NON-NLS-1$ //We need to append the full path and then remove the root path. //This allows us to resolve nested complex types String parentXPath = node == null ? "" : node.getParentXpath(); //$NON-NLS-1$ parentXPath = parentXPath.replace(schemaTreeModel.getRootPath(), ""); //$NON-NLS-1$ xpath.append(parentXPath).append(relativeXpath); } }