/* * 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.HashMap; import java.util.List; import java.util.Map; import java.util.Stack; import org.eclipse.xsd.XSDElementDeclaration; import org.eclipse.xsd.XSDTypeDefinition; import org.eclipse.xsd.impl.XSDElementDeclarationImpl; import org.eclipse.xsd.impl.XSDModelGroupImpl; import org.eclipse.xsd.impl.XSDParticleImpl; import org.teiid.core.designer.util.StringConstants; import org.teiid.designer.modelgenerator.wsdl.model.Part; /** * @since 8.0 */ public class SchemaTreeModel { Collection<SchemaNode> nodeList = new ArrayList<SchemaNode>(); String namespace = null; String rootPath = null; public static Map<String, String> namespaceMap = new HashMap<String, String>(); public Part[] partArray = null; public Map<String, String> getNamespaceMap() { return namespaceMap; } public String getNamespace() { return namespace; } public void setNamespace(String namespace) { this.namespace = namespace; } public Part[] getPartArray() { return partArray; } public void setPartArray(Part[] partArray) { this.partArray = partArray; } public void setNamespaceMap(Map<String, String> namespaceMap) { SchemaTreeModel.namespaceMap = namespaceMap; } public String getRootPath() { return this.rootPath; } public void setRootPath(String rootPath) { this.rootPath = rootPath; } public Collection<SchemaNode> getNodeList() { return this.nodeList; } public void setNodeList(Collection<SchemaNode> nodeList) { this.nodeList = nodeList; } public String getRootNodeXpath() { for (SchemaNode node:this.nodeList){ if (node.isRoot){ return node.getRelativeXpath(); } } return ""; //$NON-NLS-1$ } public String determineRootPath(){ StringBuilder commonRoot = new StringBuilder(); List<String> segmentList = new ArrayList(); for (SchemaNode node:this.nodeList){ if (node.children.isEmpty()){ String path = node.getFullPathMinusLastSegment(); if (!path.equals("")){ //$NON-NLS-1$ segmentList.add(path); } } } //We parse paths to get all segments. We need to find the shortest //path up front, since we cannot have a common root greater than //the shortest path. String[][] segments = new String[segmentList.size()][]; int shortestPathLength = 0; for(int i = 0; i < segmentList.size(); i++){ segments[i] = segmentList.get(i).split("/"); //$NON-NLS-1$ if (i==0) shortestPathLength = segments[i].length; if (shortestPathLength>segments[i].length){ shortestPathLength = segments[i].length; } } for(int j = 0; j < shortestPathLength; j++){ String thisSegment = segments[0][j]; boolean allMatched = true; for(int i = 0; i < segments.length && allMatched; i++){ if(segments[i].length < j){ allMatched = false; break; } allMatched &= segments[i][j].equals(thisSegment); } if(allMatched){ commonRoot.append("/").append(thisSegment) ; //$NON-NLS-1$ }else{ break; } } //Change any double slashes to single slashes commonRoot = new StringBuilder(commonRoot.toString().replaceAll("//", "/")); //$NON-NLS-1$ //$NON-NLS-2$ return commonRoot.toString(); } /** * @since 8.0 */ public class SchemaNode { protected Object element; protected SchemaNode parent; protected boolean isRoot = false; protected Collection<SchemaNode> children = new ArrayList<SchemaTreeModel.SchemaNode>(); public SchemaNode() { parent = null; element = null; } public SchemaNode(Object element, SchemaNode parent, SchemaNode child, boolean isRoot) { this.element = element; this.parent = parent; this.setRoot(isRoot); if (child != null) { children.add(child); } } public void addChild(SchemaNode child) { this.children.add(child); } public Collection<SchemaNode> getChildren() { return children; } public void setParent(SchemaNode parent) { this.parent = parent; } public void setElement(Object element) { this.element = element; } public SchemaNode getParent() { return parent; } public Object getElement() { return element; } public boolean isRoot() { return this.isRoot; } public void setRoot(boolean isRoot) { this.isRoot = isRoot; } public String getRelativeXpath() { String name = ""; //$NON-NLS-1$ if (element instanceof XSDTypeDefinition) { name = ((XSDTypeDefinition)element).getName(); if (name==null){ name = ((XSDTypeDefinition)element).getAliasName(); } }else if (element instanceof XSDParticleImpl && ((XSDParticleImpl)element).getTerm() instanceof XSDElementDeclaration) { XSDElementDeclaration xed = (XSDElementDeclaration) ((XSDParticleImpl)element).getTerm(); name = (xed.getName() != null ? xed.getName() : xed.getAliasName()); } return "/" + getNamespacePrefix(element) + name; //$NON-NLS-1$ } public String getParentXpath() { Stack stack = new Stack(); SchemaNode parent = this.getParent(); StringBuilder xpath = new StringBuilder(); if (parent == null) { return ""; //$NON-NLS-1$ } getParentXpath(stack, parent); int stackSize=stack.size(); for (int i=0; i<stackSize; i++){ xpath.append(stack.pop()); } return xpath.toString(); } public String getFullPath() { return getParentXpath()+getRelativeXpath(); } public String getFullPathMinusLastSegment() { String relativePath = getRelativeXpath(); if (!relativePath.isEmpty()){ int i = relativePath.lastIndexOf("/"); //$NON-NLS-1$ if (i==0) { relativePath = ""; //$NON-NLS-1$ }else{ relativePath = relativePath.substring(0,i-1); } } return getParentXpath()+relativePath; } private void getParentXpath(Stack stack, SchemaNode parent) { if (parent == null) { return; } Object parentElement = parent.getElement(); String name = 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(); } stack.push("/"+ getNamespacePrefix(parentElement) +name); //$NON-NLS-1$ } else if (parentElement instanceof XSDElementDeclarationImpl) { name = ((XSDElementDeclarationImpl) parentElement).getName(); stack.push("/"+ getNamespacePrefix(parentElement) +name); //$NON-NLS-1$ } else if (parentElement instanceof XSDModelGroupImpl){ //fall through to getParentXpath() logic } else { return; } if (parent.getParent() != null) { getParentXpath(stack, parent.getParent()); } } @Override public String toString() { return "" + getElement(); //$NON-NLS-1$ } } private String getNamespacePrefix(Object obj) { String nsPrefix = ""; //$NON-NLS-1$ String ns = ""; //$NON-NLS-1$ if (obj instanceof XSDParticleImpl && ((XSDParticleImpl) obj).getContent() instanceof XSDElementDeclarationImpl) { ns = ((XSDElementDeclarationImpl) ((XSDParticleImpl) obj) .getContent()).getTargetNamespace(); } else if (obj instanceof XSDElementDeclarationImpl) { ns = ((XSDElementDeclarationImpl) obj).getTargetNamespace(); } for (Object nsKey: SchemaTreeModel.namespaceMap.keySet()){ if (SchemaTreeModel.namespaceMap.get(nsKey).equals(ns)){ nsPrefix = (String) nsKey; break; } } if (nsPrefix==null) nsPrefix=StringConstants.EMPTY_STRING; // This is default.. no need to alias // if (nsPrefix.equals(ResponseInfo.DEFAULT_NS)) nsPrefix = ""; //$NON-NLS-1$ //$NON-NLS-2$ // We will always prefix, since we can't count on a service default for a given element return nsPrefix.equals("") ? nsPrefix : nsPrefix + ":"; //$NON-NLS-1$ //$NON-NLS-2$ } }