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

Source Code of org.eclipse.wst.xml.core.internal.search.XMLSearchParticipant$DOMVisitor

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

import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.wst.common.core.search.SearchMatch;
import org.eclipse.wst.common.core.search.SearchParticipant;
import org.eclipse.wst.common.core.search.SearchRequestor;
import org.eclipse.wst.common.core.search.document.ComponentDeclarationEntry;
import org.eclipse.wst.common.core.search.document.Entry;
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.document.SearchDocumentSet;
import org.eclipse.wst.common.core.search.pattern.ComponentSearchPattern;
import org.eclipse.wst.common.core.search.pattern.FileReferencePattern;
import org.eclipse.wst.common.core.search.pattern.SearchPattern;
import org.eclipse.wst.common.core.search.scope.ContentTypeSearchScope;
import org.eclipse.wst.common.core.search.scope.SearchScope;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolver;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.search.impl.IXMLSearchConstants;
import org.eclipse.wst.xml.core.internal.search.impl.XMLSearchDocument;
import org.eclipse.wst.xml.core.internal.search.matching.PatternMatcher;
import org.eclipse.wst.xml.core.internal.search.matching.XMLSearchPatternMatcher;
import org.eclipse.wst.xml.core.internal.search.quickscan.XMLQuickScan;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
*
*/
public abstract class XMLSearchParticipant extends SearchParticipant {
 
  protected static final boolean debugPerf = "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.xml.core.internal.search/perf")); //$NON-NLS-1$ //$NON-NLS-2$

  public XMLSearchParticipant() {
    super();
  }

 
  /*
public  boolean initialize(SearchPattern pattern, String[] contentTypes){
   
      super.initialize(pattern, contentTypes);
    this.supportedContentTypes = contentTypes;
   
    if(pattern instanceof XMLComponentSearchPattern){
      return true;
    }
    return false;
  }*/

 

  public SearchDocument createSearchDocument(String documentPath) {

    return new XMLSearchDocument(documentPath, this);

  }

  public String getDescription() {
    return "XML search participant"; //$NON-NLS-1$
  }



  private void locateMatches(SearchPattern pattern, SearchDocument document,
      SearchRequestor requestor, Map searchOptions, IProgressMonitor monitor) {

        // TODO... utilize search options (that should get passed down via the SearchEngine)
        // to specify if accurate source coordinates are req'd if not, simply use the SAX results
        //
        if (pattern.getMatchRule() == SearchPattern.R_PATTERN_MATCH)
        {         
          IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(document.getPath()));
          // TODO.. don't assume the category is COMPONENT_DECL... handle any arbitarty category
          Entry[] entries = document.getEntries(IXMLSearchConstants.COMPONENT_DECL, null, 0);
          for (int i = 0; i < entries.length; i++)
          {
            // TODO.. don't assume this is just a component declaration entry           
            ComponentDeclarationEntry entry = (ComponentDeclarationEntry)entries[i];
            SearchMatch searchMatch = new SearchMatch(null, 0, 0, file);
            searchMatch.map.put("name", entry.getName()); //$NON-NLS-1$
            searchMatch.map.put("metaName", entry.getMetaName()); //$NON-NLS-1$
            try
            {
              requestor.acceptSearchMatch(searchMatch);
            }
            catch (Exception e)
            {             
            }
          } 
        }
        else
        if (document.getModel() instanceof IDOMModel) {
      IDOMModel domModel = (IDOMModel) document.getModel();
      IDOMElement contextNode = (IDOMElement) domModel.getDocument()
          .getDocumentElement();
      DOMVisitor visitor = new DOMVisitor(document.getPath(), pattern,
          requestor);
      visitor.visit(contextNode);
    }
        }
  }
 
  private PatternMatcher getAdapter(Object adaptableObject, Class adapterType) {
    if (PatternMatcher.class.equals(adapterType) &&
        (adaptableObject instanceof XMLSearchPattern ||
        adaptableObject instanceof XMLComponentSearchPattern) ) {
      return new XMLSearchPatternMatcher(this);
    }
    return null;
  }

  private class DOMVisitor {

    String path;
    SearchPattern pattern;
    SearchRequestor requestor;
    PatternMatcher matcher;

   
    protected DOMVisitor(String path, SearchPattern pattern,
        SearchRequestor requestor) {
      super();
      this.path = path;
      this.pattern = pattern;
     
      matcher = (PatternMatcher)pattern.getAdapter(PatternMatcher.class);
      if(matcher == null){
        matcher = getAdapter(pattern, PatternMatcher.class);
      }
      this.requestor = requestor;
    }

    private void visit(Node node) {
      if (node.getNodeType() == Node.ELEMENT_NODE) {
        match((Element)node);
        NodeList nodeList = node.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
          Node aNode = nodeList.item(i);
          visit(aNode);
        }
      }
    }

    private void match(Element node) {
      IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(
          new Path(path));
      if(matcher != null){
        matcher.locateMatches(pattern, file, node, requestor);
      }

     
    }

  }

  public SearchScope selectDocumentLocations(SearchPattern pattern, SearchScope scope, Map searchOptions, IProgressMonitor monitor) {
    /*
     * gate #1: reduce the scope to the files with the content type that
     * could be searched using this participant
     */
    String[] contentTypes = getSupportedContentTypes()
    if(contentTypes != null && contentTypes.length > 0){
      scope = new ContentTypeSearchScope(scope, contentTypes);
    }
    return super.selectDocumentLocations(pattern, scope, searchOptions, monitor);
  }
 
  public abstract ComponentSearchContributor getSearchContributor();


  public void beginSearching(SearchPattern pattern, Map searchOptions) {
   
    super.beginSearching(pattern, searchOptions);
    if(pattern instanceof XMLComponentDeclarationPattern){
      XMLComponentDeclarationPattern componentPattern = (XMLComponentDeclarationPattern)pattern;
      XMLSearchPattern childPattern = getSearchContributor().getDeclarationPattern(componentPattern.getMetaName());
      if(childPattern != null){
          childPattern.setSearchName(componentPattern.getName().getLocalName());
          childPattern.setSearchNamespace(componentPattern.getName().getNamespace());
             componentPattern.addChildren(this, new XMLSearchPattern[]{childPattern});
      }
     
    }
    else if(pattern instanceof XMLComponentReferencePattern){
      XMLComponentReferencePattern componentPattern = (XMLComponentReferencePattern)pattern;
      XMLSearchPattern[] childPatterns = getSearchContributor().getReferencesPatterns(componentPattern.getMetaName());
      for (int i = 0; i < childPatterns.length; i++) {
        XMLSearchPattern childPattern = childPatterns[i];
        childPattern.setSearchName(componentPattern.getName().getLocalName());
        childPattern.setSearchNamespace(componentPattern.getName().getNamespace());       
      }
      componentPattern.addChildren(this, childPatterns);
     
    }
  }
 
 
  /**
   * The intend of this method is to limit the search to the files that have content
   * which can be searched for the given pattern. It is called from
   * {@link #selectDocumentLocations(SearchPattern, SearchScope, IProgressMonitor)}
   *
   * @param pattern the search pattern that is searched for
   * @return content type's unique identifiers that could be searched for the given pattern.
   */
  public abstract String[] getSupportedContentTypes();

  public void populateSearchDocument(SearchDocument document, SearchPattern pattern)
  {
    PatternMatcher matcher = (PatternMatcher)pattern.getAdapter(PatternMatcher.class);
    if(matcher == null){
      matcher = getAdapter(pattern, PatternMatcher.class);
    }
    XMLQuickScan.populateSearchDocument(document, matcher, pattern);   
  }

  public void locateMatches(SearchDocumentSet documentSet, SearchPattern pattern, SearchScope scope, SearchRequestor requestor, Map searchOptions, IProgressMonitor monitor) throws CoreException
  {
    long time = System.currentTimeMillis();
   
    // TODO: use the file reference entries in the documents to reduce the scope to the referenced files only
    // SearchDocument[] documents = documentSet.getSearchDocuments(id);
               
        // check to see if the search pattern is qualified by a file location
        // if this is the case then we can use file scoping rules to prune the matches
        IFile targetFile = null;
        if (pattern instanceof ComponentSearchPattern)
        {
          ComponentSearchPattern componentSearchPattern = (ComponentSearchPattern)pattern;
          targetFile = componentSearchPattern.getFile();                                      
        }   
       
    // here we should have in scope only referenced files
    IFile[] files = scope.enclosingFiles()
    for (int i = 0; i < files.length; i++)
    {
      IFile file = files[i];
      String path = file.getLocation().toString();
      SearchDocument document = documentSet.getSearchDocument(path, id);
      if (document != null)
      {             
      Entry[] entries = document.getEntries(getSearchEntryCategory(pattern), null, 0);          
      if ((entries != null && entries.length > 0) || (searchOptions != null && searchOptions.get("searchDirtyContent") != null))
            {
              //for (int j = 0; j < entries.length; j++)
              //{
              //  Entry entry = entries[j];
                //System.out.println("entry " + entry.getCategory() + " " + entry.getKey() + " " + entry.getClass().getName());                
              //} 
             
              boolean isInScope = true;
              if (targetFile != null)
              {
                try
                {
                  isInScope = isLinked(documentSet, "file:///" + path, "file:///" + targetFile.getLocation().toString()); //$NON-NLS-1$ //$NON-NLS-2$
                  //if (path.endsWith("CancelSelection.wsdl")  && path.indexOf("clone1") != -1)
                  //{
                  //  fileReferenceTable.debug(qualifiedPath, 0, 5);
                  //}                  
                }
                catch (Exception e)
                {
                  e.printStackTrace();
                }
              }             
              if (isInScope)
              {
          this.locateMatches(pattern, document, requestor, searchOptions, monitor);
             
            }
      }
    }
   
   
    if (debugPerf)
    {
      System.out
          .println("" //$NON-NLS-1$
              + getDescription()
              + ": " + (System.currentTimeMillis() - time) + "ms for locateMatches"); //$NON-NLS-1$ //$NON-NLS-2$
    }

   
  }
   
    private boolean isLinked(SearchDocumentSet set, String source, String target)
    {
      return isLinked(set, source, target, new HashMap());
    }
   
    private boolean isLinked(SearchDocumentSet set, String source, String target, HashMap visited)
    {
      if (source.equals(target))
        return true;
     
      String fileProtocol = "file:///";             //$NON-NLS-1$
     
      // Fix for bug 204174 - Begin
      if(target.charAt(fileProtocol.length()) == '/'//$NON-NLS-1$
      {
          target = fileProtocol + target.substring(fileProtocol.length() + 1);
      }
      // Fix for bug 204174 - End
           
      if (source.startsWith(fileProtocol))
      {   
       
      SearchDocument document = set._tempGetSearchDocumetn(source.substring(fileProtocol.length()));     
      if (document != null)
      {       
        URIResolver uriResolver = URIResolverPlugin.createResolver();       
        Entry[] entries = document.getEntries(IXMLSearchConstants.REF, null, 0);
        String[] resolveEntry = new String[entries.length];       
        for (int j = 0; j < entries.length; j++)
        {
          Entry entry = entries[j];
          if (entry instanceof FileReferenceEntry)
          {
            FileReferenceEntry fileReferenceEntry = (FileReferenceEntry)entry;
            // TODO.. record an utilize the public id from the fileReferenceEntry
            //
            if (fileReferenceEntry.getRelativeFilePath() != null)
            { 
              String resolvedURI = uriResolver.resolve(source, null, fileReferenceEntry.getRelativeFilePath());
              resolveEntry[j] = resolvedURI;
              if (resolvedURI.equals(target))
              {
                return true;
              }            
            } 
          }
        }
        // now see if there's an indirect link from the source to the target
        // we keep track of the nodes we've already visited to avoid cycles
        if (visited.get(source) == null)
        {
          visited.put(source, Boolean.TRUE);
          for (int j = 0; j < entries.length; j++)
          {                    
            String resolvedURI = resolveEntry[j];
            if (resolvedURI != null && isLinked(set, resolveEntry[j], target, visited))               
              return true;           
          }   
        }                     
      }           
      }
      return false;
    }
   
  
   
  public static String getSearchEntryCategory(SearchPattern pattern){
    if(pattern instanceof XMLComponentDeclarationPattern){
      return IXMLSearchConstants.COMPONENT_DECL;
    }
    else if(pattern instanceof XMLComponentReferencePattern){
      return IXMLSearchConstants.COMPONENT_REF;
    }
    else if(pattern instanceof FileReferencePattern){
       return IXMLSearchConstants.COMPONENT_REF;
    }
    return null;
  }  
}
TOP

Related Classes of org.eclipse.wst.xml.core.internal.search.XMLSearchParticipant$DOMVisitor

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.