blob: 29d93f35c6e4cefdbfff292242fb4e2ab2b46474 [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 Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Jens Lukowski/Innoopract - initial renaming/restructuring
*
*/
package org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl;
import java.util.Hashtable;
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.internal.modelqueryimpl.InferredGrammarFactory;
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.w3c.dom.Document;
import org.w3c.dom.Element;
/**
*
*/
public class InferredGrammarBuildingCMDocumentLoader extends CMDocumentLoader
{
protected CMElementDeclaration inferredCMElementDeclaration;
protected CMDocument inferredCMDocument;
protected InferredGrammarFactory inferredGrammarFactory;
protected Hashtable createdCMDocumentTable;
public InferredGrammarBuildingCMDocumentLoader(Document document, ModelQuery modelQuery)
{
this(document, modelQuery.getCMDocumentManager());
}
public InferredGrammarBuildingCMDocumentLoader(Document document, CMDocumentManager cmDocumentManager)
{
super(document, cmDocumentManager);
createdCMDocumentTable = new Hashtable();
inferredGrammarFactory = new InferredGrammarFactory();
}
public void loadCMDocuments()
{
//System.out.println("----------loadCMDocuments ------------");
if (inferredGrammarFactory != null)
{
//long time = System.currentTimeMillis();
super.loadCMDocuments();
//System.out.println("--- elapsed time (" + count + ") = " + (System.currentTimeMillis() - time));
//inferredGrammarFactory.debugPrint(createdCMDocumentTable.values());
}
}
public void handleElement(Element element)
{
CMElementDeclaration parentInferredCMElementDeclaration = inferredCMElementDeclaration;
if (inferredCMDocument == null)
{
String cacheKey = "inferred-document"; //$NON-NLS-1$
inferredCMDocument = inferredGrammarFactory.createCMDocument(""); //$NON-NLS-1$
cmDocumentManager.addCMDocument("", "", cacheKey, "DTD", inferredCMDocument); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
createdCMDocumentTable.put(cacheKey, inferredCMDocument);
}
inferredCMElementDeclaration = inferredGrammarFactory.createCMElementDeclaration(inferredCMDocument, element, false);
if (parentInferredCMElementDeclaration != null)
{
inferredGrammarFactory.createCMContent(inferredCMDocument, parentInferredCMElementDeclaration, inferredCMDocument, inferredCMElementDeclaration, false, null);
}
visitChildNodes(element);
// reset the 'current' state to inital values
inferredCMElementDeclaration = parentInferredCMElementDeclaration;
}
public void handleElementNS(Element element)
{
CMDocument parentInferredCMDocument = inferredCMDocument;
CMElementDeclaration parentInferredCMElementDeclaration = inferredCMElementDeclaration;
inferredCMDocument = null;
inferredCMElementDeclaration = null;
// by adding the element to the namespaceTable, handleGrammar() will get called for any schema references
if (element.getParentNode() != document)
{
namespaceTable.addElement(element);
}
String prefix = element.getPrefix();
String uri = namespaceTable.getURIForPrefix(prefix);
if (uri == null && element.getParentNode() == document)
{
// when this is the root element
// we need to add an implied "no namespace schema location"
uri = "ommitted-namespace"; //$NON-NLS-1$
namespaceTable.addNamespaceInfo(prefix, uri, ""); //$NON-NLS-1$
}
// here's where we update the inferred grammar if required
//
boolean createCMElementDeclaration = true;
boolean isLocal = (uri == null && prefix == null);
if (isLocal)
{
if (parentInferredCMDocument == null)
{
// this is a local element... and the parent is not inferred (e.g) it has a known grammar
// so we don't need to create an element declaration for this element
createCMElementDeclaration = false;
}
else
{
if (uri == null)
{
uri = "ommitted-namespace"; //$NON-NLS-1$
}
}
}
if (createCMElementDeclaration)
{
if (isLocal)
{
inferredCMDocument = parentInferredCMDocument;
inferredCMElementDeclaration = inferredGrammarFactory.createCMElementDeclaration(inferredCMDocument, element, true);
}
else
{
boolean createCMDocument = false;
String cacheKey = "inferred-document" + uri; //$NON-NLS-1$
inferredCMDocument = (CMDocument)createdCMDocumentTable.get(cacheKey);
if (inferredCMDocument == null)
{
// we don't have an inferred document for this uri yet... let's see of we need one
int status = cmDocumentManager.getCMDocumentStatus(uri);
if (status == CMDocumentCache.STATUS_NOT_LOADED || status == CMDocumentCache.STATUS_ERROR)
{
// the cache does not contain a 'proper' CMDocument for this uri
// so we need to create an inferred one
createCMDocument = true;
}
}
if (createCMDocument)
{
//System.out.println("encountered element {" + element.getNodeName() + "} ... creating inferred CMDocument for " + uri);
inferredCMDocument = inferredGrammarFactory.createCMDocument(uri);
cmDocumentManager.addCMDocument(uri, "", cacheKey, "XSD", inferredCMDocument); //$NON-NLS-1$ //$NON-NLS-2$
createdCMDocumentTable.put(cacheKey, inferredCMDocument);
}
if (inferredCMDocument != null)
{
inferredCMElementDeclaration = inferredGrammarFactory.createCMElementDeclaration(inferredCMDocument, element, false);
}
}
if (parentInferredCMElementDeclaration != null)
{
inferredGrammarFactory.createCMContent(parentInferredCMDocument, parentInferredCMElementDeclaration, inferredCMDocument, inferredCMElementDeclaration, isLocal, uri);
}
}
visitChildNodes(element);
// reset the 'current' state to inital values
inferredCMElementDeclaration = parentInferredCMElementDeclaration;
inferredCMDocument = parentInferredCMDocument;
}
}