Package org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl

Source Code of org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl.CMDocumentLoader

/*******************************************************************************
* Copyright (c) 2002, 2006 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.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.wst.sse.core.utils.StringUtils;
import org.eclipse.wst.xml.core.internal.Logger;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManager;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.IExternalSchemaLocationProvider;
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.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
*
*/
public class CMDocumentLoader
{                                          
  private final static boolean _trace = Boolean.valueOf(Platform.getDebugOption("org.eclipse.wst.xml.core/externalSchemaLocation")).booleanValue(); //$NON-NLS-1$
  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)
    {
      if (!checkExternalSchema())
        visitNode(document);  
    }

    //System.out.println("--- elapsed time (" + count + ") = " + (System.currentTimeMillis() - time));
  }

  protected boolean checkExternalSchema() {
    boolean externalSchemaLoaded = false;
    if (document instanceof IDOMDocument) {
      final String baseLocation = ((IDOMDocument) document).getModel().getBaseLocation();
      if (baseLocation == null)
        return false;
      final IPath basePath = new Path(baseLocation);
      IFile file = null;
      if (basePath.segmentCount() > 1) {
        file = ResourcesPlugin.getWorkspace().getRoot().getFile(basePath);
      }
      final URI uri = (file == null || !file.isAccessible()) ? new File(baseLocation).toURI() : file.getLocationURI();
      if (uri != null) {
        IExternalSchemaLocationProvider[] providers = ExternalSchemaLocationProviderRegistry.getInstance().getProviders();
        for (int i = 0; i < providers.length; i++) {
          long time = _trace ? System.currentTimeMillis(): 0;
          final Map locations = providers[i].getExternalSchemaLocation(uri);
          if (_trace) {
            long diff = System.currentTimeMillis() - time;
            if (diff > 250)
              Logger.log(Logger.INFO, "Schema location provider took [" + diff + "ms] for URI [" + uri + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
          }
          if (locations != null && !locations.isEmpty()) {
            // Use the externalSchemaLocation
            if (namespaceTable != null && namespaceTable.isNamespaceEncountered()) {
              final String location = locations.get(IExternalSchemaLocationProvider.SCHEMA_LOCATION).toString();
              if (location != null) {
                final String[] ids = StringUtils.asArray(location);
                // namespace : location pairs
                if (ids.length >= 2 && ids.length % 2 == 0) {
                  if (!externalSchemaLoaded)
                    cmDocumentManager.removeAllReferences();
                  for (int j = 0; j < ids.length; j+=2) {
                    handleGrammar(ids[j], ids[j + 1], "XSD"); //$NON-NLS-1$
                    externalSchemaLoaded = true;
                  }
                }
              }
            }
            else { // noNamespace
              handleGrammar(uri.toString(), locations.get(IExternalSchemaLocationProvider.NO_NAMESPACE_SCHEMA_LOCATION).toString(), "XSD"); //$NON-NLS-1$
              externalSchemaLoaded = true;
              break;
            }
          }
        }
      }
    }
    return externalSchemaLoaded;
  }

  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;
  }
}
TOP

Related Classes of org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl.CMDocumentLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.