Package org.eclipse.wst.xml.core.internal.search.quickscan

Source Code of org.eclipse.wst.xml.core.internal.search.quickscan.XMLQuickScanContentHandler

/*******************************************************************************
* Copyright (c) 2004, 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
*******************************************************************************/

package org.eclipse.wst.xml.core.internal.search.quickscan;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

import org.eclipse.wst.common.core.search.document.ComponentDeclarationEntry;
import org.eclipse.wst.common.core.search.document.ComponentReferenceEntry;
import org.eclipse.wst.common.core.search.document.FileReferenceEntry;
import org.eclipse.wst.common.core.search.document.SearchDocument;
import org.eclipse.wst.common.core.search.pattern.QualifiedName;
import org.eclipse.wst.common.core.search.pattern.SearchPattern;
import org.eclipse.wst.xml.core.internal.search.XMLComponentDeclarationPattern;
import org.eclipse.wst.xml.core.internal.search.XMLComponentReferencePattern;
import org.eclipse.wst.xml.core.internal.search.impl.IXMLSearchConstants;
import org.eclipse.wst.xml.core.internal.search.matching.PatternMatcher;
import org.eclipse.wst.xml.core.internal.search.matching.SAXSearchElement;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
* This class is a SAX content handler, it should be recycled before scanning a file for the new SearchPattern.
*
*/
public class XMLQuickScanContentHandler extends DefaultHandler
{
  private Map namespaceMap = new HashMap(); // Map of string prefix keys and namespace
  private String targetNamespace = ""; //$NON-NLS-1$
 
  private SearchPattern pattern;
  private SearchDocument document;  // we'll add useful entries in the search document as we parsing
  private SAXSearchElement searchElement = new SAXSearchElement();

  private boolean hasMatch = false;
  private Stack currentPath = new Stack();
  private PatternMatcher matcher;
 
  public static final String XMLSCHEMA_NAMESPACE = "http://www.w3.org/2001/XMLSchema"; //$NON-NLS-1$
  public static final String WSDL_NAMESPACE = "http://schemas.xmlsoap.org/wsdl/"; //$NON-NLS-1$

 
  public XMLQuickScanContentHandler(PatternMatcher matcher, SearchPattern pattern) {
    super();
    this.pattern = pattern;
    this.matcher = matcher;
  }
 
  public XMLQuickScanContentHandler(SearchDocument document, PatternMatcher matcher, SearchPattern pattern) {
    super();
    this.pattern = pattern;
    this.matcher = matcher;
    this.document = document;
  }
 
  public XMLQuickScanContentHandler() {
    super();
  }

  public void startElement(String uri, String localName, String qName,
      Attributes attributes) throws SAXException
 
    // Search for targetNamespace if we haven't encountered it yet.
    if (targetNamespace.equals("")) //$NON-NLS-1$
    {
      int nAttributes = attributes.getLength();
      for (int i = 0; i < nAttributes; i++)
      {
        if ("targetNamespace".equals(attributes.getQName(i))) //$NON-NLS-1$
        {
          targetNamespace = attributes.getValue(i);
          break;
        }
      }
    }
   
    // collect link info
   
    // TODO This code should be refactored to delegate the responsibility to
    // detect links between files to the search providers/contributors.
    // The current code only handles the XSD and WSDL cases.
   
    if("import".equals(localName) && namespaceMatches(uri)){ //$NON-NLS-1$
      FileReferenceEntry documentEntry = new FileReferenceEntry();
      documentEntry.setCategory(IXMLSearchConstants.REF);
      documentEntry.setKey("import"); //$NON-NLS-1$
      String namespace = attributes.getValue("namespace"); //$NON-NLS-1$
      String location = attributes.getValue(getLocationAttributeName(uri)); //$NON-NLS-1$
      documentEntry.setPublicIdentifier(namespace);
      documentEntry.setRelativeFilePath(location);           
      document.putEntry(documentEntry);
    }
    if(("redefine".equals(localName)|| "include".equals(localName)) && //$NON-NLS-1$ //$NON-NLS-2$
        namespaceMatches(uri)){
      FileReferenceEntry documentEntry = new FileReferenceEntry();
      documentEntry.setCategory(IXMLSearchConstants.REF);
      documentEntry.setKey("include"); //$NON-NLS-1$
      String location = attributes.getValue(getLocationAttributeName(uri)); //$NON-NLS-1$
      documentEntry.setPublicIdentifier(uri);
      documentEntry.setRelativeFilePath(location);
      document.putEntry(documentEntry);
    }
   
   
        // issue (cs) you may want to try perf measurements to compate reusing the same
        // instance of a SAXSearchElement instead of newing one each time
    //XMLSearchPattern.SAXSearchElement searchElement = new XMLSearchPattern.SAXSearchElement();
    searchElement.setElementName(localName);
    searchElement.setElementNamespace(uri);
    searchElement.setAttributes(attributes);
    searchElement.setNamespaceMap(namespaceMap);
    searchElement.setTargetNamespace(targetNamespace);
    if (currentPath.size() > 0)
    {
      String parentName = (String)currentPath.peek();
      searchElement.setParentName(parentName);
    }     
 

    if(matcher != null){
      if(matcher.matches(pattern, searchElement)){
        hasMatch = true;
        if(pattern instanceof XMLComponentReferencePattern){
          ComponentReferenceEntry documentEntry = new ComponentReferenceEntry();
          documentEntry.setCategory(IXMLSearchConstants.COMPONENT_REF);
          QualifiedName name = new QualifiedName(uri, localName);
          documentEntry.setKey(name.toString());
          documentEntry.setName(name);
          document.putEntry(documentEntry);
        }
        else if(pattern instanceof XMLComponentDeclarationPattern){
          ComponentDeclarationEntry documentEntry = new ComponentDeclarationEntry();
          documentEntry.setCategory(IXMLSearchConstants.COMPONENT_DECL);
                    QualifiedName name = new QualifiedName(targetNamespace, attributes.getValue("name")); //$NON-NLS-1$
          QualifiedName metaName = new QualifiedName(uri, localName);                   
          documentEntry.setKey(name.toString());
                    documentEntry.setName(name);
          documentEntry.setMetaName(metaName);
          document.putEntry(documentEntry);
        }
      }
    }
    currentPath.push(localName); //$NON-NLS-1$   
  }

  private String getLocationAttributeName(String uri)
  {
    if (XMLSCHEMA_NAMESPACE.equals(uri))
    {
      return "schemaLocation";
    }
   
    else if (WSDL_NAMESPACE.equals(uri))
    {
      return "location";
    }
   
    return "";
  }

  private boolean namespaceMatches(String uri)
  {
    return XMLSCHEMA_NAMESPACE.equals(uri) ||
          WSDL_NAMESPACE.equals(uri);
  }
 
  public void endElement(String uri, String localName, String qName)
      throws SAXException
  {
    currentPath.pop();
  }

  /**
   * Callback for SAX parser
   *
   * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
   *      java.lang.String)
   */
  public void startPrefixMapping(String arg0, String arg1)
      throws SAXException
  {
    if (arg0 != null && arg0.length() > 0)
    {
      this.namespaceMap.put(arg0, arg1);
    }
  }

  public String getTargetNamespace() {
    return targetNamespace;
  }

  public void setTargetNamespace(String targetNamespace) {
    this.targetNamespace = targetNamespace;
  }

  public boolean hasMatch() {
    return hasMatch;
  }

 
}
TOP

Related Classes of org.eclipse.wst.xml.core.internal.search.quickscan.XMLQuickScanContentHandler

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.