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

Source Code of org.eclipse.wst.xml.core.internal.parser.ContextRegionContainer

/*******************************************************************************
* Copyright (c) 2001, 2009 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.parser;



import org.eclipse.jface.text.BadLocationException;
import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentEvent;
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.ITextRegionContainer;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.core.internal.text.TextRegionListImpl;
import org.eclipse.wst.xml.core.internal.Logger;


public class ContextRegionContainer implements ITextRegionContainer {
  protected int length;
  protected ITextRegionCollection parent;
  protected ITextRegionList regions;
  protected int start;
  protected int textLength;
  protected String type;

  public ContextRegionContainer() {
    super();
    regions = new TextRegionListImpl();

  }

  /**
   * these "deep" parenting is not normal, but just in case.
   */
  private IStructuredDocument _getParentDocument() {
    // go up enough parents to get to document
    ITextRegionCollection parent = getParent();
    while (!(parent instanceof IStructuredDocumentRegion)) {
      // would be an error not to be container, but
      // won't check for it now
      parent = ((ITextRegionContainer) parent).getParent();
    }
    return ((IStructuredDocumentRegion) parent).getParentDocument();
  }


  public void adjust(int i) {

    start += i;
    // I erroneously added length and textLength
    // TODO: may want to rename this method to adjustStart
    //length += i;
    //textLength += i;

  }

  public void adjustLength(int i) {
    length += i;
  }

  public void adjustStart(int i) {
    start += i;
  }


  public void adjustTextLength(int i) {
    textLength += i;

  }

  public boolean containsOffset(int i) {

    return getStartOffset() <= i && i < getEndOffset();
  }

  public boolean containsOffset(ITextRegion containedRegion, int offset) {
    return getStartOffset(containedRegion) <= offset && offset < getEndOffset(containedRegion);
  }

  /**
   * This method is just to equate positions. clients may (will probably)
   * still need to make calls to equate regions, parent, etc.
   */
  public void equatePositions(ITextRegion region) {
    start = region.getStart();
    length = region.getLength();
    textLength = region.getTextLength();
  }

  public int getEnd() {
    return start + length;
  }

  public int getEndOffset() {
    // our startOffset take into account our parent, and our start
    return getStartOffset() + getLength();
  }

  public int getEndOffset(ITextRegion containedRegion) {
    return getStartOffset(containedRegion) + containedRegion.getLength();
  }

  public ITextRegion getFirstRegion() {
    return getRegions().get(0);
  }

  public String getFullText() {
    return getParent().getFullText(this);
  }

  public String getFullText(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion aRegion) {
    // Must be proxied here since aRegion should always be a child of
    // *this* container and indexed from
    // this container's offset
    return parent.getFullText().substring(start + aRegion.getStart(), start + aRegion.getEnd());
  }

  public ITextRegion getLastRegion() {
    return getRegions().get(getRegions().size() - 1);
  }

  public int getLength() {
    return length;
  }


  public int getNumberOfRegions() {
    return getRegions().size();
  }

  public ITextRegionCollection getParent() {
    return parent;
  }

  /**
   * The parameter offset refers to the overall offset in the document.
   */
  public ITextRegion getRegionAtCharacterOffset(int offset) {
    ITextRegion result = null;
    if (regions != null) {
      int thisStartOffset = getStartOffset();
      if (offset < thisStartOffset)
        return null;
      int thisEndOffset = getStartOffset() + getLength();
      if (offset > thisEndOffset)
        return null;
      // transform the requested offset to the "scale" that
      // regions are stored in, which are all relative to the
      // start point.
      //int transformedOffset = offset - getStartOffset();
      //
      ITextRegionList regions = getRegions();
      int length = regions.size();
      int low = 0;
      int high = length;
      int mid = 0;
      // Binary search for the region
      while (low < high) {
        mid = low + ((high - low) >> 1);
        ITextRegion region = regions.get(mid);
        if (org.eclipse.wst.sse.core.internal.util.Debug.debugStructuredDocument) {
          System.out.println("region(s) in IStructuredDocumentRegion::getRegionAtCharacterOffset: " + region); //$NON-NLS-1$
          System.out.println("       midpoint of search:" + mid); //$NON-NLS-1$
          System.out.println("       requested offset: " + offset); //$NON-NLS-1$
          //System.out.println(" transformedOffset: " +
          // transformedOffset); //$NON-NLS-1$
          System.out.println("       region start: " + region.getStart()); //$NON-NLS-1$
          System.out.println("       region end: " + region.getEnd()); //$NON-NLS-1$
          System.out.println("       region type: " + region.getType()); //$NON-NLS-1$
          System.out.println("       region class: " + region.getClass()); //$NON-NLS-1$

        }
        // Region is before this one
        if (offset < region.getStart() + thisStartOffset)
          high = mid;
        else if (offset > (region.getEnd() + thisStartOffset - 1))
          low = mid + 1;
        else
          return region;
      }
      return null;
    }
    return result;
  }

  public ITextRegionList getRegions() {
    return regions;
  }

  public int getStart() {
    return start;
  }

  public int getStartOffset() {
    return getParent().getStartOffset() + getStart();
  }

  public int getStartOffset(ITextRegion containedRegion) {
    // it is an error to pass null to this method
    // ISSUE: need better "spec" on error behavior:
    // for now will return zero as this will roughly
    // work for some cases (and avoid NPE).
    if (containedRegion == null) {
      return getStartOffset();
    }
    return getStartOffset() + containedRegion.getStart();
  }

  /**
   * same as getFullText for this region type ... do we need to take white
   * space off?
   */

  public String getText() {
    String result = null;
    try {
      IStructuredDocument parentDocument = _getParentDocument();
      result = parentDocument.get(start, length);
    } catch (BadLocationException e) {
      Logger.logException("program error: unreachable exception", e); //$NON-NLS-1$
    }
    return result;
  }

  public String getText(org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion aRegion) {
    // Must be proxied here since aRegion should always be a child of
    // *this* container and indexed from
    // this container's offset
    return parent.getText().substring(start + aRegion.getStart(), start + aRegion.getTextEnd());
  }

  public int getTextEnd() {
    return start + textLength;
  }

  public int getTextEndOffset() {
    ITextRegion region = regions.get(regions.size() - 1);
    // our startOffset take into account our parent, and our start
    // (pa) 10/4 changed to be based on text end
    //           it used to return incorrect value for embedded region containers
    //

    // TODO CRITICAL -- need to re-work this work around, so doesn't
    // depend on XMLRegionContext
    //    // this is a workaround for 226823///////////
    //    for (int i = regions.size() - 1; i >= 0 && region.getType() ==
    // XMLRegionContext.WHITE_SPACE; i--)
    //      region = (ITextRegion) regions.get(i);
    //    /////////////////////////////////////////////

    return getStartOffset() + region.getTextEnd();
  }

  public int getTextEndOffset(ITextRegion containedRegion) {
    int result = 0;
    if (regions != null) {
      int length = getRegions().size();
      for (int i = 0; i < length; i++) {
        ITextRegion region = getRegions().get(i);
        if (region == containedRegion) {
          result = getStartOffset(region) + region.getTextEnd();
          break;
        }
      }
    }
    return result;
  }

  public int getTextLength() {
    return textLength;
  }

  public String getType() {
    return type;
  }

  public void setLength(int i) {
    length = i;
  }

  public void setParent(ITextRegionCollection parentRegion) {
    parent = parentRegion;
  }

  public void setRegions(ITextRegionList containedRegions) {
    regions = containedRegions;
  }

  public void setStart(int i) {
    start = i;
  }

  public void setTextLength(int i) {
    textLength = i;
  }

  public void setType(String string) {
    type = string;
  }

  public String toString() {
    String className = getClass().getName();
    String shortClassName = className.substring(className.lastIndexOf(".") + 1); //$NON-NLS-1$
    String result = "Container!!! " + shortClassName + "--> " + getType() + ": " + getStart() + "-" + getTextEnd() + (getTextEnd() != getEnd() ? ("/" + getEnd()) : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
    return result;
  }

  public StructuredDocumentEvent updateRegion(Object requester, IStructuredDocumentRegion parent, String changes, int requestStart, int lengthToReplace) {
    org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent result = null;
    // FUTURE_TO_DO: need to implement region level parsing in
    // ITextRegionContainer::updateModel
    // never being called?
    return result;
  }

}
TOP

Related Classes of org.eclipse.wst.xml.core.internal.parser.ContextRegionContainer

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.