Author: bbrodt
Date: 2010-10-29 11:44:15 -0400 (Fri, 29 Oct 2010)
New Revision: 26144
Added:
trunk/bpel/plugins/org.eclipse.bpel.model/src/org/eclipse/bpel/model/util/XSD2XMLGenerator.java
trunk/bpel/plugins/org.eclipse.bpel.model/src/org/eclipse/bpel/model/util/XSDComparer.java
Modified:
trunk/bpel/plugins/org.eclipse.bpel.model/META-INF/MANIFEST.MF
trunk/bpel/plugins/org.eclipse.bpel.ui/src/org/eclipse/bpel/ui/properties/VariablePartAssignCategory.java
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/EmfModelQuery.java
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/ModelQuery.java
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/helpers/ModelQueryImpl.java
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/model/IModelQuery.java
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/model/Validator.java
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/rules/CValidator.java
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/rules/messages.properties
Log:
OPEN - issue JBIDE-7351: General issues with Variable Initialization, Assign, and Copy
https://jira.jboss.org/browse/JBIDE-7351
Modified: trunk/bpel/plugins/org.eclipse.bpel.model/META-INF/MANIFEST.MF
===================================================================
--- trunk/bpel/plugins/org.eclipse.bpel.model/META-INF/MANIFEST.MF 2010-10-29 15:01:47 UTC
(rev 26143)
+++ trunk/bpel/plugins/org.eclipse.bpel.model/META-INF/MANIFEST.MF 2010-10-29 15:44:15 UTC
(rev 26144)
@@ -14,7 +14,9 @@
org.apache.xerces;bundle-version="[2.9.0,3.0.0)",
javax.wsdl;bundle-version="[1.5.0,1.6.0)",
org.eclipse.bpel.common.model;bundle-version="[0.4.0,2.0.0)",
- org.jboss.tools.usage;bundle-version="1.0.0";resolution:=optional
+ org.eclipse.wst.xml.core,
+ org.eclipse.wst.xml.ui,
+ org.eclipse.wst.xsd.ui
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.bpel.model,
org.eclipse.bpel.model.adapters,
@@ -31,3 +33,5 @@
org.eclipse.bpel.model.terms,
org.eclipse.bpel.model.util
Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Import-Package: org.eclipse.wst.xsd.contentmodel.internal,
+ org.eclipse.wst.xml.ui.internal.wizards
Added:
trunk/bpel/plugins/org.eclipse.bpel.model/src/org/eclipse/bpel/model/util/XSD2XMLGenerator.java
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.model/src/org/eclipse/bpel/model/util/XSD2XMLGenerator.java
(rev 0)
+++
trunk/bpel/plugins/org.eclipse.bpel.model/src/org/eclipse/bpel/model/util/XSD2XMLGenerator.java 2010-10-29
15:44:15 UTC (rev 26144)
@@ -0,0 +1,446 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.eclipse.bpel.model.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMGroup;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
+import org.eclipse.wst.xml.core.internal.contentmodel.CMNodeList;
+import org.eclipse.wst.xml.core.internal.contentmodel.ContentModelManager;
+import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMElementDeclarationImpl;
+import org.eclipse.wst.xml.core.internal.contentmodel.basic.CMNamedNodeMapImpl;
+import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilder;
+import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl;
+import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceInfoManager;
+import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMWriter;
+import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
+import org.eclipse.wst.xml.ui.internal.wizards.NewXMLGenerator;
+import org.eclipse.wst.xsd.contentmodel.internal.XSDImpl.XSDAttributeUseAdapter;
+import org.eclipse.wst.xsd.contentmodel.internal.XSDImpl.XSDElementDeclarationAdapter;
+import org.eclipse.xsd.XSDAttributeDeclaration;
+import org.eclipse.xsd.XSDAttributeUse;
+import org.eclipse.xsd.XSDConcreteComponent;
+import org.eclipse.xsd.XSDElementDeclaration;
+import org.eclipse.xsd.XSDEnumerationFacet;
+import org.eclipse.xsd.XSDNamedComponent;
+import org.eclipse.xsd.XSDSchema;
+import org.eclipse.xsd.XSDSimpleTypeDefinition;
+import org.eclipse.xsd.XSDTypeDefinition;
+import org.eclipse.xsd.impl.XSDElementDeclarationImpl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * This extends the internal NewXMLGenerator and fixes some issues with <choice>
elements
+ *
+ * @see
https://jira.jboss.org/browse/JBIDE-6748,
https://jira.jboss.org/browse/JBIDE-7351
+ * @author Bob Brodt
+ * @date Oct 29, 2010
+ */
+@SuppressWarnings("restriction")
+public class XSD2XMLGenerator extends NewXMLGenerator {
+
+ // this mess is an attempt to insulate ourselves from changes in the DOMCOntentBuilder
API
+ public static final int BUILD_OPTIONAL_ATTRIBUTES = 1;
+ public static final int BUILD_OPTIONAL_ELEMENTS = 1 << 1;
+ public static final int BUILD_FIRST_CHOICE = 1 << 2;
+ public static final int BUILD_TEXT_NODES = 1 << 3;
+ public static final int BUILD_FIRST_SUBSTITUTION = 1 << 4;
+ public static final int BUILD_STRUCTURE_ONLY = 1 << 5;
+
+ public static final int BUILD_ONLY_REQUIRED_CONTENT =
+ BUILD_FIRST_CHOICE
+ | BUILD_TEXT_NODES;
+ public static final int BUILD_ALL_CONTENT =
+ BUILD_OPTIONAL_ATTRIBUTES
+ | BUILD_OPTIONAL_ELEMENTS
+ | BUILD_FIRST_CHOICE
+ | BUILD_TEXT_NODES;
+
+ MyDOMContentBuilderImpl contentBuilder = null;
+ protected String queryPath[] = new String[0];
+ protected int myBuildPolicy = BUILD_ONLY_REQUIRED_CONTENT;
+ protected String xsdURI = null;
+
+ /**
+ * @param xsdURI
+ * @param rootElementName
+ */
+ public XSD2XMLGenerator(String xsdURI, String rootName) {
+ setRootElementName(rootName);
+ this.xsdURI = xsdURI;
+ }
+
+
+ /**
+ * Default constructor requires a call to setRoot() which will determine
+ * the root element name and XSD uri
+ */
+ public XSD2XMLGenerator() {
+ super();
+ }
+
+ /**
+ * @param path
+ */
+ public void setQueryPath(String path)
+ {
+ if (path!=null && path.length()>0) {
+ this.queryPath = path.split("/");
+ if (this.queryPath!=null && this.queryPath.length>0) {
+ for (int i=0; i<this.queryPath.length; ++i) {
+ this.queryPath[i] = this.queryPath[i].replaceFirst(".*:", "");
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.wst.xml.ui.internal.wizards.NewXMLGenerator#setBuildPolicy(int)
+ */
+ @Override
+ public void setBuildPolicy(int buildPolicy) {
+ this.myBuildPolicy = buildPolicy;
+ }
+
+ /**
+ * @return
+ * @throws Exception
+ */
+ public String createXML() throws Exception {
+
+ if (xsdURI==null)
+ throw new IllegalArgumentException("XML Generator: XSD location is
unknown");
+
+ CMDocument cmDocument = ContentModelManager.getInstance().createCMDocument(xsdURI,
"xsd");
+ setCMDocument(cmDocument);
+ createNamespaceInfoList();
+
+ // create the xml model
+ CMNamedNodeMap map = cmDocument.getElements();
+ CMElementDeclaration cmRootElement = null;
+
+ cmRootElement = (CMElementDeclaration) map.getNamedItem(getRootElementName());
+ if (cmRootElement==null)
+ throw new IllegalArgumentException("XML Generator: Root element
\'"+getRootElementName()+"\' is not defined in this XSD");
+
+ Document xmlDocument =
DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+
+ createContentBuilder(xmlDocument);
+
+ // do the dirty deed!
+ contentBuilder.createDefaultRootContent(cmDocument, cmRootElement, namespaceInfoList);
+
+ // create an output stream so we can generate a string
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
+
+ DOMWriter domWriter = new DOMWriter(outputStreamWriter);
+
+ // TODO... instead of relying on file extensions, we need to keep
+ // track of the grammar type...
+ // better yet we should create an SSE document so that we can format
+ // it nicely before saving then we won't need the DOMWriter at all
+ domWriter.print(xmlDocument);
+ outputStream.flush();
+ outputStream.close();
+
+ return outputStream.toString();
+ }
+
+ /**
+ * @param xmlDocument
+ */
+ private void createContentBuilder(Document xmlDocument) {
+ contentBuilder = new MyDOMContentBuilderImpl(xmlDocument);
+
+ // convert our build policy to theirs
+ int bp = 0;
+ if ((myBuildPolicy|BUILD_OPTIONAL_ATTRIBUTES) != 0) bp |=
DOMContentBuilder.BUILD_OPTIONAL_ATTRIBUTES;
+ if ((myBuildPolicy|BUILD_OPTIONAL_ELEMENTS) != 0) bp |=
DOMContentBuilder.BUILD_OPTIONAL_ELEMENTS;
+ if ((myBuildPolicy|BUILD_FIRST_CHOICE) != 0) bp |=
DOMContentBuilder.BUILD_FIRST_CHOICE;
+ if ((myBuildPolicy|BUILD_TEXT_NODES) != 0) bp |= DOMContentBuilder.BUILD_TEXT_NODES;
+ if ((myBuildPolicy|BUILD_FIRST_SUBSTITUTION) != 0) bp |=
DOMContentBuilder.BUILD_FIRST_SUBSTITUTION;
+ contentBuilder.setBuildPolicy(bp);
+ }
+
+
+ /**
+ * Given a CMNode object, determine the XSD type definition for the Node
+ *
+ * @param cmNode - a CMNode object encapsulating either an Element or an Attribute
+ * @return XSD type definition, or null
+ */
+ public static XSDTypeDefinition getXSDType(CMNode cmNode) {
+ // this code snippet was obtained here:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=265274
+ XSDTypeDefinition xsdType = null;
+
+ if(cmNode instanceof CMElementDeclaration) {
+ CMElementDeclaration cmElementDeclaration = (CMElementDeclaration)cmNode;
+ if(cmElementDeclaration instanceof XSDElementDeclarationAdapter) {
+ XSDElementDeclarationAdapter xsdElementDeclarationAdapter =
(XSDElementDeclarationAdapter)cmElementDeclaration;
+ Notifier target = xsdElementDeclarationAdapter.getTarget();
+ if(target instanceof XSDElementDeclaration) {
+ XSDElementDeclaration xsdElementDeclaration = (XSDElementDeclaration)target;
+ xsdType =
xsdElementDeclaration.getResolvedElementDeclaration().getTypeDefinition();
+ }
+ }
+ }
+ else if(cmNode instanceof CMAttributeDeclaration) {
+ CMAttributeDeclaration cmAttributeDeclaration = (CMAttributeDeclaration)cmNode;
+ if(cmAttributeDeclaration instanceof XSDAttributeUseAdapter) {
+ XSDAttributeUseAdapter xsdAttributeUseAdapter =
(XSDAttributeUseAdapter)cmAttributeDeclaration;
+ Notifier target = xsdAttributeUseAdapter.getTarget();
+ if(target instanceof XSDAttributeUse) {
+ XSDAttributeUse xsdAttributeUse = (XSDAttributeUse)target;
+ XSDAttributeDeclaration xsdAttributeDeclaration =
xsdAttributeUse.getAttributeDeclaration();
+ if(xsdAttributeDeclaration != null) {
+ xsdType =
xsdAttributeDeclaration.getResolvedAttributeDeclaration().getTypeDefinition();
+ }
+ }
+ }
+ }
+
+ return xsdType;
+ }
+
+ /**
+ * Internal class that extends the actual XML generator.
+ * There are a couple of, let's call them "misbehaviors", of the
DOMContentBuilder
+ * implementation that we need to correct:
+ * 1. if the caller specified an XPath and if any of the elements in that path are
+ * "choices" then generate the XML for those particular choices, instead of
picking
+ * the first choice in the sequence.
+ * 2. if the generated "choice" contains an "enumeration" element,
generate the correct
+ * text value for that element, instead of picking the first enumeration value derived
+ * from the base type.
+ */
+ public class MyDOMContentBuilderImpl extends DOMContentBuilderImpl {
+
+ // need to keep track of the current parent CMNode object so we can determine the
+ // XSD type definition when trying to build text content for a node (see
createTextNode())
+ protected Stack<CMNode> cmNodeStack = new Stack<CMNode>();
+
+ public MyDOMContentBuilderImpl(Document document) {
+ super(document);
+ }
+
+ /* (non-Javadoc)
+ * @see
org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl#createDefaultRootContent(org.eclipse.wst.xml.core.internal.contentmodel.CMDocument,
org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration)
+ */
+ @Override
+ public void createDefaultRootContent(CMDocument cmDocument,
+ CMElementDeclaration rootCMElementDeclaration) throws Exception {
+ if (namespaceInfoList != null) {
+ DOMNamespaceInfoManager manager = new DOMNamespaceInfoManager();
+ String name = rootCMElementDeclaration.getNodeName();
+ if (namespaceInfoList.size() > 0) {
+ NamespaceInfo info = (NamespaceInfo) namespaceInfoList.get(0);
+ if (info.prefix != null && info.prefix.length() > 0) {
+ name = info.prefix + ":" + name; //$NON-NLS-1$
+ }
+ }
+ rootElement = createElement(rootCMElementDeclaration, name, document);
+ if ((myBuildPolicy & BUILD_STRUCTURE_ONLY)==0)
+ manager.addNamespaceInfo(rootElement, namespaceInfoList, true);
+ }
+ createDefaultContent(document, rootCMElementDeclaration);
+ }
+
+ /* (non-Javadoc)
+ * @see
org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl#visitCMGroup(org.eclipse.wst.xml.core.internal.contentmodel.CMGroup)
+ */
+ @Override
+ public void visitCMGroup(CMGroup e) {
+ // this was copied directly from DOMContentBuilderImpl because there is apparently
+ // no way of having CMNode return the "contentHint" property (see original
implementation)
+ // short of subclassing CMNode...an example provided by the wtp team would have
+ // helped here.
+ cmGroupStack.push(e);
+
+ int forcedMin = (buildOptionalElements(myBuildPolicy) || alwaysVisit) ? 1 : 0;
+ int min = Math.max(e.getMinOccur(), forcedMin);
+
+ int max = 0;
+ if (e.getMaxOccur() == -1) // unbounded
+ max = getNumOfRepeatableElements();
+ else
+ max = Math.min(e.getMaxOccur(), getNumOfRepeatableElements());
+
+ if (max < min)
+ max = min;
+
+ alwaysVisit = false;
+
+ for (int i = 1; i <= max; i++) {
+ if (e.getOperator() == CMGroup.CHOICE && buildFirstChoice(myBuildPolicy)) {
+ CMNode cmNode = null;
+
+ if (domLevel>0 && domLevel<=queryPath.length)
+ {
+ for (int n=0; n<e.getChildNodes().getLength(); ++n ) {
+ CMNode cn = e.getChildNodes().item(n);
+ if (cn.getNodeName().equals(queryPath[domLevel-1])) {
+ cmNode = cn;
+ break;
+ }
+ }
+ }
+
+ // if no cmNode has been determined from the path, just use the first choice
+ if (cmNode == null) {
+ CMNodeList nodeList = e.getChildNodes();
+ if (nodeList.getLength() > 0) {
+ cmNode = nodeList.item(0);
+ }
+ }
+
+ if (cmNode != null) {
+ visitCMNode(cmNode);
+ }
+ }
+ else if (e.getOperator() == CMGroup.ALL // ALL
+ || e.getOperator() == CMGroup.SEQUENCE) // SEQUENCE
+ {
+ // visit all of the content
+ super.visitCMGroup(e);
+ }
+ }
+
+ cmGroupStack.pop();
+ }
+
+ /* (non-Javadoc)
+ * @see
org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl#handlePushParent(org.w3c.dom.Element,
org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration)
+ */
+ @Override
+ protected void handlePushParent(Element parent, CMElementDeclaration ed) {
+ super.handlePushParent(parent, ed);
+ cmNodeStack.push(ed);
+ }
+
+ /* (non-Javadoc)
+ * @see
org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl#handlePopParent(org.w3c.dom.Element,
org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration)
+ */
+ @Override
+ protected void handlePopParent(Element element, CMElementDeclaration ed) {
+ super.handlePopParent(element, ed);
+ cmNodeStack.pop();
+ }
+
+ /* (non-Javadoc)
+ * @see
org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl#createElement(org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration,
java.lang.String, org.w3c.dom.Node)
+ */
+ @Override
+ protected org.w3c.dom.Element createElement(CMElementDeclaration ed, String name, Node
parent) {
+ // if building XML that represents only structure, use a generic element name
+ // (either "simpleElem" or "complexElem") instead of the elements
actual tag name
+ if ((myBuildPolicy & BUILD_STRUCTURE_ONLY) != 0) {
+ CMDataType dt = ed.getDataType();
+ if (dt!=null)
+ return document.createElement("simpleElem");
+ return document.createElement("complexElem");
+ }
+ return document.createElement(name);
+ }
+
+ /* (non-Javadoc)
+ * @see
org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl#createAttribute(org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration,
java.lang.String, org.w3c.dom.Node)
+ */
+ @Override
+ protected org.w3c.dom.Attr createAttribute(CMAttributeDeclaration ad, String name, Node
parent) {
+ // TODO: I think attribute names MUST match even if we're only building XML
structure
+ // for the purposes of comparing two XSD fragments...
+ return document.createAttribute(name);
+ }
+
+ /* (non-Javadoc)
+ * @see
org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl#createTextNode(org.eclipse.wst.xml.core.internal.contentmodel.CMDataType,
java.lang.String, org.w3c.dom.Node)
+ */
+ @Override
+ protected org.w3c.dom.Text createTextNode(CMDataType dataType, String value, Node
parent) {
+
+ // get XSD type definition from parent object currently at the top of our stack
+ // so that we can get the (reduced) enumeration value types for that element
+ // instead of for the base type (which is what XSDImpl#getEnumeratedValuesForType()
does!)
+ if (cmNodeStack.size()>0) {
+ XSDTypeDefinition xsdType = getXSDType(cmNodeStack.peek());
+ if (xsdType!=null) {
+ List result = new ArrayList();
+ getEnumeratedValuesForSimpleType(xsdType, result);
+ if (!result.isEmpty()) {
+ value = (String)result.get(0);
+ return document.createTextNode(value);
+ }
+ }
+ }
+
+ // if building XML that represents only structure, use a generic text value
+ // (the data type) instead of the value determined by the generator (see
+ // XSDTypeUtil#getInstanceValue() for example...)
+ if ((myBuildPolicy & BUILD_STRUCTURE_ONLY) != 0)
+ value = dataType.getDataTypeName();
+
+ return document.createTextNode(value);
+ }
+
+ /**
+ * This was stolen directly from XSDImpl. It builds a list of the enumeration
+ * values for the given XSD type definition.
+ *
+ * @param type - an XSD type definition (presumably determined from a CMNode)
+ * @param result - List to which we will add our results
+ */
+ public void getEnumeratedValuesForSimpleType(XSDTypeDefinition type, List result) {
+ List enumerationFacets = ((XSDSimpleTypeDefinition) type)
+ .getEnumerationFacets();
+ for (Iterator i = enumerationFacets.iterator(); i.hasNext();) {
+ XSDEnumerationFacet enumFacet = (XSDEnumerationFacet) i.next();
+ List values = enumFacet.getValue();
+ for (Iterator j = values.iterator(); j.hasNext();) {
+ Object o = j.next();
+ if (o != null) {
+ if (!result.contains(o)) {
+ result.add(o.toString());
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Added:
trunk/bpel/plugins/org.eclipse.bpel.model/src/org/eclipse/bpel/model/util/XSDComparer.java
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.model/src/org/eclipse/bpel/model/util/XSDComparer.java
(rev 0)
+++
trunk/bpel/plugins/org.eclipse.bpel.model/src/org/eclipse/bpel/model/util/XSDComparer.java 2010-10-29
15:44:15 UTC (rev 26144)
@@ -0,0 +1,781 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.eclipse.bpel.model.util;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.xsd.*;
+import org.eclipse.xsd.util.XSDConstants;
+
+/**
+ * Compares two XSD fragments for structure and data type compatibility.
+ * Optional components in either the left or right schema may be skipped
+ * over during the comparison unless a strict match is requested (see
+ * <code>setStrict()<code>).
+ *
+ * Components which have a "minOccurs" of 0 are considered optional.
+ * Wildcard components (<xsd:any> elements) will match any component
+ * in the other schema.
+ *
+ * After the comparison, diagnostics are available which indicate the
+ * components in the left and right schema that do not match. Warning
+ * diagnostics are generated whenever optional components were skipped
+ * to force a match.
+ *
+ * @see
https://jira.jboss.org/browse/JBIDE-7351
+ * @author Bob Brodt
+ * @date Oct 29, 2010
+ */
+public class XSDComparer {
+
+ protected boolean strict = false;
+ protected boolean debug = false;
+ protected List<XSDDiagnostic> diagnostics;
+
+ public void setStrict(boolean flag) {
+ strict = flag;
+ }
+
+ public void setDebug(boolean flag) {
+ debug = flag;
+ }
+
+ /**
+ * The main comparison function that compares two XSD type definitions.
+ * These may be the entire schema or just fragments within a schema.
+ *
+ * @param type1 - the "left" type definition
+ * @param type2 - the "right" type definition
+ * @return true if the types are compatible, false if not.
+ * Warning diagnostics may still be generated for a successful match.
+ */
+ public boolean compare(XSDTypeDefinition type1, XSDTypeDefinition type2) {
+ boolean result = false;
+ if (type1==null || type2==null)
+ throw new IllegalArgumentException("XSDComparer: XSD types may not be
null");
+
+ try {
+ // always clear out diagnostics before we start
+ if (diagnostics!=null)
+ diagnostics.clear();
+
+ // for debugging only: run through the exercises even if the
+ // two objects are one and the same
+ if (!debug && type1==type2)
+ return true;
+
+ result = compare(getChildTerms(type1), getChildTerms(type2), 0);
+ } catch (Exception e) {
+ return false;
+ }
+
+ return result;
+ }
+
+ /**
+ * Compares a list of the immediate children of a component; called recursively
+ * for children that are complex elements.
+ *
+ * @param list1 - children of the "left" schema
+ * @param list2 - children of the "right" schema
+ * @param level - recursion level (for debug printing)
+ * @return true if the left and right children lists are compatible.
+ */
+ protected boolean compare(List<XSDTerm> list1, List<XSDTerm> list2, int
level) {
+
+ XSDTerm term1 = null;
+ XSDTerm term2 = null;
+
+ try {
+ int index1 = 0;
+ int index2 = 0;
+ int size1 = list1.size();
+ int size2 = list2.size();
+ while (index1 < size1 && index2 < size2) {
+ term1 = list1.get(index1);
+ term2 = list2.get(index2);
+ if ( term1 instanceof XSDElementDeclaration && term2 instanceof
XSDElementDeclaration) {
+ XSDElementDeclaration elem1 = (XSDElementDeclaration)term1;
+ XSDElementDeclaration elem2 = (XSDElementDeclaration)term2;
+ XSDTypeDefinition type1 = elem1.getTypeDefinition();
+ XSDTypeDefinition type2 = elem2.getTypeDefinition();
+ if (type1 instanceof XSDSimpleTypeDefinition && type2 instanceof
XSDSimpleTypeDefinition) {
+ dump("Comparing ", elem1, type1, level);
+ dump(" to ", elem2, type2, level);
+ String s1 = getTypeNameHierarchy(elem1);
+ String s2 = getTypeNameHierarchy(elem2);
+ if (!s1.equals(s2)) {
+ addError("different data types: "+s1+" vs "+s2,elem1,elem2);
+ return false;
+ }
+ } else if (type1 instanceof XSDComplexTypeDefinition && type2 instanceof
XSDComplexTypeDefinition) {
+ int min1 = getMinOccurs(term1);
+ int min2 = getMinOccurs(term2);
+ int max1 = getMaxOccurs(term1);
+ int max2 = getMaxOccurs(term2);
+ if (strict) {
+ if (min1 != min2 || max1 != max2) {
+ addError("different cardinality: " + min1 + " to " + max1 +
" vs " + min2 + " to " + max2, term1,term2);
+ return false;
+ }
+ } else {
+ if (min1 > max2 || min2 > max1) {
+ addError("incompatible cardinality: " + min1 + " to " + max1
+ " vs " + min2 + " to " + max2, term1,term2);
+ return false;
+ }
+ }
+ dump("Comparing ", elem1, type1, level);
+ dump(" to ", elem2, type2, level);
+ boolean result = compare(getChildTerms(elem1), getChildTerms(elem2), level + 1);
+ if (!result) {
+ addError("different complex element structures",elem1,elem2);
+ return false;
+ }
+ } else {
+ if (!strict) {
+ // try shifting optional elements and continue from there
+ dump("Elements out of sync - skipping optional elements");
+ if (isOptional(elem1)) {
+ // skip over this one and compare remaining elements
+ List<XSDTerm> newList1 = new ArrayList<XSDTerm>();
+ List<XSDTerm> newList2 = new ArrayList<XSDTerm>();
+ for (int i = index1 + 1; i < size1; ++i)
+ newList1.add(list1.get(i));
+ for (int i = index2; i < size2; ++i)
+ newList2.add(list2.get(i));
+ if (compare(newList1, newList2, level)) {
+ addWarning("skipped optional element(s) in left schema",elem1,elem2);
+ return true;
+ }
+ addError("different complex element structures",elem1,elem2);
+ }
+ if (isOptional(elem2)) {
+ // skip over this one and compare remaining elements
+ List<XSDTerm> newList1 = new ArrayList<XSDTerm>();
+ List<XSDTerm> newList2 = new ArrayList<XSDTerm>();
+ for (int i = index1; i < size1; ++i)
+ newList1.add(list1.get(i));
+ for (int i = index2 + 1; i < size2; ++i)
+ newList2.add(list2.get(i));
+ if (compare(newList1, newList2, level)) {
+ addWarning("skipped optional element(s) in right
schema",elem1,elem2);
+ return true;
+ }
+ addError("different complex element structures",elem1,elem2);
+ }
+ }
+ addError("different complex element structures",elem1,elem2);
+ return false;
+ }
+
+ List<XSDAttributeDeclaration> attrs1 = getAttributeDeclarations(elem1);
+ List<XSDAttributeDeclaration> attrs2 = getAttributeDeclarations(elem2);
+ if (attrs1.size() != attrs2.size()) {
+ addError("differing number of attributes",elem1,elem2);
+ return false;
+ }
+ for (int i = 0; i < attrs1.size(); ++i) {
+ XSDAttributeDeclaration attr1 = attrs1.get(i);
+ XSDAttributeDeclaration attr2 = attrs2.get(i);
+ if (!attr1.getQName().equals(attr2.getQName())) {
+ addError("differing attribute names: "+attr1.getQName()+" vs
"+attr2.getQName(),elem1,elem2);
+ return false;
+ }
+ if (!attr1.getLexicalValue().equals(attr2.getLexicalValue())) {
+ addError("differing attribute values: "+attr1.getLexicalValue()+"
vs "+attr2.getLexicalValue(),elem1,elem2);
+ return false;
+ }
+ }
+
+ } else if (term1 instanceof XSDWildcard && !(term2 instanceof XSDWildcard) )
{
+ // left schema term is a wildcard, right schema is not
+ int min = getMinOccurs(term1);
+ int max = getMinOccurs(term1);
+ if (max==-1)
+ max = size1;
+
+ for (int n=min; n<=max; ++n) {
+ // skip over this one and compare remaining elements
+ List<XSDTerm> newList1 = new ArrayList<XSDTerm>();
+ List<XSDTerm> newList2 = new ArrayList<XSDTerm>();
+ for (int i = index1 + 1 + n; i < size1; ++i)
+ newList1.add(list1.get(i));
+ for (int i = index2; i < size2; ++i)
+ newList2.add(list2.get(i));
+ if (compare(newList1, newList2, level)) {
+ addWarning("skipped optional element(s) in left schema",term1,term2);
+ return true;
+ }
+ }
+ addError("different complex element structures",term1,term2);
+ return false;
+ } else if (term1 instanceof XSDWildcard && !(term2 instanceof XSDWildcard) )
{
+ // right schema is a wildcard, left schema is not
+ int min = getMinOccurs(term2);
+ int max = getMinOccurs(term2);
+ if (max==-1)
+ max = size2;
+
+ for (int n=min; n<=max; ++n) {
+ // skip over this one and compare remaining elements
+ List<XSDTerm> newList1 = new ArrayList<XSDTerm>();
+ List<XSDTerm> newList2 = new ArrayList<XSDTerm>();
+ for (int i = index1; i < size1; ++i)
+ newList1.add(list1.get(i));
+ for (int i = index2 + 1 + n; i < size2; ++i)
+ newList2.add(list2.get(i));
+ if (compare(newList1, newList2, level)) {
+ addWarning("skipped optional element(s) in right schema",term1,term2);
+ return true;
+ }
+ }
+ addError("different complex element structures",term1,term2);
+ return false;
+ } else if (term1 instanceof XSDWildcard && term2 instanceof XSDWildcard) {
+ // both wildcards - it's a match!
+ int min1 = getMinOccurs(term1);
+ int max1 = getMinOccurs(term1);
+ int min2 = getMinOccurs(term2);
+ int max2 = getMinOccurs(term2);
+ if (min1!=min2 || max1!=max2) {
+ // not possible
+ addError("different <xsd:any> cardinality: "+min1+" to
"+max1+" vs "+min2+" to "+max2,term1,term2);
+ }
+ }
+
+ ++index1;
+ ++index2;
+ }
+
+ // any leftovers? they must be optional
+ if (strict && size1 != size2) {
+ addError("different number of elements: "+size1+" vs
"+size2,term1,term2);
+ return false;
+ }
+
+ if (index1 < size1) {
+ dump("Additional elements in left schema");
+ while (index1 < size1) {
+ term1 = list1.get(index1);
+ if (isOptional(term1)) {
+ dump("Ignoring optional element", term1, null, 1);
+ addWarning("skipped optional element in left schema",term1,term2);
+ term1 = list2.get(++index1);
+ } else {
+ addError("additional elements in left schema",term1,term2);
+ return false;
+ }
+ }
+ }
+
+ if (index2 < size2) {
+ dump("Additional elements in right schema");
+ while (index2 < size2) {
+ term2 = list2.get(index2);
+ if (isOptional(term2)) {
+ dump("Ignoring optional element", term2, null, 1);
+ addWarning("skipped optional element in right schema",term1,term2);
+ term2 = list2.get(++index2);
+ } else {
+ addError("additional elements in right schema",term1,term2);
+ return false;
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ addError("caught exception: "+e.toString(),term1,term2);
+ return false;
+ }
+ dump("*** Schemas are compatible");
+
+ return true;
+ }
+
+ /**
+ * Returns the data type name of the given element, including base types.
+ *
+ * @param elem - the element
+ * @return data type name hierarchy as a ":" separated string
+ */
+ protected String getTypeNameHierarchy(XSDElementDeclaration elem) {
+ String s = "";
+ Stack<String> names = new Stack<String>();
+ XSDTypeDefinition type = elem.getType();
+ while (type != type.getBaseType()) {
+ String name = type.getName();
+ if (name != null)
+ names.push(name);
+ type = type.getBaseType();
+ }
+ while (!names.isEmpty()) {
+ if (s.isEmpty())
+ s = names.pop();
+ else
+ s = s + ":" + names.pop();
+ }
+ return s;
+ }
+
+ /**
+ * Returns a list of immediate children for the specified element.
+ *
+ * @param element - the parent element
+ * @return A list of XSDTerm objects
+ */
+ protected final List<XSDTerm> getChildTerms(XSDElementDeclaration element) {
+ return getChildTerms(element.getType());
+ }
+
+ /**
+ * Returns a list of immediate children for the specified XSD type.
+ *
+ * @param type - the parent type
+ * @return A list of XSDTerm objects
+ */
+ protected final List<XSDTerm> getChildTerms(XSDTypeDefinition type) {
+ final ArrayList<XSDTerm> terms = new ArrayList<XSDTerm>();
+
+ TypeWalker.Visitor visitor = new TypeWalker.Visitor() {
+ public boolean visit(XSDTypeDefinition type) {
+ // simple types don't have children
+ if (type instanceof XSDSimpleTypeDefinition)
+ return true;
+
+ XSDComplexTypeDefinition cType = (XSDComplexTypeDefinition) type;
+
+ visitTerms(cType, new TermVisitor() {
+ public void visit(XSDParticle particle) {
+ // element declaration, or wildcard: add to list
+ XSDParticleContent content = particle.getContent();
+ if (content instanceof XSDElementDeclaration) {
+ XSDElementDeclaration decl = (XSDElementDeclaration) particle.getContent();
+
+ if (decl.isElementDeclarationReference())
+ decl = decl.getResolvedElementDeclaration();
+ // System.out.println("Adding "+decl.getName());
+ terms.add(decl);
+ } else if (content instanceof XSDWildcard) {
+ // System.out.println("Adding <xsd:any>");
+ terms.add((XSDWildcard) content);
+ }
+ }
+ });
+
+ return true;
+ }
+ };
+
+ TypeWalker walker = new TypeWalker(type);
+ walker.walk(visitor);
+
+ return terms;
+ }
+
+ /**
+ * Returns the value of the "minOccurs" attribute for the given XSD element.
+ *
+ * @param term - the XSD element
+ * @return numerical value of "minOccurs" or 1 if the element does not
specify
+ */
+ public int getMinOccurs(XSDTerm term) {
+ String smin = term.getElement().getAttribute("minOccurs");
+ int min = 1;
+ if (smin!=null && !smin.isEmpty()) {
+ try {
+ min = Integer.parseInt(smin);
+ } catch (NumberFormatException e) {
+ }
+ }
+ return min;
+ }
+
+ /**
+ * Returns the value of the "maxOccurs" attribute for the given XSD element.
+ *
+ * @param term - the XSD element
+ * @return numerical value of "maxOccurs" or 1 if the element does not
specify
+ */
+ public int getMaxOccurs(XSDTerm term) {
+ String smax = term.getElement().getAttribute("maxOccurs");
+ int max = 1;
+ if (smax!=null && !smax.isEmpty()) {
+ try {
+ max = Integer.parseInt(smax);
+ } catch (NumberFormatException e) {
+ if (smax.equalsIgnoreCase("unbounded"))
+ max = -1;
+ }
+ }
+ return max;
+ }
+
+ /**
+ * Returns true if the specified XSD element is optional.
+ *
+ * @param term
+ * @return true if the element has "minOccurs=0"
+ */
+ protected boolean isOptional(XSDTerm term) {
+
+ if (getMinOccurs(term)==0)
+ return true;
+ return false;
+ }
+
+ /**
+ * Examine the content of a complex type and visit each of its particles.
+ * This will expand <xsd:sequence>, <xsd:choice>, <xsd:all>,
<xsd:group>
+ * and <xsd:any> elements.
+ *
+ * @param cType - the complex type to examine
+ * @param visitor - a TermVisitor which will be called for each particle found
+ */
+ private void visitTerms(XSDComplexTypeDefinition cType, TermVisitor visitor) {
+
+ // simple types are leaf nodes
+ if (cType.getContent() == null || (cType.getContent() instanceof
XSDSimpleTypeDefinition))
+ return;
+
+ // the last particle visited; used to detect <xsd:any> elements
+ XSDParticleContent lastVisited = null;
+
+ // use a queue to simulate the recursion
+ LinkedList<XSDParticle> queue = new LinkedList<XSDParticle>();
+ queue.addLast((XSDParticle) cType.getContent());
+
+ while (!queue.isEmpty()) {
+ XSDParticle particle = (XSDParticle) queue.removeFirst();
+
+ // analyze type of particle content
+ int pType = org.eclipse.xsd.util.XSDUtil.nodeType(particle.getElement());
+ if (pType == XSDConstants.ELEMENT_ELEMENT) {
+ lastVisited = particle.getContent();
+ visitor.visit(particle);
+ } else {
+ // model group
+ XSDModelGroup modelGroup = null;
+ switch (pType) {
+ case XSDConstants.GROUP_ELEMENT:
+ XSDModelGroupDefinition grpDef = (XSDModelGroupDefinition) particle.getContent();
+ if (grpDef.isModelGroupDefinitionReference())
+ grpDef = grpDef.getResolvedModelGroupDefinition();
+
+ modelGroup = grpDef.getModelGroup();
+ break;
+
+ case XSDConstants.CHOICE_ELEMENT:
+ case XSDConstants.ALL_ELEMENT:
+ case XSDConstants.SEQUENCE_ELEMENT:
+ modelGroup = (XSDModelGroup) particle.getContent();
+ break;
+
+ case XSDConstants.ANY_ELEMENT:
+ // see forum post at:
+ //
http://www.eclipse.org/forums/index.php?t=msg&th=20437&start=0&am...
+ //
+ // The XSDWildcard seems to be emitted in the case where an element has no type
information;
+ // and it is also emitted in response to an actual xsd:any element appearing in the
schema.
+ //
+ // In both cases, the XSDWildcard appears the same (surprisingly it refers to a DOM
element
+ // from Xerces of xsd:any). there is confusion here between elements of type
anyType, i..e.,
+ // <xsd:element name="x" type=xsd:anyType"/> verses element
wildcards <xsd:any>. When matching
+ // element content using the DFA returned by XSDParticle, each element will match
either an
+ // element declaration or a wildcard, which you can tell apart easily by whether
you've matched
+ // an XSDElementDeclaration or an XSDWildcard.
+ if (lastVisited!=null) {
+ // found an <xsd:any> element - go visit it!
+ lastVisited = particle.getContent();
+ visitor.visit(particle);
+ }
+ break;
+
+ default:
+ // TODO: do we need to handle additional XSD node types?
+ break;
+ }
+
+ if (modelGroup != null) {
+ // enque all particles in the group
+ List<XSDParticle> particles = modelGroup.getParticles();
+ for (XSDParticle p : particles) {
+ queue.addLast(p);
+ }
+
+ lastVisited = null;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a list of all attribute declarations declared in the type or any
+ * base type, of the specified element.
+ *
+ * @param element - the element
+ * @return a list of XSDAttributeDeclaration objects
+ */
+ public final List<XSDAttributeDeclaration>
getAttributeDeclarations(XSDElementDeclaration element) {
+ final ArrayList<XSDAttributeDeclaration> attributes = new
ArrayList<XSDAttributeDeclaration>();
+
+ // walk up the type hierarchy of the element to generate a list of atts
+ TypeWalker walker = new TypeWalker(element.getType());
+
+ TypeWalker.Visitor visitor = new TypeWalker.Visitor() {
+ public boolean visit(XSDTypeDefinition type) {
+
+ // simple types dont have attributes
+ if (type instanceof XSDSimpleTypeDefinition)
+ return true;
+
+ XSDComplexTypeDefinition cType = (XSDComplexTypeDefinition) type;
+
+ // get all the attribute content (groups,or uses) and add to list
+ List<XSDAttributeGroupContent> contents = cType.getAttributeContents();
+ for (XSDAttributeGroupContent content : contents) {
+ if (content instanceof XSDAttributeUse) {
+ // an attribute, add it to the list
+ XSDAttributeUse use = (XSDAttributeUse) content;
+ attributes.add(use.getAttributeDeclaration());
+ } else if (content instanceof XSDAttributeGroupDefinition) {
+ // attribute group, add all atts in group to list
+ XSDAttributeGroupDefinition attGrp = (XSDAttributeGroupDefinition) content;
+
+ if (attGrp.isAttributeGroupDefinitionReference()) {
+ attGrp = attGrp.getResolvedAttributeGroupDefinition();
+ }
+
+ List<XSDAttributeUse> uses = attGrp.getAttributeUses();
+ for (XSDAttributeUse use : uses) {
+ attributes.add(use.getAttributeDeclaration());
+ }
+ }
+ }
+
+ return true;
+ }
+ };
+
+ walker.walk(visitor);
+ return attributes;
+ }
+
+ /**
+ * Returns a list diagnostics of that may have been created
+ * during the comparison
+ *
+ * @return a list of XSDDiagnostic objects
+ */
+ public List<XSDDiagnostic> getDiagnostics() {
+ if (diagnostics==null) {
+ diagnostics = new ArrayList<XSDDiagnostic>();
+ }
+ return diagnostics;
+ }
+
+ /**
+ * Convenience method for formatting diagnostics as strings
+ *
+ * @param index - the index into the diagnostics array
+ * @return a nicely formatted string
+ */
+ public String getDiagnostic(int index) {
+ String msg = "";
+
+ if (diagnostics!=null && index>=0 && index<diagnostics.size()) {
+ XSDDiagnostic d = diagnostics.get(index);
+ String name1 = "";
+ String name2 = "";
+ String schema1 = "";
+ String schema2 = "";
+ XSDTerm comp1 = null;
+ XSDTerm comp2 = null;
+ EList<XSDConcreteComponent> components = d.getComponents();
+ if (components.size()>0 && components.get(0) instanceof XSDTerm)
+ comp1 = (XSDTerm)components.get(0);
+ if (components.size()>1 && components.get(1) instanceof XSDTerm)
+ comp2 = (XSDTerm)components.get(1);
+
+ if (comp1 instanceof XSDElementDeclaration) {
+ name1 = ((XSDElementDeclaration)comp1).getQName();
+ schema1 = comp1.eResource().getURI().toString();
+ }
+ else if (comp1 instanceof XSDWildcard) {
+ name1 = "<xsd:any>";
+ schema1 = comp1.eResource().getURI().toString();
+ }
+ if (comp2 instanceof XSDElementDeclaration) {
+ name2 = ((XSDElementDeclaration)comp2).getQName();
+ schema2 = comp2.eResource().getURI().toString();
+ }
+ else if (comp2 instanceof XSDWildcard) {
+ name2 = "<xsd:any>";
+ schema2 = comp2.eResource().getURI().toString();
+ }
+
+ if ( comp1!=null && comp2!=null ) {
+ msg = "Element <" + name1 + ">" +
+ " in " + schema1 +
+ " differs from <" + name2 + ">";
+ if (!schema1.equals(schema2))
+ msg += " in " + schema2;
+ msg += " - " + d.getMessage();
+ }
+ else {
+ msg =
+ "Schema " + d.getLocationURI() +
+ " - " + d.getMessage();
+ }
+ }
+ return msg;
+ }
+
+ /**
+ * Creates a new diagnostic and adds it to our list.
+ *
+ * @param severity - one of the XSDDiagnosticSeverity values (WARNING, ERROR, etc.)
+ * @param msg - a human-readable message to associate with the diagnostic
+ * @param comp1 - the "left" schema component
+ * @param comp2 - the "right" schema component
+ * @return a newly constructed XSDDiagnostic object
+ */
+ protected XSDDiagnostic addDiagnostic(int severity, String msg, XSDConcreteComponent
comp1, XSDConcreteComponent comp2) {
+ XSDDiagnostic diag = XSDFactory.eINSTANCE.createXSDDiagnostic();
+ diag.setSeverity(XSDDiagnosticSeverity.get(severity));
+ diag.setMessage(msg);
+ diag.getComponents().add(comp1);
+ diag.getComponents().add(comp2);
+ getDiagnostics().add(diag);
+
+ return diag;
+ }
+
+ /**
+ * Convenience method for creating a WARNING diagnostic
+ *
+ * @param msg - a human-readable message to associate with the diagnostic
+ * @param comp1 - the "left" schema component
+ * @param comp2 - the "right" schema component
+ * @return a newly constructed XSDDiagnostic object
+ */
+ protected XSDDiagnostic addWarning(String msg, XSDConcreteComponent comp1,
XSDConcreteComponent comp2) {
+ return addDiagnostic(XSDDiagnosticSeverity.WARNING, msg, comp1, comp2);
+ }
+
+ /**
+ * Convenience method for creating a WARNING diagnostic
+ *
+ * @param msg - a human-readable message to associate with the diagnostic
+ * @param comp1 - the "left" schema component
+ * @param comp2 - the "right" schema component
+ * @return a newly constructed XSDDiagnostic object
+ */
+ protected XSDDiagnostic addError(String msg, XSDConcreteComponent comp1,
XSDConcreteComponent comp2) {
+ return addDiagnostic(XSDDiagnosticSeverity.ERROR, msg, comp1, comp2);
+ }
+
+ /**
+ * Debug message printer
+ *
+ * @param label - a text string to print to stderr
+ */
+ private void dump(String label) {
+
+ if (debug)
+ dump(label, null, null, 0);
+ }
+
+ /**
+ * Debug message printer
+ *
+ * @param label - text string
+ * @param term - an XSD element to dump
+ * @param type - and its type
+ * @param level - indent level
+ */
+ private void dump(String label, XSDTerm term, XSDTypeDefinition type, int level) {
+
+ if (debug) {
+ if (term != null && type != null) {
+ String indent = "";
+ for (int i = 0; i < level; ++i)
+ indent += " ";
+ if (term instanceof XSDElementDeclaration) {
+ XSDElementDeclaration decl = (XSDElementDeclaration) term;
+ if (type instanceof XSDSimpleTypeDefinition)
+ System.err.println(label + indent + "<" + decl.getName() + ">
type=\""
+ + this.getTypeNameHierarchy(decl)+"\"");
+ else if (type instanceof XSDComplexTypeDefinition || type == null)
+ System.err.println(label + indent + "<" + decl.getName() +
"\">");
+ else
+ System.err.println("dump: unknown XSD type: " +
type.getClass().toString());
+ } else if (term instanceof XSDWildcard) {
+ System.err.println(label + indent + "<any/>");
+ } else
+ System.err.println("dump: unknown term: " + term.getClass().toString());
+ } else
+ System.err.println(label);
+ }
+ }
+
+ /**
+ * Simple visitor interface for complex types
+ */
+ private interface TermVisitor {
+ void visit(XSDParticle particle);
+ }
+
+ /**
+ * XSD type hierarchy walker that visits each XSD type from the bottom-up
+ */
+ private static class TypeWalker {
+
+ // bottom of the type hierarchy
+ XSDTypeDefinition base;
+
+ public TypeWalker(XSDTypeDefinition base) {
+ this.base = base;
+ }
+
+ public void walk(Visitor visitor) {
+
+ XSDTypeDefinition type = base;
+
+ while(type != null) {
+ if (!visitor.visit(type))
+ break;
+ // walk up the type hierarchy to the top
+ if (type.equals(type.getBaseType()))
+ break;
+ type = type.getBaseType();
+ }
+ }
+
+ public interface Visitor {
+ boolean visit(XSDTypeDefinition type);
+ }
+ }
+}
Modified:
trunk/bpel/plugins/org.eclipse.bpel.ui/src/org/eclipse/bpel/ui/properties/VariablePartAssignCategory.java
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.ui/src/org/eclipse/bpel/ui/properties/VariablePartAssignCategory.java 2010-10-29
15:01:47 UTC (rev 26143)
+++
trunk/bpel/plugins/org.eclipse.bpel.ui/src/org/eclipse/bpel/ui/properties/VariablePartAssignCategory.java 2010-10-29
15:44:15 UTC (rev 26144)
@@ -10,13 +10,10 @@
*******************************************************************************/
package org.eclipse.bpel.ui.properties;
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collections;
import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilderFactory;
import org.eclipse.bpel.common.ui.details.IDetailsAreaConstants;
import org.eclipse.bpel.common.ui.flatui.FlatFormAttachment;
@@ -31,6 +28,7 @@
import org.eclipse.bpel.model.messageproperties.Property;
import org.eclipse.bpel.model.util.BPELConstants;
import org.eclipse.bpel.model.util.BPELUtils;
+import org.eclipse.bpel.model.util.XSD2XMLGenerator;
import org.eclipse.bpel.ui.Messages;
import org.eclipse.bpel.ui.adapters.IVirtualCopyRuleSide;
import org.eclipse.bpel.ui.commands.InsertCopyCommand;
@@ -57,20 +55,10 @@
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.wsdl.Message;
import org.eclipse.wst.wsdl.Part;
-import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
-import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
-import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
-import org.eclipse.wst.xml.core.internal.contentmodel.ContentModelManager;
-import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl;
-import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceInfoManager;
-import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMWriter;
-import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
-import org.eclipse.wst.xml.ui.internal.wizards.NewXMLGenerator;
import org.eclipse.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDTypeDefinition;
-import org.w3c.dom.Document;
/**
* An AssignCategory presenting a tree from which the user can select any of: -
@@ -578,16 +566,17 @@
return;
}
- MyNewXMLGenerator generator = new MyNewXMLGenerator();
- generator.setRootElementName(rootElement);
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // use the new and improved XSD -> XML generator
+ // this was an internal class that was moved to org.eclipse.bpel.model.util
+ XSD2XMLGenerator generator = new XSD2XMLGenerator(uriWSDL, rootElement);
- CMDocument cmdoc = ContentModelManager.getInstance().createCMDocument(
- uriWSDL, "xsd");
- generator.setCMDocument(cmdoc);
- generator.createNamespaceInfoList();
+ // be sure to tell the generator which elements in a "choice" we are
interested in
+ if (side.getQuery()!=null && side.getQuery().getValue().trim().length()>0)
+ generator.setQueryPath(side.getQuery().getValue());
try {
- String literal = generator.createXML("tmp");
+ String literal = generator.createXML();
Copy copy = BPELFactory.eINSTANCE.createCopy();
Assign a = (Assign) ((To) side.getCopyRuleSide()).getContainer()
.getContainer();
@@ -710,72 +699,4 @@
}
}
-
- class MyNewXMLGenerator extends NewXMLGenerator {
-
- public String createXML(String xmlFileName) throws Exception {
- CMDocument cmDocument = getCMDocument();
-
- // create the xml model
- CMNamedNodeMap nameNodeMap = cmDocument.getElements();
- CMElementDeclaration cmElementDeclaration = (CMElementDeclaration) nameNodeMap
- .getNamedItem(getRootElementName());
-
- Document xmlDocument = DocumentBuilderFactory.newInstance()
- .newDocumentBuilder().newDocument();
- MyDOMContentBuilderImpl contentBuilder = new MyDOMContentBuilderImpl(
- xmlDocument);
-
- contentBuilder.setBuildPolicy(contentBuilder.BUILD_OPTIONAL_ELEMENTS);
- contentBuilder.createDefaultRootContent(cmDocument,
- cmElementDeclaration, namespaceInfoList);
-
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
- outputStream);
-
- DOMWriter domWriter = new DOMWriter(outputStreamWriter);
-
- // TODO... instead of relying on file extensions, we need to keep
- // track of the grammar type
- // better yet we should reate an SSE document so that we can format
- // it
- // nicely before saving
- // then we won't need the DOMWriter at all
- //
- domWriter.print(xmlDocument);
- outputStream.flush();
- outputStream.close();
-
- return outputStream.toString();
- }
-
- }
-
- class MyDOMContentBuilderImpl extends DOMContentBuilderImpl {
-
- public MyDOMContentBuilderImpl(Document document) {
- super(document);
- }
-
- @Override
- public void createDefaultRootContent(CMDocument cmDocument,
- CMElementDeclaration rootCMElementDeclaration) throws Exception {
- if (namespaceInfoList != null) {
- DOMNamespaceInfoManager manager = new DOMNamespaceInfoManager();
- String name = rootCMElementDeclaration.getNodeName();
- if (namespaceInfoList.size() > 0) {
- NamespaceInfo info = (NamespaceInfo) namespaceInfoList
- .get(0);
- if (info.prefix != null && info.prefix.length() > 0) {
- name = info.prefix + ":" + name; //$NON-NLS-1$
- }
- }
- rootElement = createElement(rootCMElementDeclaration, name,
- document);
- manager.addNamespaceInfo(rootElement, namespaceInfoList, true);
- }
- createDefaultContent(document, rootCMElementDeclaration);
- }
- }
}
Modified:
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/EmfModelQuery.java
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/EmfModelQuery.java 2010-10-29
15:01:47 UTC (rev 26143)
+++
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/EmfModelQuery.java 2010-10-29
15:44:15 UTC (rev 26144)
@@ -24,8 +24,10 @@
import org.eclipse.bpel.model.partnerlinktype.Role;
import org.eclipse.bpel.model.util.ImportResolver;
import org.eclipse.bpel.model.util.ImportResolverRegistry;
+import org.eclipse.bpel.model.util.XSDComparer;
import org.eclipse.bpel.model.util.WSDLUtil;
import org.eclipse.bpel.model.util.XSDUtil;
+import org.eclipse.bpel.validator.factory.AdapterFactory;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
@@ -43,7 +45,6 @@
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
-import org.eclipse.xsd.impl.XSDNamedComponentImpl;
/**
*
@@ -60,7 +61,22 @@
public class EmfModelQuery {
static final String CONTEXT_MSG = "The EMF context object object cannot be
null";
+
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // we need an instance of this so we can get diagnostics for error reporting
+ XSDComparer xsdComparer;
+
+ public EmfModelQuery() {
+ xsdComparer = new XSDComparer();
+ // if debug mode is set in the builder, force XSD comparison
+ xsdComparer.setDebug(AdapterFactory.DEBUG);
+ }
+
+ public XSDComparer getXSDComparer() {
+ return xsdComparer;
+ }
+
/**
* @param eObj
* @param qname
@@ -498,16 +514,20 @@
* @param dst
* @return true if compatible, false if not.
*/
-
- public static boolean compatiblePartnerActivityMessages (EObject src, EObject dst) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // no longer static because of xsdComparer object
+ public boolean compatiblePartnerActivityMessages (EObject src, EObject dst) {
assertTrue(src != null, CONTEXT_MSG);
assertTrue(dst != null, CONTEXT_MSG);
//
https://jira.jboss.org/browse/JBIDE-7116
// quick exit
- if (src==dst)
- return true;
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // ...unless we're in debug mode!
+ if (AdapterFactory.DEBUG==false)
+ if (src==dst)
+ return true;
Message srcMsg = null;
Message dstMsg = null;
@@ -594,15 +614,17 @@
* @param dst the destination type
* @return if the types are compatible, false otherwise
*/
-
- public static boolean compatibleType(EObject src, EObject dst) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // no longer static because of xsdComparer object
+ public boolean compatibleType(EObject src, EObject dst) {
assertTrue(src != null, CONTEXT_MSG);
assertTrue(dst != null, CONTEXT_MSG);
//
https://jira.jboss.org/browse/JBIDE-7116
// quick exit
- if (src==dst)
- return true;
+ if (AdapterFactory.DEBUG==false)
+ if (src==dst)
+ return true;
Message srcMsg = null;
Message dstMsg = null;
@@ -649,9 +671,15 @@
if (srcType != null && dstType != null) {
//https://jira.jboss.org/browse/JBIDE-7116
- if (compatibleType(srcType, dstType)) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // use XSDComparer
+ if (xsdComparer.compare(srcType,dstType)) {
return true;
}
+
+ // construct a new comparer to prevent the original
+ // diagnostics from being cleared
+ XSDComparer comp = new XSDComparer();
// check if src is derived from dst.
// 1) src is NCName, dst is string --> compatible.
@@ -660,11 +688,11 @@
do {
// System.out.println("Checking: " + dstType + " against baseType:
" + baseType);
//
https://jira.jboss.org/browse/JBIDE-7116
- if (compatibleType(dstType, baseType)) {
+ if (comp.compare(baseType,dstType)) {
return true;
}
baseType = baseType.getBaseType();
- } while ( !compatibleType(baseType,baseType.getBaseType()) );
+ } while (baseType!=baseType.getBaseType());
return false;
}
@@ -684,12 +712,15 @@
//
https://jira.jboss.org/browse/JBIDE-7116
// new: compare contents of messages
- public static boolean compatibleType(Message src, Message dst) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // no longer static because of xsdComparer object
+ public boolean compatibleType(Message src, Message dst) {
assertTrue(src != null, CONTEXT_MSG);
assertTrue(dst != null, CONTEXT_MSG);
- if (src==dst)
- return true;
+ if (AdapterFactory.DEBUG==false)
+ if (src==dst)
+ return true;
if (!src.getQName().equals(dst.getQName()))
return false;
@@ -717,39 +748,45 @@
//
https://jira.jboss.org/browse/JBIDE-7116
// new: compare XSDElementDeclaractions
- public static boolean compatibleType(XSDElementDeclaration src, XSDElementDeclaration
dst) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // no longer static because of xsdComparer object
+ public boolean compatibleType(XSDElementDeclaration src, XSDElementDeclaration dst) {
assertTrue(src != null, CONTEXT_MSG);
assertTrue(dst != null, CONTEXT_MSG);
- if (src==dst)
- return true;
+ if (AdapterFactory.DEBUG==false)
+ if (src==dst)
+ return true;
- // TODO: currently just doing a rudimentary name-only compare
- // need to add XSD compare/diff when the eclipse MDT project builds one
- return XSDNamedComponentImpl.Comparator.getInstance().compare(src,dst) == 0;
+ return compatibleType(src.getTypeDefinition(),dst.getTypeDefinition());
}
//
https://jira.jboss.org/browse/JBIDE-7116
// new: compare XSDTypeDefinitions
- public static boolean compatibleType(XSDTypeDefinition src, XSDTypeDefinition dst) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // no longer static because of xsdComparer object
+ public boolean compatibleType(XSDTypeDefinition src, XSDTypeDefinition dst) {
assertTrue(src != null, CONTEXT_MSG);
assertTrue(dst != null, CONTEXT_MSG);
- if (src==dst)
- return true;
+ if (AdapterFactory.DEBUG==false)
+ if (src==dst)
+ return true;
- // rudimentary name-only compare
- return XSDNamedComponentImpl.Comparator.getInstance().compare(src,dst) == 0;
+ return xsdComparer.compare(src,dst);
}
//
https://jira.jboss.org/browse/JBIDE-7116
// new: compare PortTypes
- public static boolean compatibleType(PortType src, PortType dst) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // no longer static because of xsdComparer object
+ public boolean compatibleType(PortType src, PortType dst) {
assertTrue(src != null, CONTEXT_MSG);
assertTrue(dst != null, CONTEXT_MSG);
- if (src==dst)
- return true;
+ if (AdapterFactory.DEBUG==false)
+ if (src==dst)
+ return true;
// do portTypes have to be defined in the same WSDL?
// URI uri1 = src.eResource().getURI();
@@ -777,12 +814,15 @@
//
https://jira.jboss.org/browse/JBIDE-7116
// new: compare Operations
- public static boolean compatibleType(Operation src, Operation dst) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // no longer static because of xsdComparer object
+ public boolean compatibleType(Operation src, Operation dst) {
assertTrue(src != null, CONTEXT_MSG);
assertTrue(dst != null, CONTEXT_MSG);
- if (src==dst)
- return true;
+ if (AdapterFactory.DEBUG==false)
+ if (src==dst)
+ return true;
if (src.getName()==null || !src.getName().equals(dst.getName()))
return false;
Modified:
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/ModelQuery.java
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/ModelQuery.java 2010-10-29
15:01:47 UTC (rev 26143)
+++
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/ModelQuery.java 2010-10-29
15:44:15 UTC (rev 26144)
@@ -25,7 +25,6 @@
import org.eclipse.bpel.validator.model.UndefinedNode;
import org.eclipse.bpel.validator.model.XNotImplemented;
import org.eclipse.core.runtime.IAdapterManager;
-import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.wst.wsdl.WSDLElement;
@@ -47,6 +46,9 @@
* @author Michal Chmielewski (michal.chmielewski(a)oracle.com)
* @date Sep 21, 2006
*
+ *
https://jira.jboss.org/browse/JBIDE-7351
+ * EMFModelQuery is no longer static because of XSDComparer object
+ * for fetching diagnostics of comparison
*/
@SuppressWarnings("nls")
@@ -137,20 +139,20 @@
case TEST_COMPATIBLE_PARTNER_ACTIVITY_MESSAGE:
// n1 is source
// n2 is destination
- return EmfModelQuery.compatiblePartnerActivityMessages (
+ return emfModelQuery.compatiblePartnerActivityMessages (
adapt(n1,EObject.class,ADAPT_HINT_NONE),
adapt(n2,EObject.class,ADAPT_HINT_NONE) );
case TEST_COMPATIBLE_TYPE :
// n1 is the source
// n2 is the destination
- return EmfModelQuery.compatibleType ( adapt(n1,EObject.class,ADAPT_HINT_NONE),
adapt(n2,EObject.class,ADAPT_HINT_NONE));
+ return emfModelQuery.compatibleType ( adapt(n1,EObject.class,ADAPT_HINT_NONE),
adapt(n2,EObject.class,ADAPT_HINT_NONE));
case TEST_IS_SIMPLE_TYPE :
if (n1 == null || n1.isResolved() == false) {
return false;
}
- return EmfModelQuery.isSimpleType ( adapt(n1,EObject.class,ADAPT_HINT_NONE) ) ;
+ return emfModelQuery.isSimpleType ( adapt(n1,EObject.class,ADAPT_HINT_NONE) ) ;
case TEST_RESOVLED :
if (n1 == null) {
@@ -276,7 +278,7 @@
case LOOKUP_NODE_IMPORT :
if (context.isResolved()) {
- eObj = EmfModelQuery.lookupImport(adapt(context,EObject.class,ADAPT_HINT_NONE), name
);
+ eObj = emfModelQuery.lookupImport(adapt(context,EObject.class,ADAPT_HINT_NONE), name
);
}
if (eObj == null) {
@@ -312,7 +314,7 @@
case LOOKUP_NODE_PARTNER_LINK_TYPE :
if ( context.isResolved() ) {
- eObj = EmfModelQuery.lookupPartnerLinkType (
adapt(context,EObject.class,ADAPT_HINT_NONE), qname );
+ eObj = emfModelQuery.lookupPartnerLinkType (
adapt(context,EObject.class,ADAPT_HINT_NONE), qname );
}
if (eObj == null) {
result = new UndefinedNode(IConstants.PLNK_ND_PARTNER_LINK_TYPE, IConstants.AT_NAME,
qname.getLocalPart() );
@@ -321,7 +323,7 @@
case LOOKUP_NODE_ROLE :
if ( context.isResolved() ) {
- eObj = EmfModelQuery.lookupRole ( adapt(context,EObject.class,ADAPT_HINT_NONE), name
) ;
+ eObj = emfModelQuery.lookupRole ( adapt(context,EObject.class,ADAPT_HINT_NONE), name
) ;
}
if (eObj == null) {
result = new UndefinedNode(IConstants.PLNK_ND_PARTNER_LINK_TYPE, IConstants.AT_NAME,
name );
@@ -330,7 +332,7 @@
case LOOKUP_NODE_OPERATION :
if ( context.isResolved()) {
- eObj = EmfModelQuery.lookupOperation ( adapt(context,EObject.class,ADAPT_HINT_NONE),
name );
+ eObj = emfModelQuery.lookupOperation ( adapt(context,EObject.class,ADAPT_HINT_NONE),
name );
}
if (eObj == null) {
result = new UndefinedNode ( IConstants.WSDL_ND_OPERATION, IConstants.AT_NAME, name
);
@@ -339,7 +341,7 @@
case LOOKUP_NODE_PORT_TYPE :
if ( context.isResolved() ) {
- eObj = EmfModelQuery.lookupPortType ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname) ;
+ eObj = emfModelQuery.lookupPortType ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname) ;
}
if (eObj == null) {
result = new UndefinedNode ( IConstants.WSDL_ND_PORT_TYPE, IConstants.AT_NAME,
qname.getLocalPart() );
@@ -348,7 +350,7 @@
case LOOKUP_NODE_MESSAGE_TYPE :
if ( context.isResolved() ) {
- eObj = EmfModelQuery.lookupMessage ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname) ;
+ eObj = emfModelQuery.lookupMessage ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname) ;
}
if (eObj == null) {
result = new UndefinedNode(IConstants.WSDL_ND_MESSAGE, IConstants.AT_NAME,
qname.getLocalPart() );
@@ -356,11 +358,11 @@
break;
case LOOKUP_NODE_MESSAGE_PART :
- return adapt(EmfModelQuery.lookupMessagePart (
adapt(context,EObject.class,ADAPT_HINT_NONE), name),INode.class,ADAPT_HINT_NONE );
+ return adapt(emfModelQuery.lookupMessagePart (
adapt(context,EObject.class,ADAPT_HINT_NONE), name),INode.class,ADAPT_HINT_NONE );
case LOOKUP_NODE_XSD_ELEMENT :
if ( context.isResolved() ) {
- eObj = EmfModelQuery.lookupXSDElement ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname);
+ eObj = emfModelQuery.lookupXSDElement ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname);
}
if (eObj == null) {
result = new UndefinedNode(IConstants.AT_ELEMENT,IConstants.AT_NAME,
qname.getLocalPart());
@@ -369,7 +371,7 @@
case LOOKUP_NODE_XSD_TYPE :
if (context.isResolved()) {
- eObj = EmfModelQuery.lookupXSDType ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname);
+ eObj = emfModelQuery.lookupXSDType ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname);
}
if (eObj == null) {
result = new UndefinedNode(IConstants.AT_TYPE,IConstants.AT_NAME,
qname.getLocalPart());
@@ -378,7 +380,7 @@
case LOOKUP_NODE_PROPERTY :
if (context.isResolved()) {
- eObj = EmfModelQuery.lookupProperty ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname );
+ eObj = emfModelQuery.lookupProperty ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname );
}
if (eObj == null) {
result = new UndefinedNode(IConstants.VPROP_ND_PROPERTY, IConstants.AT_NAME,
qname.getLocalPart());
@@ -387,7 +389,7 @@
case LOOKUP_NODE_NAME_STEP :
if (context.isResolved()) {
- eObj = EmfModelQuery.lookupNameStep( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname, 0 );
+ eObj = emfModelQuery.lookupNameStep( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname, 0 );
}
if (eObj == null) {
result = new
UndefinedNode(IConstants.AT_ELEMENT,IConstants.AT_NAME,qname.getLocalPart() );
@@ -396,7 +398,7 @@
case LOOKUP_NODE_NAME_STEP_ATTRIBUTE :
if (context.isResolved()) {
- eObj = EmfModelQuery.lookupNameStep( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname, 1 );
+ eObj = emfModelQuery.lookupNameStep( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname, 1 );
}
if (eObj == null) {
result = new
UndefinedNode(IConstants.AT_ELEMENT,IConstants.AT_NAME,qname.getLocalPart() );
@@ -405,7 +407,7 @@
case LOOKUP_NODE_TYPE_OF_PART :
if (context.isResolved()) {
- eObj = EmfModelQuery.lookupTypeOfPart ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname );
+ eObj = emfModelQuery.lookupTypeOfPart ( adapt(context,EObject.class,ADAPT_HINT_NONE),
qname );
}
if (eObj == null) {
result = new
UndefinedNode(IConstants.AT_ELEMENT,IConstants.AT_NAME,"Unknown");
Modified:
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/helpers/ModelQueryImpl.java
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/helpers/ModelQueryImpl.java 2010-10-29
15:01:47 UTC (rev 26143)
+++
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/helpers/ModelQueryImpl.java 2010-10-29
15:44:15 UTC (rev 26144)
@@ -19,6 +19,7 @@
import javax.xml.namespace.QName;
+import org.eclipse.bpel.validator.EmfModelQuery;
import org.eclipse.bpel.validator.model.Filters;
import org.eclipse.bpel.validator.model.IConstants;
import org.eclipse.bpel.validator.model.IFilter;
@@ -62,17 +63,34 @@
static final protected Selector mSelector = new Selector();
+ /**
+ *
https://jira.jboss.org/browse/JBIDE-7351
+ * Need an EmfModelQuery to contain the XSDComparer object so that
+ * we can grab diagnostics from it after a failed XSD compare (used
+ * for error reporting!)
+ */
+ protected EmfModelQuery emfModelQuery;
+
/**
* Protected constructor, just to initialize the basics the basics.
*
*/
public ModelQueryImpl () {
-
+ emfModelQuery = new EmfModelQuery();
}
-
+
/**
+ * Return error message from XSDComparer if assignments are incompatible
+ *
+ *
https://jira.jboss.org/browse/JBIDE-7351
+ */
+ public String getDiagnostic(int index)
+ {
+ return emfModelQuery.getXSDComparer().getDiagnostic(index);
+ }
+ /**
* Return an answer that decides whether the model has support for
* the given aspects that the validator wants.
* @param item
Modified:
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/model/IModelQuery.java
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/model/IModelQuery.java 2010-10-29
15:01:47 UTC (rev 26143)
+++
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/model/IModelQuery.java 2010-10-29
15:44:15 UTC (rev 26144)
@@ -23,8 +23,14 @@
public interface IModelQuery extends IModelQueryLookups {
-
/**
+ * Return error message from XSDComparer if assignments are incompatible
+ *
+ *
https://jira.jboss.org/browse/JBIDE-7351
+ */
+ public String getDiagnostic(int index);
+
+ /**
* Answer the priority with which this implementation of ModelQuery ought to
* be called with.
*
Modified:
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/model/Validator.java
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/model/Validator.java 2010-10-29
15:01:47 UTC (rev 26143)
+++
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/model/Validator.java 2010-10-29
15:44:15 UTC (rev 26144)
@@ -605,8 +605,9 @@
* @param node
* @return true if defined, false otherwise
*/
-
- protected boolean isDefined ( INode node ) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // no longer static because of XSDComparer in EmfModelQuery
+ protected static boolean isDefined ( INode node ) {
return node != null && node.isResolved();
}
@@ -617,8 +618,9 @@
* @param node
* @return true of undefined, false if defined.
*/
-
- protected boolean isUndefined ( INode node ) {
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // no longer static because of XSDComparer in EmfModelQuery
+ protected static boolean isUndefined ( INode node ) {
return node == null || node.isResolved() == false;
}
Modified:
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/rules/CValidator.java
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/rules/CValidator.java 2010-10-29
15:01:47 UTC (rev 26143)
+++
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/rules/CValidator.java 2010-10-29
15:44:15 UTC (rev 26144)
@@ -341,16 +341,17 @@
} else if (bCompatible == false) {
-
+ //
https://jira.jboss.org/browse/JBIDE-7351
+ // added diagnostic message for easier location of the incompatibility
problem = createError();
problem.fill("BPELC_COPY__INCOMPATIBLE",
toString(mNode.nodeName()),
"text.term.from",
fromTypeNode,
"text.term.to",
- toTypeNode
+ toTypeNode,
+ mModelQuery.getDiagnostic(0)
);
-
}
}
Modified:
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/rules/messages.properties
===================================================================
---
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/rules/messages.properties 2010-10-29
15:01:47 UTC (rev 26143)
+++
trunk/bpel/plugins/org.eclipse.bpel.validator/src/org/eclipse/bpel/validator/rules/messages.properties 2010-10-29
15:44:15 UTC (rev 26144)
@@ -856,8 +856,10 @@
# {3}: RHS (from spec)
# {4}: its type
BPELC_COPY__INCOMPATIBLE.summary = Incompatible types of {1} and {3}.
+#
https://jira.jboss.org/browse/JBIDE-7351
+# added {5} for diagnostics from XSDComparer
BPELC_COPY__INCOMPATIBLE = The {1} of "{2}" is not \
- compatible with {3} of "{4}"
+ compatible with {3} of "{4}" - {5}
BPELC_COPY__INCOMPATIBLE.fix = Types must be compatible.
#
# ---