blob: b15037cbdb63968ffebcbfa913bf81ec64eb6bd5 [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.dtd.core.internal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.swt.graphics.Image;
import org.eclipse.wst.dtd.core.internal.document.DTDModelImpl;
import org.eclipse.wst.dtd.core.internal.parser.DTDRegionTypes;
import org.eclipse.wst.dtd.core.internal.text.RegionIterator;
import org.eclipse.wst.sse.core.internal.model.FactoryRegistry;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
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.text.TextRegionListImpl;
import org.eclipse.wst.xml.core.internal.document.NodeContainer;
import org.w3c.dom.Node;
public abstract class DTDNode extends NodeContainer implements IndexedRegion {
// these are characteroffsets
protected DTDFile dtdFile;
// flat node that contains this node
protected IStructuredDocumentRegion flatNode;
protected TextRegionListImpl regions = new TextRegionListImpl();
protected TextRegionListImpl whitespace = new TextRegionListImpl();
public DTDNode(DTDFile dtdFile, IStructuredDocumentRegion flatNode) {
this.dtdFile = dtdFile;
this.flatNode = flatNode;
}
public void addRegion(ITextRegion region) {
/*
* if (startRegion == null) { startRegion = region; } endRegion =
* region;
*/
regions.add(region);
}
public void addWhitespaceRegion(ITextRegion region) {
whitespace.add(region);
}
public void beginRecording(Object requestor, String label) {
getDTDFile().getDTDModel().beginRecording(requestor, label);
}
public Node cloneNode(boolean deepest) {
return null;
}
public boolean contains(int testPosition) {
return containsRange(testPosition, testPosition);
}
public boolean containsRange(int start, int end) {
return getStartOffset() <= start && end <= getEndOffset();
}
public void delete(DTDNode child) {
beginRecording(this, DTDCoreMessages._UI_LABEL_DTD_NODE_DELETE); //$NON-NLS-1$
delete(this, child);
endRecording(this);
}
public void delete(Object requestor, DTDNode child) {
replaceText(requestor, child.getStartOffset(), child.getFullNodeLength(), ""); //$NON-NLS-1$
}
public void endRecording(Object requestor) {
getDTDFile().getDTDModel().endRecording(requestor);
}
public Object[] getChildren() {
return getChildrenList().toArray();
}
public List getChildrenList() {
Node child = getFirstChild();
if (child != null) {
List children = new ArrayList();
for (; child != null; child = child.getNextSibling()) {
children.add(child);
}
return children;
}
else {
return Collections.EMPTY_LIST;
}
}
public DTDNode getDeepestNode(int offset) {
if (contains(offset)) {
// now see if a child contains this offset
Object[] children = getChildren();
for (int i = 0; i < children.length; i++) {
DTDNode child = (DTDNode) children[i];
DTDNode deepest = child.getDeepestNode(offset);
if (deepest != null) {
return deepest;
}
} // end of for ()
return this;
}
return null;
}
public DTDNode getDeepestNode(int start, int end) {
if (containsRange(start, end)) {
// now see if a child contains this offset
Object[] children = getChildren();
for (int i = 0; i < children.length; i++) {
DTDNode child = (DTDNode) children[i];
DTDNode deepest = child.getDeepestNode(start, end);
if (deepest != null) {
return deepest;
}
} // end of for ()
return this;
}
return null;
}
public DTDFile getDTDFile() {
return dtdFile;
}
public int getEndOffset() {
return getStructuredDTDDocumentRegion().getEndOffset(getEndRegion());
}
public ITextRegion getEndRegion() {
return regions.get(regions.size() - 1);// endRegion;
}
/**
*/
public FactoryRegistry getFactoryRegistry() {
DTDModelImpl model = dtdFile.getDTDModel();
if (model != null) {
FactoryRegistry reg = model.getFactoryRegistry();
if (reg != null)
return reg;
}
return null;
}
public int getFullNodeLength() {
return getWhitespaceEndOffset() - getStartOffset();
}
public String getFullNodeText() {
String text = getNodeText();
if (whitespace.size() > 0) {
RegionIterator iter = new RegionIterator(whitespace);
while (iter.hasNext()) {
ITextRegion region = iter.next();
text += getStructuredDTDDocumentRegion().getText(region);
}
}
return text;
}
abstract public Image getImage();
public String getName() {
ITextRegion region = getNameRegion();
if (region != null) {
return getStructuredDTDDocumentRegion().getText(region);
}
return ""; //$NON-NLS-1$
}
public ITextRegion getNameRegion() {
RegionIterator iter = iterator();
while (iter.hasNext()) {
ITextRegion region = iter.next();
if (region.getType() == DTDRegionTypes.NAME) {
return region;
}
}
return null;
}
// return the first token containing the specified token type
public ITextRegion getNextRegion(RegionIterator iter, String type) {
while (iter.hasNext()) {
ITextRegion region = iter.next();
if (region.getType().equals(type)) {
return region;
}
}
return null;
}
public int getNodeLength() {
return getEndOffset() - getStartOffset();
}
public String getNodeName() {
return getName();
}
public String getNodeText() {
StringBuffer sb = new StringBuffer();
RegionIterator iter = iterator();
while (iter.hasNext()) {
ITextRegion region = iter.next();
sb.append(getStructuredDTDDocumentRegion().getText(region));
}
return sb.toString();
}
public short getNodeType() {
return -1;
}
public int getStartOffset() {
return getStructuredDTDDocumentRegion().getStartOffset(getStartRegion());
}
// private Region startRegion,endRegion;
public ITextRegion getStartRegion() {
return regions.get(0);
// return startRegion;
}
/**
* Get the value of flatNode.
*
* @return value of flatNode.
*
* ISSUE:named changed not to be confused with default access protected
* super class method, but should re-think if this is correct technique.
* Perhaps getFirstRegion?
*/
public IStructuredDocumentRegion getStructuredDTDDocumentRegion() {
return flatNode;
}
// return end offset including whitespace
// or just the end offset if there is no whitespace
public int getWhitespaceEndOffset() {
if (whitespace.size() > 0) {
ITextRegion region = whitespace.get(whitespace.size() - 1);
return getStructuredDTDDocumentRegion().getEndOffset(region);
}
return getEndOffset();
}
public boolean hasTrailingWhitespace() {
return whitespace.size() > 0;
}
public RegionIterator iterator() {
// System.out.println("create region iter " + this.getClass() + " with
// start , end = " + getStartOffset() + ", " +getEndOffset());
return new RegionIterator(regions);
}
public void replaceText(Object requestor, int start, int length, String newText) {
getDTDFile().getStructuredDocument().replaceText(requestor, start, length, newText);
}
public void resolveRegions() {
}
public void setName(Object requestor, String name) {
if (!getName().equals(name)) {
ITextRegion nameRegion = getNameRegion();
if (nameRegion != null) {
// nameToken.updateText(name);
getDTDFile().getDTDModel().getReferenceUpdater().nameAboutToChange(requestor, this, name);
replaceText(requestor, getStructuredDTDDocumentRegion().getStartOffset(nameRegion), nameRegion.getLength(), name);
}
}
}
public void setName(String name) {
beginRecording(this, DTDCoreMessages._UI_LABEL_DTD_NODE_NAME_CHG); //$NON-NLS-1$
setName(this, name);
endRecording(this);
}
/**
* Set the value of flatNode.
*
* @param v
* Value to assign to flatNode. ISSUE:named changed not to be
* confused with default access protected super class method,
* but should re-think if this is correct technique
*/
void setStructuredDTDDocumentRegion(IStructuredDocumentRegion v) {
this.flatNode = v;
}
// skips past next name token in the iterator
protected void skipPastName(RegionIterator iter) {
while (iter.hasNext()) {
ITextRegion currentRegion = iter.next();
if (currentRegion.getType() == DTDRegionTypes.NAME) {
break;
}
}
}
public boolean supports(java.lang.String feature, java.lang.String version) {
return false;
}
}