001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.core.text.toc;
011:
012: import java.io.Serializable;
013: import java.util.ArrayList;
014: import java.util.List;
015:
016: import org.eclipse.pde.core.IModel;
017: import org.eclipse.pde.internal.core.itoc.ITocConstants;
018: import org.eclipse.pde.internal.core.text.DocumentObject;
019: import org.eclipse.pde.internal.core.text.IDocumentElementNode;
020:
021: /**
022: * TocObject - All objects modeled in a Table of Contents subclass TocObject
023: * This class contains functionality common to all TOC elements.
024: */
025: public abstract class TocObject extends DocumentObject implements
026: ITocConstants, Serializable {
027:
028: /**
029: * Constructs the TocObject and initializes its attributes.
030: *
031: * @param model The model associated with this TocObject.
032: * @param parent The parent of this TocObject.
033: */
034: public TocObject(TocModel model, String tagName) {
035: super (model, tagName);
036: }
037:
038: protected String getAttributeIndent() {
039: return " "; //$NON-NLS-1$
040: }
041:
042: /**
043: * @return the children of the object or an empty List if none exist.
044: */
045: public List getChildren() { //Create a copy of the child list instead of
046: //returning the list itself. That way, our list
047: //of children cannot be altered from outside
048: ArrayList list = new ArrayList();
049:
050: // Add children of this topic
051: IDocumentElementNode[] childNodes = getChildNodes();
052: if (childNodes.length > 0) {
053: for (int i = 0; i < childNodes.length; ++i) {
054: if (childNodes[i] instanceof TocObject) {
055: list.add(childNodes[i]);
056: }
057: }
058: }
059:
060: return list;
061: }
062:
063: public boolean isLeafNode() {
064: return !canBeParent();
065: }
066:
067: /**
068: * @return true iff this TOC object is capable of containing children.
069: */
070: public abstract boolean canBeParent();
071:
072: /**
073: * @return the root TOC element that is an ancestor to this TocObject.
074: */
075: public TocModel getModel() {
076: final IModel sharedModel = getSharedModel();
077: if (sharedModel instanceof TocModel) {
078: return (TocModel) sharedModel;
079: }
080:
081: return null;
082: }
083:
084: /**
085: * @return the root TOC element that is an ancestor to this TocObject.
086: */
087: public Toc getToc() {
088: final TocModel model = getModel();
089:
090: if (model != null) {
091: return model.getToc();
092: }
093:
094: return null;
095: }
096:
097: /**
098: * @return the identifier for this TocObject.
099: */
100: public abstract String getName();
101:
102: /**
103: * @return the path to the resource associated with this TOC object
104: * or <code>null</code> if one does not exist.
105: */
106: public abstract String getPath();
107:
108: /**
109: * @return the parent of this TocObject, or <br />
110: * <code>null</code> if the TocObject has no parent.
111: */
112: public TocObject getParent() {
113: IDocumentElementNode parent = getParentNode();
114: return parent instanceof TocObject ? (TocObject) parent : null;
115: }
116:
117: /**
118: * Check if the object is a direct or indirect descendant
119: * of the object parameter.
120: *
121: * @param obj The TOC object to find in this object's ancestry
122: * @return true iff obj is an ancestor of this TOC object
123: */
124: public boolean descendsFrom(TocObject obj) {
125: if (this .equals(obj)) {
126: return true;
127: }
128:
129: if (getParent() != null && obj.canBeParent()) {
130: return getParent().descendsFrom(obj);
131: }
132:
133: return false;
134: }
135:
136: /**
137: * Get the concrete type of this TocObject.
138: */
139: public abstract int getType();
140:
141: /**
142: * @param tocObject the child used to locate a sibling
143: * @return the TocObject preceding the specified one
144: * in the list of children
145: */
146: public TocObject getPreviousSibling(TocObject tocObject) {
147: return (TocObject) getPreviousSibling(tocObject,
148: TocObject.class);
149: }
150:
151: /**
152: * @param tocObject the child used to locate a sibling
153: * @return the TocObject proceeding the specified one
154: * in the list of children
155: */
156: public TocObject getNextSibling(TocObject tocObject) {
157: return (TocObject) getNextSibling(tocObject, TocObject.class);
158: }
159:
160: /**
161: * @return true iff a child object can be removed
162: */
163: public boolean canBeRemoved() {
164: if (getType() == TYPE_TOC) { //Semantic Rule: The TOC root element can never be removed
165: return false;
166: }
167:
168: TocObject parent = getParent();
169: if (parent != null) {
170: if (parent.getType() == TYPE_TOC) { //Semantic Rule: The TOC root element must always
171: //have at least one child
172: return parent.getChildren().size() > 1;
173: }
174:
175: return true;
176: }
177:
178: return false;
179: }
180: }
|