blob: 0763332f89cacaf9ab6e5ae8329e33e770394be1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2002 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.modelqueryimpl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManager;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDocumentCache;
import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceInfo;
import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceTable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
*
*/
public class CMDocumentLoader
{
protected Document document;
protected ModelQuery modelQuery;
protected CMDocumentManager cmDocumentManager;
protected boolean isInferredGrammarEnabled = true;
protected CMDocumentLoadingNamespaceTable namespaceTable;
protected int count = 0;
public CMDocumentLoader(Document document, ModelQuery modelQuery)
{
this(document, modelQuery.getCMDocumentManager());
}
public CMDocumentLoader(Document document, CMDocumentManager cmDocumentManager)
{
this.document = document;
this.cmDocumentManager = cmDocumentManager;
}
public void loadCMDocuments()
{
//System.out.println("----------loadCMDocuments ------------");
//long time = System.currentTimeMillis();
boolean walkDocument = false;
cmDocumentManager.removeAllReferences();
String[] doctypeInfo = XMLAssociationProvider.getDoctypeInfo(document);
if (doctypeInfo != null)
{
// load the doctype if required
walkDocument = handleGrammar(doctypeInfo[0], doctypeInfo[1], "DTD"); //$NON-NLS-1$
}
else
{
Element element = getRootElement(document);
if (element != null)
{
namespaceTable = new CMDocumentLoadingNamespaceTable(document);
namespaceTable.addElement(element);
if (namespaceTable.isNamespaceEncountered())
{
walkDocument = true;
//System.out.println("isNamespaceAware");
}
else
{
namespaceTable = null;
walkDocument = isInferredGrammarEnabled;
//System.out.println("is NOT namespaceAware");
}
}
}
if (walkDocument)
{
visitNode(document);
}
//System.out.println("--- elapsed time (" + count + ") = " + (System.currentTimeMillis() - time));
}
public boolean handleGrammar(String publicId, String systemId, String type)
{
boolean result = false;
int status = cmDocumentManager.getCMDocumentStatus(publicId);
if (status == CMDocumentCache.STATUS_NOT_LOADED)
{
cmDocumentManager.addCMDocumentReference(publicId, systemId, type);
}
else if (status == CMDocumentCache.STATUS_ERROR)
{
result = true;
}
return result;
}
public void handleElement(Element element)
{
visitChildNodes(element);
}
public void handleElementNS(Element element)
{
namespaceTable.addElement(element);
visitChildNodes(element);
}
public void visitNode(Node node)
{
int nodeType = node.getNodeType();
if (nodeType == Node.ELEMENT_NODE)
{
count++;
Element element = (Element)node;
if (namespaceTable == null)
{
handleElement(element);
}
else
{
handleElementNS(element);
}
}
else if (nodeType == Node.DOCUMENT_NODE)
{
visitChildNodes(node);
}
}
protected void visitChildNodes(Node node)
{
for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling())
{
visitNode(child);
}
}
protected class CMDocumentLoadingNamespaceTable extends NamespaceTable
{
protected List newNamespaceList;
public CMDocumentLoadingNamespaceTable(Document document)
{
super(document);
}
public void addElement(Element element)
{
newNamespaceList = null;
super.addElement(element);
if (newNamespaceList != null)
{
for (Iterator i = newNamespaceList.iterator(); i.hasNext(); )
{
NamespaceInfo info = (NamespaceInfo)i.next();
handleGrammar(info.uri, info.locationHint, "XSD"); //$NON-NLS-1$
}
}
}
protected void internalAddNamespaceInfo(String key, NamespaceInfo info)
{
super.internalAddNamespaceInfo(key, info);
if (newNamespaceList == null)
{
newNamespaceList = new ArrayList();
}
newNamespaceList.add(info);
}
}
protected Element getRootElement(Document document)
{
Element result = null;
NodeList nodeList = document.getChildNodes();
int nodeListLength = nodeList.getLength();
for (int i = 0 ; i < nodeListLength; i++)
{
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
result = (Element)node;
break;
}
}
return result;
}
}