Package org.cfeclipse.cfml.editors

Source Code of org.cfeclipse.cfml.editors.ICFDocument

/*
* Created on Apr 5, 2004
*
* The MIT License
* Copyright (c) 2004 Rob Rohan
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software
* is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.cfeclipse.cfml.editors;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

import org.cfeclipse.cfml.CFMLPlugin;
import org.cfeclipse.cfml.editors.contentassist.CFEContentAssistManager;
import org.cfeclipse.cfml.editors.contentassist.IAssistAttrValueContributor;
import org.cfeclipse.cfml.editors.contentassist.IAssistContributor;
import org.cfeclipse.cfml.editors.contentassist.IAssistTagContributor;
import org.cfeclipse.cfml.editors.partitioner.CFEPartition;
import org.cfeclipse.cfml.external.ExternalFile;
import org.cfeclipse.cfml.natures.CFENature;
import org.cfeclipse.cfml.natures.IContentAssistContributorNature;
import org.cfeclipse.cfml.parser.CFDocument;
import org.cfeclipse.cfml.parser.CFNodeList;
import org.cfeclipse.cfml.parser.CFParser;
import org.cfeclipse.cfml.parser.CommentParser;
import org.cfeclipse.cfml.parser.docitems.CfmlTagItem;
import org.cfeclipse.cfml.parser.docitems.DocItem;
import org.cfeclipse.cfml.preferences.ParserPreferenceConstants;
import org.cfeclipse.cfml.util.ResourceUtils;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;

/**
* <p>
* This is mostly just a wrapper document that holds the parser and is
* attached to a Document. So if you can get access to a document you
* can get to this and get the parser.
* </p>
* <p>
* If you have an IDocument you can perform the following to get an ICFDocument:
* </p>
* <pre>
* \/\/
* if(doc instanceof ICFDocument)
* {
*   ICFDocument cfDoc = (ICFDocument)doc;
*   ... perform operations ...
* </pre>
* <p>
* With an ICFDocument class you are able to access the parse result.
* </p>
* @author Rob
*/
public class ICFDocument extends Document implements ICFEFileDocument {

    /** The parser that was/is run over this document */
  protected CFParser docParser = null;
  /** The resource that this document is derived from. Required for the parser */
  protected IResource lastRes = null;
  /** Comment parser - parses the TODOs. Will one day be put into the CFParser */
  private CommentParser commentParser = new CommentParser();
  /** ?? */
  //private static Thread t;
  /** The parse result of the document. NB: can be null if there were errors */
  private CFDocument docStructure = null;
 
  /**
     * The private CAM for this document.
     * NB: Not used as it's a possible solution for per-project frameworks
     * (and therefore per-project CACors)
     */
    private CFEContentAssistManager docCAM;
 
    /** Represents the time at which the CAM was last refreshed */
    private Date lastCAMRefresh;
   
  public ICFDocument()
  {
    super();
    this.docCAM = null;
  }
 
  public ICFDocument(String content) {
    super();
    this.docCAM = null;
    this.set(content);
    // TODO Auto-generated constructor stub
  }

  /**
   * Gets the parser for this document.
   *
   * @return An instance of a parser.
   */
  public CFParser getParser()
  {
    return docParser;
  }
 
  /**
   * Calls the parser and runs it over this document.<br/>
   * It then calls the comment parser.
   *
   */
  public void parseDocument()
  {
    if(docParser != null)
    {
        IPreferenceStore prefStore = CFMLPlugin.getDefault().getPreferenceStore();
      docParser.setCFScriptParsing(prefStore.getBoolean(ParserPreferenceConstants.P_PARSE_DOCFSCRIPT));
      docParser.setReportErrors(prefStore.getBoolean(ParserPreferenceConstants.P_PARSE_REPORT_ERRORS));
      CFDocument parsed = docParser.parseDoc();
      if (parsed != null) {
        docStructure = parsed;
      }
     
      commentParser.ParseDocument(this,lastRes);
      commentParser.setTaskMarkers();
     
      if(docStructure == null)
        System.err.println(
          "ICFDocument::parseDocument() - Parse result is null!"
        );
    }
  }
 
  /**
   * Gets a tag object given a starting and ending position
   * @param startpos
   * @param endpos
   * @return
   */
  public DocItem getTagAt(int startpos, int endpos)
  {

      return getTagAt(startpos,endpos,false);
  }

 
  public void addPosition(String category, Position position) throws BadLocationException, BadPositionCategoryException  {
      if (category.startsWith("__content_types_category")) {
          //System.out.println("Adding position " + position.offset + ":" + Integer.toString(position.offset + position.length) + " " + ((CFEPartition)position).getType());
      }
      super.addPosition(category,position);
  }
 
  public void removePosition(String category, Position position) throws BadPositionCategoryException {
      if (category.startsWith("__content_types_category")
              && position instanceof CFEPartition) {
          //System.out.println("Removing position " + position.offset + ":" + Integer.toString(position.offset + position.length) + ((CFEPartition)position).getType());
      }
      if(position != null) {       
        super.removePosition(category,position);
      }
  }
 
  /**
   * Gets a tag object given a starting and ending position
   * @param startpos
   * @param endpos
   * @param includeClosingTags
   * @return
   */
  public DocItem getTagAt(int startpos, int endpos, boolean includeClosingTags)
  {
    //build the xpath
    String attrString = "[#startpos<=" + startpos + " and #endpos>=" + endpos + "]";
    //System.out.println(this.getClass() + " Finding the tag in the document" + attrString);
    CFDocument docRoot = getCFDocument();

    // there might be a parse error with the document itself, which nullifies this
    if(docRoot == null) {
      return null;
    }

    try {
      CFNodeList matchingNodes = docRoot.getDocumentRoot().selectNodes(
        "//*" + attrString
        ,includeClosingTags
      );
     
      //there should only be 0 or 1 nodes in any one position (unless it spans
      //more then one tag I suppose
      if(matchingNodes.size() > 0)
      {
        DocItem node = (DocItem)matchingNodes.get(0);
        if (node instanceof CfmlTagItem) {         
          return (CfmlTagItem)node;
        } else {
          // probably a comment, but we could use this for udder stuff too?
          return node;
         
        }
      }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
   
    return null;
  }
 
 
  //NEED to add a function which is getTagAt(int startpos)
 
 
  /**
   * Gets the tag name at the given position (i.e. include,set,module,etc)
   * @param startpos
   * @param endpos
   * @return
   */
  public String getTagNameAt(int startpos, int endpos)
  {
    //String str = null;
    DocItem cti = getTagAt(startpos, endpos);
   
    if(cti != null)
    {
      return cti.getName();
    }
   
    return null;
  }
 
  /**
   * Sets the resource that is associated with this document.<br/>
   * It also resets the parser for this document.
   *
   * @param newRes The resource that represents this document.
   */
  public void setParserResource(IResource newRes)
  {
      this.lastRes = newRes;
    if(docParser == null)
    {
      docParser = new CFParser(this, lastRes);
      IPreferenceStore prefStore = CFMLPlugin.getDefault().getPreferenceStore();
      docParser.setCFScriptParsing(prefStore.getBoolean(ParserPreferenceConstants.P_PARSE_DOCFSCRIPT));
    }
    else
    {
      docParser.parseDoc(this);
    }
  }
 
  /**
   * Retrieves the IResource that this document is based upon
   * @return the resource
   */
  public IResource getResource() {
    return this.lastRes;
  }
 
  /**
   * Sets the resource that is associated with this document.<br/>
   * It also resets the parser for this document.
   *
   * @param newRes The resource that represents this document.
   */
  public void setResource(IResource newRes)
  {
      this.setParserResource(newRes);
  }
 
  /**
   * Clears all of the markers (i.e. problem, todo, etc) that are associated
   * with this document.
   *
   */
 
  public void clearAllMarkers()
  {
     
    try
    {
       
      lastRes.deleteMarkers(
          IMarker.PROBLEM, true, IResource.DEPTH_ONE
        );
     

      lastRes.deleteMarkers(
              "org.cfeclipse.cfml.todomarker", true, IResource.DEPTH_ONE
        );
     

    }
    catch(CoreException ce)
    {
      ce.printStackTrace(System.err);
    }
    catch (Exception e) {
        //e.printStackTrace();
    }
  }
 
 
  /**
   * Gets the parse result of this document.
   * @return If not null, the parse result, if null there was a parse error.
   */
  public CFDocument getCFDocument()
  {
    return docStructure;
  }
 
  /**
   * Retrieves the Content Assist Manager (CAM) for this document. This is the
     * manager for the CACors that are associated with this document.
     *
     * The current implementation of this simply retrieves the CFE-global CAM
     * as project natures are not yet implemented. Once implemented this will work
     * in the default manner.
   *
   * @see org.cfeclipse.cfml.editors.ICFEFileDocument
   */
    public CFEContentAssistManager getContentAssistManager() {
     
        if (this.getResource() instanceof ExternalFile) {
            return CFMLPlugin.getDefault().getGlobalCAM();
        }
    if(this.lastRes == null)
        return CFMLPlugin.getDefault().getGlobalCAM();

    CFEContentAssistManager returnManager = null;
    //CFENature nature;       
   
    try {
        if(!ResourceUtils.hasNature(this.lastRes.getProject(),
            CFENature.NATURE_ID))
            return CFMLPlugin.getDefault().getGlobalCAM();
       
        //nature = (CFENature)lastRes.getProject().getNature(CFENature.NATURE_ID);
       
        //returnManager = nature.getNatureCAM();
        returnManager = getCAM();
    } catch(CoreException ex) {
        ex.printStackTrace();
       
    }
    return returnManager;
    }
   
    protected CFEContentAssistManager getCAM()
    {
     
        try {
            refreshCAM();
        }
        catch(CoreException ex)
        {
            ex.printStackTrace();
        }
        return this.docCAM;
    }
   
    /**
     * Recreates the document's CAM based upon the natures that provide content
     * assist.
     *
     * @param natureIter Iterator of a collection of IContentAssistContributorNature's
     */
    private void refreshCAMFromList(Iterator natureIter)
    {
        this.docCAM = new CFEContentAssistManager();
        while(natureIter.hasNext())
        {
            CFEContentAssistManager currManager = ((IContentAssistContributorNature)natureIter.next()).getNatureCAM();
      Iterator currIter = currManager.getTagAssistors().iterator();
      while (currIter.hasNext()) {
        this.docCAM.registerTagAssist((IAssistContributor) currIter.next());
      }

      currIter = currManager.getAttributeAssistors().iterator();
      while (currIter.hasNext())
        this.docCAM.registerAttributeAssist((IAssistTagContributor) currIter.next());

      currIter = currManager.getValueAssistors().iterator();
      while (currIter.hasNext())
        this.docCAM.registerValueAssist((IAssistAttrValueContributor) currIter.next());

      currIter = currManager.getRootAssistors().iterator();
            while(currIter.hasNext())
            {
                Object currRoot = currIter.next();
                if(currRoot instanceof IAssistContributor)
                    this.docCAM.registerRootAssist((IAssistContributor)currRoot);
                else if(currRoot instanceof IContentAssistProcessor)
                    this.docCAM.registerRootAssist((IContentAssistProcessor)currRoot);
            }
           
        }
    }
   
    private void refreshCAM() throws CoreException
    {
        if(this.docCAM == null)
        {
            this.docCAM = new CFEContentAssistManager();
            this.lastCAMRefresh = new Date(0)// Init last refresh date to the epoch
        }
        IProject project = this.lastRes.getProject();
        IProjectNature [] natures = ResourceUtils.getProjectNatures(project);
        ArrayList cacNatures = new ArrayList();
       
        boolean needUpdate = false;
       
        for(int i = 0; i < natures.length; i++)
        {
            if(!(natures[i] instanceof IContentAssistContributorNature))
                continue;
           
            IContentAssistContributorNature cacorNature = (IContentAssistContributorNature)natures[i];
           
            if(cacorNature.getLastUpdateDate().after(this.lastCAMRefresh))
            {
                needUpdate = true;
            }
            cacNatures.add(cacorNature);
        }
       
        if(needUpdate)
        {
            refreshCAMFromList(cacNatures.iterator());
        }
       
        this.lastCAMRefresh = new Date();
    }
   
    /**
     * Refreshes this document's CAM from the framework natures associated
     * with the project that this document belongs to.
     *
     * The idea is that each document has it's own CAM. Or perhaps a project
     * should have it's own CAM. Unsure at the moment. This is only a
     * possible solution.
     *
     * Basically when a framework nature is associated with a project it
     * also registers itself under the naturelist property of that project.
     * The naturelist property is simply a colon-separated list of project
     * natures (is there a way to get a list of natures associated with
     * a project?). From this list (or a proper method) it goes through
     * each asking them for their CACs that they provide (if any).
     *
     * Each CAC is added to the doc's CAM, ready for access by an editor.
     * I don't believe we can do it any other way if we wish to support
     * multiple frameworks within the same project. Though we could
     * perhaps implement a IProject or extend whatever Eclipse uses and
     * have the CAM stored in the project.
     *
     * Alternatively every time a nature is associated with a project
     * we index that along side the project. The plugin maintains the
     * CAM for each project and requests for the CAM work in a simliar
     * manner as the access to the global CAM at the moment.
     *
     */
/*   
    private void refreshCAM()
    {
        docCAM = new CFEContentAssistManager();
        try {
            IProject docPrj = this.getResource().getProject();
            QualifiedName name = new QualifiedName("org.cfeclipse.cfml.props", "naturelist");
            String frameworkNatures = docProj.getPersistentProperty(name);
            String frameworksNames [] = frameworkNatures.split(":");
            for(int fIndex = 0; fIndex < frameworksNames.length; fIndex++)
            {
                ICFEProjectNature fNature = (ICFEProjectNature)docProj.getNature(frameworksNames[fIndex]);
                if(fNature.getAttributeCAC() != null)
                    this.docCAM.registerAttributeAssist(fNature.getAttributeCAC());
                if(fNature.getTagCAC() != null)
                    this.docCAM.registerTagAssist(fNature.getTagCAC());
                if(fNature.getAttrValCAC() != null)
                    this.docCAM.registerValueAssist(fNature.getAttrValCAC());
            }
        }catch(CoreException ex)
        {
            ex.printStackTrace();
        }       
    }
*/   
}
TOP

Related Classes of org.cfeclipse.cfml.editors.ICFDocument

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.