blob: 2cdc7e751b9ae9a1101821d348c3f3764549572a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2004 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) {
// transform the requested offset to the "scale" that
// regions are stored in, which are all relative to the
// start point.
//int transformedOffset = offset - getStartOffset();
//
int length = getRegions().size();
for (int i = 0; i < length; i++) {
ITextRegion region = getRegions().get(i);
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(" 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$
}
if ((getStartOffset(region) <= offset) && (offset < getEndOffset(region))) {
result = region;
break;
}
}
}
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;
}
}