diff options
Diffstat (limited to 'bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/util/DOMContentBuilderImpl.java')
-rw-r--r-- | bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/util/DOMContentBuilderImpl.java | 636 |
1 files changed, 0 insertions, 636 deletions
diff --git a/bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/util/DOMContentBuilderImpl.java b/bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/util/DOMContentBuilderImpl.java deleted file mode 100644 index 290f6f5866..0000000000 --- a/bundles/org.eclipse.wst.xml.core/src-contentmodel/org/eclipse/wst/xml/core/internal/contentmodel/util/DOMContentBuilderImpl.java +++ /dev/null @@ -1,636 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2010 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Jens Lukowski/Innoopract - initial renaming/restructuring - * - *******************************************************************************/ -package org.eclipse.wst.xml.core.internal.contentmodel.util; - -import java.util.Hashtable; -import java.util.List; -import java.util.Stack; -import java.util.Vector; - -import org.eclipse.wst.xml.core.internal.contentmodel.CMAnyElement; -import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration; -import org.eclipse.wst.xml.core.internal.contentmodel.CMContent; -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.internal.util.CMDataTypeValueHelper; -import org.w3c.dom.Attr; -import org.w3c.dom.DOMImplementation; -import org.w3c.dom.Document; -import org.w3c.dom.DocumentType; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.ProcessingInstruction; -import org.w3c.dom.Text; - - -/** - * todo... common up this code with 'ContentBuilder' - */ -public class DOMContentBuilderImpl extends CMVisitor implements DOMContentBuilder { - protected int buildPolicy = BUILD_ALL_CONTENT; - protected Hashtable propertyTable = new Hashtable(); - - protected boolean alwaysVisit = false; - protected List resultList; - protected Document document; - protected Node currentParent; - protected Node topParent; - protected Vector visitedCMElementDeclarationList = new Vector(); - protected boolean attachNodesToParent = true; - protected NamespaceTable namespaceTable; - - protected List namespaceInfoList; - protected Element rootElement; // this is used only teporarily via - // createDefaultRootContent - protected ExternalCMDocumentSupport externalCMDocumentSupport; - - public boolean supressCreationOfDoctypeAndXMLDeclaration; - - protected CMDataTypeValueHelper valueHelper = new CMDataTypeValueHelper(); - - protected int numOfRepeatableElements = 1; - protected Stack cmGroupStack = new Stack(); - protected int depthLimit = -1; - - protected int domLevel; - private int originalBuildPolicy; - - public interface ExternalCMDocumentSupport { - public CMDocument getCMDocument(Element element, String uri); - } - - public void setExternalCMDocumentSupport(ExternalCMDocumentSupport externalCMDocumentSupport) { - this.externalCMDocumentSupport = externalCMDocumentSupport; - } - - public DOMContentBuilderImpl(Document document) { - this.document = document; - namespaceTable = new NamespaceTable(document); - } - - public void setBuildPolicy(int buildPolicy) { - this.buildPolicy = buildPolicy; - } - - public int getBuildPolicy() { - return buildPolicy; - } - - protected boolean buildAllContent(int policy) { - return (policy & BUILD_ALL_CONTENT) == BUILD_ALL_CONTENT; - } - - protected boolean buildOptionalElements(int policy) { - return (policy & BUILD_OPTIONAL_ELEMENTS) == BUILD_OPTIONAL_ELEMENTS; - } - - protected boolean buildOptionalAttributes(int policy) { - return (policy & BUILD_OPTIONAL_ATTRIBUTES) == BUILD_OPTIONAL_ATTRIBUTES; - } - - protected boolean buildFirstChoice(int policy) { - return (policy & BUILD_FIRST_CHOICE) == BUILD_FIRST_CHOICE; - } - - protected boolean buildTextNodes(int policy) { - return (policy & BUILD_TEXT_NODES) == BUILD_TEXT_NODES; - } - - protected boolean buildFirstSubstitution(int policy) { - return (policy & BUILD_FIRST_SUBSTITUTION) == BUILD_FIRST_SUBSTITUTION; - } - - public List getResult() { - return resultList; - } - - public void setProperty(String propertyName, Object value) { - propertyTable.put(propertyName, value); - } - - public Object getProperty(String propertyName) { - return propertyTable.get(propertyName); - } - - public void build(Node parent, CMNode child) { - resultList = new Vector(); - topParent = parent; - currentParent = parent; - if (parent instanceof Element) { - namespaceTable.addElementLineage((Element) parent); - } - attachNodesToParent = false; - alwaysVisit = true; - visitCMNode(child); - } - - public void createDefaultRootContent(CMDocument cmDocument, CMElementDeclaration rootCMElementDeclaration, List namespaceInfoList) throws Exception { - this.namespaceInfoList = namespaceInfoList; - createDefaultRootContent(cmDocument, rootCMElementDeclaration); - } - - public void createDefaultRootContent(CMDocument cmDocument, CMElementDeclaration rootCMElementDeclaration) throws Exception { - String grammarFileName = cmDocument.getNodeName(); - if (!supressCreationOfDoctypeAndXMLDeclaration) { - // TODO cs... investigate to see if this code path is ever used, - // doesn't seem to be - // for now I'm setting the encoding to UTF-8 just incase this code - // path is used somewhere - // - String piValue = "version=\"1.0\""; //$NON-NLS-1$ - String encoding = "UTF-8"; //$NON-NLS-1$ - piValue += " encoding=\"" + encoding + "\""; //$NON-NLS-1$ //$NON-NLS-2$ - ProcessingInstruction pi = document.createProcessingInstruction("xml", piValue); //$NON-NLS-1$ - document.appendChild(pi); - - // if we have a 'dtd' then add a DOCTYPE tag - // - if (grammarFileName != null && grammarFileName.endsWith("dtd")) //$NON-NLS-1$ - { - DOMImplementation domImpl = document.getImplementation(); - DocumentType documentType = domImpl.createDocumentType(rootCMElementDeclaration.getElementName(), grammarFileName, grammarFileName); - document.appendChild(documentType); - } - } - - // if we have a schema add an xsi:schemaLocation attribute - // - if (grammarFileName != null && grammarFileName.endsWith("xsd") && namespaceInfoList != null) //$NON-NLS-1$ - { - 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); - } - - public void createDefaultContent(Node parent, CMElementDeclaration ed) { - currentParent = parent; - alwaysVisit = true; - originalBuildPolicy = buildPolicy; - visitCMElementDeclaration(ed); - } - - public String computeName(CMNode cmNode, Node parent) { - String prefix = null; - return DOMNamespaceHelper.computeName(cmNode, parent, prefix, namespaceTable); - } - - // overide the following 'create' methods to control how nodes are created - // - protected Element createElement(CMElementDeclaration ed, String name, Node parent) { - return document.createElement(name); - } - - protected Attr createAttribute(CMAttributeDeclaration ad, String name, Node parent) { - return document.createAttribute(name); - } - - protected Text createTextNode(CMDataType dataType, String value, Node parent) { - return document.createTextNode(value); - } - - protected void handlePushParent(Element parent, CMElementDeclaration ed) { - domLevel++; - } - - protected void handlePopParent(Element element, CMElementDeclaration ed) { - domLevel--; - } - - // The range must be between 1 and 99. - public void setNumOfRepeatableElements(int i) { - numOfRepeatableElements = i; - } - - protected int getNumOfRepeatableElements() { - return numOfRepeatableElements; - } - - public void visitCMElementDeclaration(CMElementDeclaration ed) { - int forcedMin = (buildOptionalElements(buildPolicy) || alwaysVisit) ? 1 : 0; - int min = Math.max(ed.getMinOccur(), forcedMin); - - // Correct the min value if the element is contained in - // a group. - if (!cmGroupStack.isEmpty()) { - CMGroup group = (CMGroup) cmGroupStack.peek(); - int gmin = group.getMinOccur(); - if (gmin == 0) - if (buildOptionalElements(buildPolicy)) { - /* do nothing: min = min */ - } - else { - min = min * gmin; // min = 0 - } - else { - min = min * gmin; - } - } - - int max = Math.min(ed.getMaxOccur(), getNumOfRepeatableElements()); - if (max < min) - max = min; - - alwaysVisit = false; - - // Note - ed may not be abstract but has substitutionGroups - // involved. - if (buildFirstSubstitution(buildPolicy) || isAbstract(ed)) // leave - // this - // for - // backward - // compatibility - // for now - { - // Note - To change so that if ed is optional, we do not - // generate anything here. - ed = getSubstitution(ed); - - // Note - the returned ed may be an abstract element in - // which case the xml will be invalid. - } - - if (min > 0 && !visitedCMElementDeclarationList.contains(ed)) { - visitedCMElementDeclarationList.add(ed); - for (int i = 1; i <= max; i++) { - // create an Element for each - Element element = null; - if (rootElement != null) { - element = rootElement; - rootElement = null; - } - else { - element = createElement(ed, computeName(ed, currentParent), currentParent); - } - - // visit the children of the GrammarElement - Node oldParent = currentParent; - currentParent = element; - handlePushParent(element, ed); - - namespaceTable.addElement(element); - - boolean oldAttachNodesToParent = attachNodesToParent; - attachNodesToParent = true; - - // instead of calling super.visitCMElementDeclaration() - // we duplicate the code with some minor modifications - CMNamedNodeMap nodeMap = ed.getAttributes(); - int size = nodeMap.getLength(); - for (int j = 0; j < size; j++) { - visitCMNode(nodeMap.item(j)); - } - - CMContent content = ed.getContent(); - if (content != null) { - visitCMNode(content); - } - - if (ed.getContentType() == CMElementDeclaration.PCDATA) { - CMDataType dataType = ed.getDataType(); - if (dataType != null) { - visitCMDataType(dataType); - } - } - // end duplication - attachNodesToParent = oldAttachNodesToParent; - handlePopParent(element, ed); - currentParent = oldParent; - linkNode(element); - } - int size = visitedCMElementDeclarationList.size(); - visitedCMElementDeclarationList.remove(size - 1); - } - } - - - public void visitCMDataType(CMDataType dataType) { - Text text = null; - String value = null; - - // For backward compatibility: - // Previous code uses a property value but new one uses - // buildPolicy. - if (getProperty(PROPERTY_BUILD_BLANK_TEXT_NODES) != null && getProperty(PROPERTY_BUILD_BLANK_TEXT_NODES).equals("true")) //$NON-NLS-1$ - buildPolicy = buildPolicy ^ BUILD_TEXT_NODES; - - if (buildTextNodes(buildPolicy)) { - value = valueHelper.getValue(dataType); - if (value == null) { - if (currentParent != null && currentParent.getNodeType() == Node.ELEMENT_NODE) { - value = currentParent.getNodeName(); - } - else { - value = "pcdata"; //$NON-NLS-1$ - } - } - } - else { - value = ""; //$NON-NLS-1$ - } - text = createTextNode(dataType, value, currentParent); - linkNode(text); - } - - public void visitCMNode(CMNode node) { - if (depthLimit != -1) { - if (domLevel > depthLimit) { - buildPolicy = buildPolicy &= ~BUILD_OPTIONAL_ELEMENTS; - } else { - buildPolicy = originalBuildPolicy; - } - } - super.visitCMNode(node); - } - - public void visitCMGroup(CMGroup e) { - cmGroupStack.push(e); - - int forcedMin = (buildOptionalElements(buildPolicy) || 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(buildPolicy)) { - CMNode hintNode = null; - - // todo... the CMGroup should specify the hint... but it seems - // as though - // the Yamato guys are making the CMElement specify the hint. - // I do it that way for now until... we should fix this post - // GA - // - int listSize = visitedCMElementDeclarationList.size(); - if (listSize > 0) { - CMElementDeclaration ed = (CMElementDeclaration) visitedCMElementDeclarationList.get(listSize - 1); - Object contentHint = ed.getProperty("contentHint"); //$NON-NLS-1$ - if (contentHint instanceof CMNode) { - hintNode = (CMNode) contentHint; - } - } - - // see if this hint corresponds to a valid choice - // - CMNode cmNode = null; - - if (hintNode != null) { - CMNodeList nodeList = e.getChildNodes(); - int nodeListLength = nodeList.getLength(); - for (int j = 0; j < nodeListLength; j++) { - if (hintNode == nodeList.item(j)) { - cmNode = hintNode; - } - } - } - - // if no cmNode has been determined from the hint, just use - // the first choice - // - if (cmNode == null) { - CMNodeList nodeList = e.getChildNodes(); - if (nodeList.getLength() > 0) { - cmNode = nodeList.item(0); - } - } - - if (cmNode != null) { - // Bug 330260 - // Problem - Add child element also adds optional grand-child elements - // This assumes 'e' is a model group choice, case 1. However 'e' could be a model group definition, case 2, where the - // first child is a model group. In the first case (choice), the first child is an - // element. Upon visiting the element (visitCMElementDeclaration), the minOccurs of the - // choice is ALSO considered. If its minOccurs is 0, then the first element is not added as a child. - // However, in the second case (model group definition), the first child is a choice, but the multiplicity is [1,1], - // meaning, it is required. So the first element is then added as child, even though - // the model group definition reference is optional. (minOccurs is not checked in this method, visitCMGroup) - // Visit the node only if it is not a GROUP (model group). If it is an element, then visit it. - if (!(cmNode.getNodeType() == CMNode.GROUP && min > 0)) { - visitCMNode(cmNode); - } - } - } - else if (e.getOperator() == CMGroup.ALL // ALL - || e.getOperator() == CMGroup.SEQUENCE) // SEQUENCE - { - // visit all of the content - super.visitCMGroup(e); - } - } - - cmGroupStack.pop(); - } - - static int count = 0; - - public void visitCMAttributeDeclaration(CMAttributeDeclaration ad) { - if (alwaysVisit || buildOptionalAttributes(buildPolicy) || ad.getUsage() == CMAttributeDeclaration.REQUIRED) { - alwaysVisit = false; - String name = computeName(ad, currentParent); - String value = valueHelper.getValue(ad, namespaceTable); - Attr attr = createAttribute(ad, name, currentParent); - attr.setValue(value != null ? value : ""); //$NON-NLS-1$ - linkNode(attr); - } - } - - protected boolean isAbstract(CMNode ed) { - boolean result = false; - if (ed != null) { - Object value = ed.getProperty("Abstract"); //$NON-NLS-1$ - result = (value == Boolean.TRUE); - } - return result; - } - - protected CMElementDeclaration getSubstitution(CMElementDeclaration ed) { - CMElementDeclaration result = ed; - CMNodeList l = (CMNodeList) ed.getProperty("SubstitutionGroup"); //$NON-NLS-1$ - if (l != null) { - for (int i = 0; i < l.getLength(); i++) { - CMNode candidate = l.item(i); - if (!isAbstract(candidate) && (candidate instanceof CMElementDeclaration)) { - result = (CMElementDeclaration) candidate; - break; - } - } - } - return result; - } - - protected CMElementDeclaration getParentCMElementDeclaration() { - CMElementDeclaration ed = null; - int listSize = visitedCMElementDeclarationList.size(); - if (listSize > 0) { - ed = (CMElementDeclaration) visitedCMElementDeclarationList.get(listSize - 1); - } - return ed; - } - - public void visitCMAnyElement(CMAnyElement anyElement) { - // ingnore buildPolicy for ANY elements... only create elements if - // absolutely needed - // - int forcedMin = alwaysVisit ? 1 : 0; - int min = Math.max(anyElement.getMinOccur(), forcedMin); - alwaysVisit = false; - - String uri = anyElement.getNamespaceURI(); - String targetNSProperty = "http://org.eclipse.wst/cm/properties/targetNamespaceURI"; //$NON-NLS-1$ - CMDocument parentCMDocument = (CMDocument) anyElement.getProperty("CMDocument"); //$NON-NLS-1$ - CMElementDeclaration ed = null; - - // System.out.println("parentCMDocument = " + parentCMDocument); - // //$NON-NLS-1$ - if (parentCMDocument != null) { - if (uri == null || uri.startsWith("##") || uri.equals(parentCMDocument.getProperty(targetNSProperty))) //$NON-NLS-1$ - { - ed = getSuitableElement(getParentCMElementDeclaration(), parentCMDocument); - } - } - - - if (ed == null && externalCMDocumentSupport != null && uri != null && !uri.startsWith("##") && currentParent instanceof Element) //$NON-NLS-1$ - { - CMDocument externalCMDocument = externalCMDocumentSupport.getCMDocument((Element) currentParent, uri); - if (externalCMDocument != null) { - ed = getSuitableElement(null, externalCMDocument); - } - } - - for (int i = 1; i <= min; i++) { - if (ed != null) { - visitCMElementDeclaration(ed); - } - else { - Element element = document.createElement("ANY-ELEMENT"); //$NON-NLS-1$ - linkNode(element); - } - } - } - - protected CMElementDeclaration getSuitableElement(CMNamedNodeMap nameNodeMap) { - CMElementDeclaration result = null; - int size = nameNodeMap.getLength(); - for (int i = 0; i < size; i++) { - CMElementDeclaration candidate = (CMElementDeclaration) nameNodeMap.item(i); - if (!visitedCMElementDeclarationList.contains(candidate)) { - result = candidate; - break; - } - } - return result; - } - - protected CMElementDeclaration getSuitableElement(CMElementDeclaration ed, CMDocument cmDocument) { - CMElementDeclaration result = null; - - if (ed != null) { - result = getSuitableElement(ed.getLocalElements()); - } - - if (result == null && cmDocument != null) { - result = getSuitableElement(cmDocument.getElements()); - } - - return result; - } - - - public void linkNode(Node node) { - if (attachNodesToParent && currentParent != null) { - if (node.getNodeType() == Node.ATTRIBUTE_NODE) { - ((Element) currentParent).setAttributeNode((Attr) node); - } - else { - currentParent.appendChild(node); - } - } - else if (resultList != null) { - resultList.add(node); - } - } - - public static void testPopulateDocumentFromGrammarFile(Document document, String grammarFileName, String rootElementName, boolean hack) { - try { - CMDocument cmDocument = ContentModelManager.getInstance().createCMDocument(grammarFileName, null); - CMNamedNodeMap elementMap = cmDocument.getElements(); - CMElementDeclaration element = (CMElementDeclaration) elementMap.getNamedItem(rootElementName); - - DOMContentBuilderImpl contentBuilder = new DOMContentBuilderImpl(document); - contentBuilder.supressCreationOfDoctypeAndXMLDeclaration = hack; - contentBuilder.createDefaultRootContent(cmDocument, element); - - System.out.println(); - System.out.println("-----------------------------"); //$NON-NLS-1$ - DOMWriter writer = new DOMWriter(); - if (hack) { - writer.print(document, grammarFileName); - } - else { - writer.print(document); - } - System.out.println("-----------------------------"); //$NON-NLS-1$ - } - catch (Exception e) { - System.out.println("Error: " + e); //$NON-NLS-1$ - e.printStackTrace(); - } - } - - public void setOptionalElementDepthLimit(int depth) { - depthLimit = depth; - } - - - // test - // - /* - * public static void main(String arg[]) { if (arg.length >= 2) { try { - * CMDocumentFactoryRegistry.getInstance().registerCMDocumentBuilderWithClassName("org.eclipse.wst.xml.core.internal.contentmodel.mofimpl.CMDocumentBuilderImpl"); - * - * String grammarFileName = arg[0]; String rootElementName = arg[1]; - * - * Document document = - * (Document)Class.forName("org.apache.xerces.dom.DocumentImpl").newInstance(); - * testPopulateDocumentFromGrammarFile(document, grammarFileName, - * rootElementName, true); } catch (Exception e) { - * System.out.println("DOMContentBuilderImpl error"); e.printStackTrace(); } } - * else { System.out.println("Usage : java - * org.eclipse.wst.xml.util.DOMContentBuildingCMVisitor grammarFileName - * rootElementName"); } } - */ -} |