Package org.eclipse.jst.jsp.ui.internal.breakpointproviders

Source Code of org.eclipse.jst.jsp.ui.internal.breakpointproviders.AbstractBreakpointProvider

/*******************************************************************************
* Copyright (c) 2004, 2005 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.jst.jsp.ui.internal.breakpointproviders;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;
import org.eclipse.jst.jsp.core.internal.provisional.JSP12Namespace;
import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts;
import org.eclipse.ui.IEditorInput;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionCollection;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.ISourceEditingTextTools;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.breakpoint.IBreakpointProvider;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.contentmodel.CMNodeWrapper;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.eclipse.wst.xml.ui.internal.provisional.IDOMSourceEditingTextTools;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* Abstract breakpoint provider class which implements breakpoint provider
* interface.
*
* This is a temporary class for JavaBreakpointProvider and
* JavaScriptBreakpointProvider, and should be refactored to separate Java and
* JavaScript parts.
*/
public abstract class AbstractBreakpointProvider implements IBreakpointProvider {

  protected static final int END_OF_LINE = -1;
  protected static final int JAVA = 1;
  protected static final int JAVASCRIPT = 2;
  private static final String[] JAVASCRIPT_LANGUAGE_KEYS = new String[]{"javascript", "javascript1.0", "javascript1.1_3", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        "javascript1.2", "javascript1.3", "javascript1.4", "javascript1.5", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
        "javascript1.6", "jscript", "sashscript"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  private static final String JSP_DIRECTIVE_PAGE = "jsp:directive.page"; //$NON-NLS-1$

  protected static final int NO_VALID_CONTENT = -2;
  protected static final int UNSUPPORTED = 0;

  protected static boolean contains(String[] haystack, String needle) {
    for (int i = 0; i < haystack.length; i++) {
      if (haystack[i].equals(needle)) {
        return true;
      }
    }
    return false;
  }

  /*
   * Return the page language
   */
  protected static int getPageLanguage(Document doc) {
    if (doc == null)
      return UNSUPPORTED;

    NodeList pageDirectives = doc.getElementsByTagName(JSP_DIRECTIVE_PAGE);
    // Search for first language directive
    for (int i = 0; i < pageDirectives.getLength(); i++) {
      Node child = pageDirectives.item(i);
      Node languageAttr = child.getAttributes().getNamedItem("language"); //$NON-NLS-1$
      if (languageAttr != null) {
        String pageLanguage = languageAttr.getNodeValue();
        if (pageLanguage == null || pageLanguage.length() == 0)
          return UNSUPPORTED;
        pageLanguage = pageLanguage.toLowerCase();
        if (contains(JAVASCRIPT_LANGUAGE_KEYS, pageLanguage))
          return JAVASCRIPT;
        else if (pageLanguage.equals("java"))//$NON-NLS-1$
          return JAVA;
        else
          return UNSUPPORTED;
      }
    }
    return JAVA; // Java is default if no language directive
  }

  /*
   * Search the RegionContainer's regions looking for JSP content. If valid
   * content is found, return the position >= 0 If no valid content is
   * found, return NO_VALID_CONTENT. If a region starts after the line's
   * endOffset, return END_OF_LINE.
   */
  private static int getValidRegionPosition(IStructuredModel model, ITextRegionCollection regionContainer, int startOffset, int endOffset) {

    ITextRegionList regions = regionContainer.getRegions();
    for (int i = 0; i < regions.size(); i++) {
      ITextRegion region = regions.get(i);
      if (region instanceof ITextRegionCollection) {
        int validPosition = getValidRegionPosition(model, (ITextRegionCollection) region, startOffset, endOffset);
        if (validPosition == END_OF_LINE || validPosition >= 0)
          return validPosition;
      }
      else {
        // region must be at least partially on selected line
        if (regionContainer.getEndOffset(region) > startOffset) {

          int regionStartOffset = regionContainer.getStartOffset(region);
          // if region starts after line's endOffset, we're done
          // searching
          if (regionStartOffset > endOffset)
            return END_OF_LINE;

          // If region is JSP content, make sure the language is
          // Java not Javascript by
          // checking the content assist adapter's type.
          if (region.getType().equals(DOMJSPRegionContexts.JSP_CONTENT)) {
            // DWM: this logic is not incorrect ... given changes
            // to adapters, etc.
            // but probably don't need anything here, since both
            // Java and JavaScript
            // are supported in V5.

            // nsd_TODO: verify this!!!

            // INodeNotifier notifier =
            // (INodeNotifier)model.getNode(region.getStartOffset());
            // IAdapterFactory factory =
            // model.getFactoryRegistry().getFactoryFor(ContentAssistAdapter.class);
            // if(factory instanceof
            // HTMLContentAssistAdapterFactory) {
            // INodeAdapter adapter =
            // ((HTMLContentAssistAdapterFactory)factory).createAdapter(notifier,
            // region);
            // if(adapter != null && adapter instanceof
            // JSPJavaContentAssistAdapter)

            if (regionStartOffset > startOffset)
              return regionStartOffset;
            else
              return startOffset;
            // }
          }
          // a custom tag, jsp:useBean, getproperty or setproperty
          // statement is also a valid breakpoint location
          else if (region.getType().equals(DOMRegionContext.XML_TAG_NAME) && (isCustomTagRegion(model.getIndexedRegion(regionStartOffset)) || regionContainer.getText(region).equals(JSP12Namespace.ElementName.USEBEAN) || regionContainer.getText(region).equals(JSP12Namespace.ElementName.GETPROPERTY) || regionContainer.getText(region).equals(JSP12Namespace.ElementName.SETPROPERTY))) {

            if (regionStartOffset > startOffset)
              return regionStartOffset;
            else
              return startOffset;
          }
          else {
            // Defect #241090, the Text Nodes inside of JSP
            // scriptlets, expressions, and declarations are valid
            // breakpoint-able locations
            boolean isCodeNode = false;
            IndexedRegion node = model.getIndexedRegion(regionStartOffset);
            if (node != null && node instanceof Node) {
              Node domNode = (Node) node;
              Node root = domNode.getOwnerDocument().getDocumentElement();
              if (root != null && root.getNodeName().equals(JSP12Namespace.ElementName.ROOT) && domNode.getNodeType() == Node.TEXT_NODE && domNode.getParentNode() != null) {
                String parentName = domNode.getParentNode().getNodeName();
                isCodeNode = parentName.equals(JSP12Namespace.ElementName.SCRIPTLET) || parentName.equals(JSP12Namespace.ElementName.EXPRESSION) || parentName.equals(JSP12Namespace.ElementName.DECLARATION);
              }
            }
            if (isCodeNode) {
              if (regionStartOffset > startOffset)
                return regionStartOffset;
              else
                return startOffset;
            }
          }
        }
      }
    }
    return NO_VALID_CONTENT;
  }

  private static boolean isCustomTagRegion(IndexedRegion node) {

    if (node instanceof Element) {
      Element xmlElement = (Element) node;
      ModelQuery mq = ModelQueryUtil.getModelQuery(xmlElement.getOwnerDocument());
      CMElementDeclaration decl = mq.getCMElementDeclaration(xmlElement);
      if (decl instanceof CMNodeWrapper) {
        CMNode cmNode = ((CMNodeWrapper) decl).getOriginNode();
        return cmNode instanceof TLDElementDeclaration;
      }
    }
    return false;
  }

  private ISourceEditingTextTools fSourceEditingTextTools;


  protected IResource getEditorInputResource(IEditorInput input) {
    IResource resource = (IResource) input.getAdapter(IFile.class);
    if (resource == null) {
      resource = (IResource) input.getAdapter(IResource.class);
    }
    return resource;
  }

  public ISourceEditingTextTools getSourceEditingTextTools() {
    return fSourceEditingTextTools;
  }

  protected int getValidPosition(IDocument idoc, int lineNumber) {
    if (!(getSourceEditingTextTools() instanceof IDOMSourceEditingTextTools)) {
      return NO_VALID_CONTENT;
    }
    if (idoc == null)
      return NO_VALID_CONTENT;

    int startOffset, endOffset;
    try {
      startOffset = idoc.getLineOffset(lineNumber - 1);
      endOffset = idoc.getLineOffset(lineNumber) - 1;

      if (idoc == null)
        return NO_VALID_CONTENT;
      String lineText = idoc.get(startOffset, endOffset - startOffset).trim();

      // blank lines or lines with only an open or close brace or
      // scriptlet tag cannot have a breakpoint
      if (lineText.equals("") || lineText.equals("{") || //$NON-NLS-2$//$NON-NLS-1$
            lineText.equals("}") || lineText.equals("<%"))//$NON-NLS-2$//$NON-NLS-1$
        return NO_VALID_CONTENT;
    }
    catch (BadLocationException e) {
      return NO_VALID_CONTENT;
    }

    IStructuredDocumentRegion flatNode = ((IStructuredDocument) idoc).getRegionAtCharacterOffset(startOffset);
    // go through the node's regions looking for JSP content
    // until reaching the end of the line
    while (flatNode != null) {
      int validPosition = getValidRegionPosition(((IDOMDocument) ((IDOMSourceEditingTextTools) getSourceEditingTextTools()).getDOMDocument()).getModel(), flatNode, startOffset, endOffset);

      if (validPosition == END_OF_LINE)
        return NO_VALID_CONTENT;

      if (validPosition >= 0)
        return validPosition;

      flatNode = flatNode.getNext();
    }
    return NO_VALID_CONTENT;
  }

  public void setSourceEditingTextTools(ISourceEditingTextTools sourceEditingTextTools) {
    fSourceEditingTextTools = sourceEditingTextTools;
  }
}
TOP

Related Classes of org.eclipse.jst.jsp.ui.internal.breakpointproviders.AbstractBreakpointProvider

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.