001: /*
002: * Copyright (C) 2001, 2002 Robert MacGrogan
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: *
019: * $Archive: SourceJammer$
020: * $FileName: ProjectNode.java$
021: * $FileID: 4441$
022: *
023: * Last change:
024: * $AuthorName: Rob MacGrogan$
025: * $Date: 4/23/03 5:17 PM$
026: * $Comment: Replaced GPL header with LGPL header.$
027: */
028:
029: package org.sourcejammer.project.controller;
030:
031: import org.sourcejammer.project.*;
032: import org.sourcejammer.util.AppConfig;
033: import org.sourcejammer.util.ConfigurationException;
034: import org.sourcejammer.util.BadMethodArgumentException;
035: import org.sourcejammer.project.model.FileAccessException;
036: import java.util.Vector;
037: import java.util.Enumeration;
038: import org.sourcejammer.server.security.SecurityException;
039: import java.util.Hashtable;
040:
041: /**
042: * Title: $FileName: ProjectNode.java$
043: * @version $VerNum: 5$
044: * @author $AuthorName: Rob MacGrogan$<br><br>
045: *
046: * $Description: $<br>
047: * $KeyWordsOff: $<br/><br/>
048: *
049: * Contains information about a Project, including the
050: * project's name, and links to it's parent and children.
051: */
052: public abstract class ProjectNode extends ControllerNode {
053:
054: Vector mvecRemovedChildren;
055: Hashtable mhshChildren;
056: Hashtable mhshChildrenByName;
057: Hashtable mhshNamesByChild;
058: String fullPath = null;
059:
060: long mlParentID = -1;
061:
062: private static final String INDEX_SEP = "$$$";
063:
064: public ProjectNode() {
065: mvecRemovedChildren = new Vector();
066: mhshChildren = new Hashtable();
067: mhshChildrenByName = new Hashtable();
068: mhshNamesByChild = new Hashtable();
069: lightweightView.setNodeType(AppConfig.NodeTypes.PROJECT);
070: }
071:
072: public void setParentID(long l, long key) {
073: checkKey(key);
074: mlParentID = l;
075: getLightweightView().setParentID(l);
076: }
077:
078: public long getParentID() {
079: return mlParentID;
080: }
081:
082: /**
083: * Returns an Enumeration for iterating through of all of the
084: * children (ProjectChild objects) of this ProjectNode.
085: *
086: * @return an Enumeration of the ProjectNode's children.
087: */
088: public Enumeration getChildrenInfo() {
089: return mhshChildren.elements();
090: }
091:
092: /**
093: * Adds a new child node to this ProjectNode.
094: *
095: * @param nd -- a new child . Must have a unique name.
096: * @exception NodeExistsException -- if this ProjectNode already has
097: * a child with the same name as child.getNodeName();
098: */
099: public void addChildNode(Node nd, long key)
100: throws NodeExistsException {
101: checkKey(key);
102: String sName = nd.getNodeName();
103: long lNodeID = nd.getUniqueID();
104: int iNodeType = -1;
105: if (nd instanceof ProjectNode) {
106: iNodeType = org.sourcejammer.util.AppConfig.NodeTypes.PROJECT;
107: } else if (nd instanceof FileNode) {
108: iNodeType = org.sourcejammer.util.AppConfig.NodeTypes.FILE;
109: } else {
110: throw new BadMethodArgumentException("Invalid node type.");
111: }
112: addChildNode(lNodeID, iNodeType, sName, key);
113: }
114:
115: public void addChildNode(long lChildID, int iChildNodeType,
116: String sChildName, long key) throws NodeExistsException {
117: checkKey(key);
118: if (mhshChildrenByName.get(sChildName) != null) {
119: throw new NodeExistsException(
120: "This project already contains a child node with the name: "
121: + sChildName + ".");
122: }
123:
124: ProjectChild child = new ProjectChild(lChildID, iChildNodeType,
125: sChildName);
126: String sUniqueIDIndexKey = buildChildIndexKey(lChildID,
127: iChildNodeType);
128: mhshChildren.put(sUniqueIDIndexKey, child);
129: mhshChildrenByName.put(sChildName, child);
130: mhshNamesByChild.put(sUniqueIDIndexKey, sChildName);
131: }
132:
133: /**
134: * Removes the child node with the specified name and
135: * adds it to removed children list.
136: *
137: * @param name -- name of the child node to be removed.
138: * @return the NodeInfo that is being removed.
139: * @exception NodeDoesNotExistException if the this does
140: * not have a child with the specified name.
141: */
142: public ProjectChild removeChildNode(String name, long key)
143: throws NodeDoesNotExistException {
144: return removeChildNode(name, key, true);
145: }
146:
147: /**
148: * Removes the child node with the specified name and
149: * adds it to removed children list if addToRemovedList is true.
150: *
151: * @param name -- name of the child node to be removed.
152: * @param addToRemovedList -- adds to removed list if true.
153: * @return the NodeInfo that is being removed.
154: * @exception NodeDoesNotExistException if the this does
155: * not have a child with the specified name.
156: */
157: public ProjectChild removeChildNode(String name, long key,
158: boolean addToRemovedList) throws NodeDoesNotExistException {
159: checkKey(key);
160: ProjectChild ndRemoved = null;
161: try {
162: ndRemoved = (ProjectChild) mhshChildrenByName.remove(name);
163: if (ndRemoved == null) {
164: throw new NodeDoesNotExistException(
165: "No node with name: " + name
166: + " in this project.");
167: }
168: String sUniqueIDIndexKey = buildChildIndexKey(ndRemoved
169: .getUniqueID(), ndRemoved.getNodeType());
170: mhshChildren.remove(sUniqueIDIndexKey);
171: mhshNamesByChild.remove(sUniqueIDIndexKey);
172: if (addToRemovedList) {
173: mvecRemovedChildren.add(ndRemoved);
174: }
175: } catch (ClassCastException ex) {
176: throw new ConfigurationException("The child node: " + name
177: + " could not be cast to a ProjectChild.", ex);
178: }
179: return ndRemoved;
180: }
181:
182: /**
183: * Restores the specified removed node using a new name as the node name.
184: */
185: public ProjectChild restoreRemovedChildNode(int index,
186: String newName, long key) throws NodeExistsException,
187: NodeDoesNotExistException, SecurityException {
188: checkKey(key);
189: ProjectChild ndRestored = (ProjectChild) mvecRemovedChildren
190: .get(index);
191: if (ndRestored == null) {
192: throw new NodeDoesNotExistException(
193: "No such removed node exists in this project.");
194: }
195:
196: if (mhshChildrenByName.get(newName) != null) {
197: throw new NodeExistsException(
198: "This project already contains a child node with the name: "
199: + newName + ".");
200: }
201:
202: String sUniqueIndex = buildChildIndexKey(ndRestored
203: .getUniqueID(), ndRestored.getNodeType());
204: mhshChildren.put(sUniqueIndex, ndRestored);
205: mhshChildrenByName.put(newName, ndRestored);
206: mhshNamesByChild.put(sUniqueIndex, newName);
207: mvecRemovedChildren.remove(index);
208: return ndRestored;
209: }
210:
211: /**
212: * Returns a Vector of removed Nodes.
213: */
214: public Vector getRemovedChildren() {
215: return mvecRemovedChildren;
216: }
217:
218: /**
219: * Sets removed children vector. Vector of ProjectChild objects.
220: */
221: public void setRemovedChildren(Vector vec) {
222: if (mvecRemovedChildren.size() > 0) {
223: throw new BadMethodArgumentException(
224: "Cannot set removed children vector when removed children already exist.");
225: }
226: mvecRemovedChildren = vec;
227: }
228:
229: /**
230: * Permanently delete a removed node from this cache and from
231: * the storage system.
232: */
233: public ProjectChild permanentlyDeleteRemovedChildNode(int index,
234: long key) throws NodeDoesNotExistException,
235: FileAccessException {
236: checkKey(key);
237: ProjectChild ndDeleted = (ProjectChild) mvecRemovedChildren
238: .remove(index);
239: if (ndDeleted == null) {
240: throw new NodeDoesNotExistException(
241: "No such removed node exists in this project.");
242: }
243: return ndDeleted;
244: }
245:
246: /**
247: * Returns the child node with the specified name.
248: *
249: * @param name -- name of the child node to be returned.
250: * @return the child node with the specified name.
251: * @exception NodeDoesNotExistException if the this does
252: * not have a child with the specified name.
253: */
254: public ProjectChild getChildNode(String name)
255: throws NodeDoesNotExistException {
256: ProjectChild ndChild = null;
257: try {
258: ndChild = (ProjectChild) mhshChildrenByName.get(name);
259: if (ndChild == null) {
260: throw new NodeDoesNotExistException(
261: "This project does not contain a child with the name: "
262: + name + ".");
263: }
264: } catch (ClassCastException ex) {
265: throw new ConfigurationException("The child node: " + name
266: + " could not be cast to a ProjectChild.", ex);
267: }
268: return ndChild;
269: }
270:
271: public ProjectChild getRemovedChildInfo(int index)
272: throws NodeDoesNotExistException {
273: ProjectChild removedChild = (ProjectChild) mvecRemovedChildren
274: .get(index);
275: if (removedChild == null) {
276: throw new NodeDoesNotExistException(
277: "There is not removed node with index of " + index
278: + " in this project.");
279: }
280: return removedChild;
281: }
282:
283: public void renameChild(long uniqueID, int nodeType,
284: String newName, long key) throws NodeExistsException {
285:
286: checkKey(key);
287: String sID = buildChildIndexKey(uniqueID, nodeType);
288: if (mhshChildrenByName.get(newName) != null) {
289: throw new NodeExistsException("Project # " + getUniqueID()
290: + " already contains a child node with the name "
291: + newName + ".");
292: }
293: String oldName = (String) mhshNamesByChild.remove(sID);
294: ProjectChild child = (ProjectChild) mhshChildrenByName
295: .remove(oldName);
296: mhshChildrenByName.put(newName, child);
297: mhshNamesByChild.put(sID, newName);
298: }
299:
300: public int childCount() {
301: return mhshChildren.size();
302: }
303:
304: private String buildChildIndexKey(long uniqueID, int nodeType) {
305: String sUniqueIDIndexKey = uniqueID + INDEX_SEP + nodeType;
306: return sUniqueIDIndexKey;
307: }
308:
309: /**
310: * Returns the fullPath.
311: * @return String
312: */
313: public String getFullPath() {
314: return fullPath;
315: }
316:
317: /**
318: * Sets the fullPath.
319: * @param fullPath The fullPath to set
320: */
321: public void setFullPath(String fullPath, long key)
322: throws SecurityException {
323: checkKey(key);
324: this.fullPath = fullPath;
325: }
326:
327: }
|