001: /*
002: * $Header: /cvs/j3dfly/J3dFly/src/org/jdesktop/j3dfly/namecontrol/NameControl.java,v 1.2 2007/02/07 01:27:38 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is Java 3D(tm) Fly Through.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dfly.namecontrol;
019:
020: import java.util.Hashtable;
021: import java.util.Set;
022: import java.util.Map;
023: import java.util.LinkedList;
024: import java.util.Iterator;
025:
026: /**
027: * Provide storage and access for any named objects in the SceneGraph
028: *
029: * The object and scene names are case sensitive
030: *
031: * Object are also stored in by class lists, so you can retrieve all
032: * instances of Behavior for example
033: *
034: * @author Paul Byrne
035: * @version $Id: NameControl.java,v 1.2 2007/02/07 01:27:38 paulby Exp $
036: */
037: public class NameControl extends java.lang.Object {
038:
039: private static NameControl nameControl = new NameControl();
040: private Hashtable scenes = new Hashtable();
041: private Hashtable objectTable = null;
042: private LinkedList listeners = null;
043: private LinkedList behaviorList = new LinkedList();
044: private LinkedList environmentList = new LinkedList();
045: private LinkedList otherList = new LinkedList();
046:
047: private int uniqueID = 0;
048:
049: /** Creates new NameControl */
050: public NameControl() {
051: // For the moment search on object is always enabled.
052: // This makes storeByType function correctly for rename
053: objectTable = new Hashtable();
054: }
055:
056: /**
057: * Add a listener for NameUpdateEvents
058: */
059: public void addNameUpdateListener(NameUpdateListener listener) {
060: if (listeners == null)
061: listeners = new LinkedList();
062:
063: listeners.add(listener);
064: }
065:
066: /**
067: * Remove a listener
068: */
069: public void removeNameUpdateListener(NameUpdateListener listener) {
070: listeners.remove(listener);
071: }
072:
073: /**
074: * Notify all listeners of this event
075: */
076: private void notifyListeners(NameUpdateEvent evt) {
077: if (listeners == null)
078: return;
079:
080: Iterator it = listeners.iterator();
081: while (it.hasNext())
082: ((NameUpdateListener) it.next()).nameUpdate(evt);
083: }
084:
085: private void storeByType(String sceneName, String objectName,
086: Object obj) {
087:
088: ObjectName nameObj = new ObjectName(sceneName, objectName);
089:
090: if (obj instanceof javax.media.j3d.Behavior)
091: behaviorList.add(nameObj);
092: else if (obj instanceof javax.media.j3d.Light
093: || obj instanceof javax.media.j3d.Fog)
094: environmentList.add(nameObj);
095: else
096: otherList.add(nameObj);
097:
098: if (objectTable != null)
099: objectTable.put(obj, nameObj);
100: }
101:
102: private void removeFromType(String sceneName, String objectName,
103: Object obj) {
104: if (sceneName == null && objectName == null)
105: return;
106:
107: ObjectName nameObj = new ObjectName(sceneName, objectName);
108:
109: if (obj instanceof javax.media.j3d.Behavior) {
110: behaviorList.remove(nameObj);
111: } else if (obj instanceof javax.media.j3d.Light
112: || obj instanceof javax.media.j3d.Fog)
113: environmentList.remove(nameObj);
114: else
115: otherList.remove(nameObj);
116:
117: if (objectTable != null)
118: objectTable.remove(obj);
119: }
120:
121: /**
122: * Returns an iterator over a list of all the names of Behavior object.
123: *
124: * Each object in the list is of type ObjectName
125: */
126: public Iterator getBehaviorNames() {
127: return behaviorList.iterator();
128: }
129:
130: /**
131: * Returns an iterator over a list of all the names of Light and
132: * Fog object.
133: *
134: * Each object in the list is of type ObjectName
135: */
136: public Iterator getEnvironmentNames() {
137: return environmentList.iterator();
138: }
139:
140: /**
141: * Returns an iterator over a alist of all the names not in the Behavior list
142: *
143: * Each object in the list is of type ObjectName
144: */
145: public Iterator getOtherNames() {
146: return otherList.iterator();
147: }
148:
149: /**
150: * Add all the named objects in the hash table. The object references
151: * are copied so table can be discarded once this method returns.
152: *
153: * The names will be associated with the filename so different files
154: * can have the same object names and no conflicts will result
155: */
156: public void addObjectsFromFile(String sceneName, Hashtable table) {
157: scenes.put(sceneName, table.clone());
158:
159: Iterator it = table.entrySet().iterator();
160: while (it.hasNext()) {
161: java.util.Map.Entry obj = (java.util.Map.Entry) it.next();
162: storeByType(sceneName, (String) obj.getKey(), obj
163: .getValue());
164: }
165:
166: notifyListeners(new NameUpdateEvent(
167: NameUpdateEvent.SCENE_ADDED, sceneName, null));
168: }
169:
170: /**
171: * Add the named object to the specified scene's names
172: *
173: * Generates a NameUpdateEvent( OBJECT_ADDED )
174: */
175: public void addObject(String sceneName, String objectName,
176: Object obj) {
177: Hashtable table = (Hashtable) scenes.get(sceneName);
178:
179: if (table == null) {
180: table = new Hashtable();
181: scenes.put(sceneName, table);
182: } else {
183: Object test = table.get(objectName);
184: if (test != null)
185: throw new RuntimeException("Name is not unique "
186: + sceneName + ":" + objectName);
187: }
188: table.put(objectName, obj);
189:
190: storeByType(sceneName, objectName, obj);
191:
192: notifyListeners(new NameUpdateEvent(
193: NameUpdateEvent.OBJECT_ADDED, sceneName, objectName));
194:
195: }
196:
197: /**
198: * Renames the object, oldName and newName must not be null and
199: * sceneName:oldName must exist in the name database.
200: *
201: * Generates a NameUpdateEvent( NAME_CHANGED )
202: */
203: public void renameObject(String sceneName, String oldName,
204: String newName, Object obj) {
205: Hashtable table;
206: Object old;
207:
208: table = (Hashtable) scenes.get(sceneName);
209:
210: old = table.remove(oldName);
211: removeFromType(sceneName, oldName, obj);
212:
213: table.put(newName, obj);
214:
215: storeByType(sceneName, newName, obj);
216:
217: notifyListeners(new NameUpdateEvent(
218: NameUpdateEvent.NAME_CHANGED, sceneName, newName));
219: }
220:
221: /**
222: * Removes the objects name
223: *
224: * Generates a NameUpdateEvent( NAME_REMOVED )
225: */
226: public void removeObject(String sceneName, String name, Object obj) {
227: Hashtable table;
228:
229: table = (Hashtable) scenes.get(sceneName);
230:
231: if (table != null) {
232: table.remove(name);
233:
234: removeFromType(sceneName, name, obj);
235:
236: notifyListeners(new NameUpdateEvent(
237: NameUpdateEvent.NAME_REMOVED, sceneName, name));
238: }
239: }
240:
241: /**
242: * Returns true if the name pair does not already exist in the
243: * name database
244: */
245: public boolean isUnique(String sceneName, String nodeName) {
246: Hashtable table = (Hashtable) scenes.get(sceneName);
247:
248: if (table == null)
249: return true;
250:
251: Object obj = table.get(nodeName);
252:
253: if (obj == null)
254: return true;
255:
256: return false;
257: }
258:
259: /*
260: public static NameControl getNameControl() {
261: return nameControl;
262: }
263: */
264:
265: /**
266: * Return a list of the scene names
267: */
268: public String[] getSceneNames() {
269: String[] ret = new String[scenes.size()];
270:
271: return (String[]) scenes.keySet().toArray(ret);
272: }
273:
274: /**
275: * Return a list of the object names within the scene
276: */
277: public String[] getObjectNames(String sceneName) {
278: Hashtable table = (Hashtable) scenes.get(sceneName);
279:
280: String[] ret = new String[table.size()];
281: return (String[]) table.keySet().toArray(ret);
282: }
283:
284: /**
285: * Returns the named object
286: */
287: public Object getNamedObject(String sceneName, String objectName) {
288: Hashtable table = (Hashtable) scenes.get(sceneName);
289:
290: if (table == null)
291: return null;
292:
293: return table.get(objectName);
294: }
295:
296: /**
297: * Returns the named object
298: */
299: public Object getNamedObject(ObjectName name) {
300: return getNamedObject(name.sceneName, name.objectName);
301: }
302:
303: /**
304: * Enable Searching of object name from Object
305: */
306: public void enableSearchOnObject(boolean enable) {
307: if (enable)
308: buildObjectTable();
309: else {
310: objectTable.clear();
311: objectTable = null;
312: }
313: }
314:
315: private void buildObjectTable() {
316: if (objectTable != null)
317: return;
318:
319: objectTable = new Hashtable();
320:
321: Set sceneSet = scenes.entrySet();
322: Iterator sceneIt = sceneSet.iterator();
323: while (sceneIt.hasNext()) {
324: Map.Entry sceneEntry = (Map.Entry) sceneIt.next();
325: Set graphSet = ((Hashtable) sceneEntry.getValue())
326: .entrySet();
327: String sceneName = (String) sceneEntry.getKey();
328: Iterator graphIt = graphSet.iterator();
329: while (graphIt.hasNext()) {
330: Map.Entry graphEntry = (Map.Entry) graphIt.next();
331: objectTable.put(graphEntry.getValue(), new ObjectName(
332: sceneName, (String) graphEntry.getKey()));
333: }
334: }
335: }
336:
337: /**
338: * Get the name of this object
339: */
340: public ObjectName getObjectName(Object obj) {
341: if (objectTable != null)
342: return (ObjectName) objectTable.get(obj);
343: else
344: throw new RuntimeException(
345: "Search for ObjectName is not enabled");
346: }
347:
348: /**
349: * Return a uniqueID that can be appended to a name to
350: * make it unique
351: */
352: public int getUniqueID() {
353: return uniqueID++;
354: }
355:
356: public class ObjectName {
357: public String sceneName;
358: public String objectName;
359:
360: public ObjectName(String sceneName, String objectName) {
361: this .sceneName = sceneName;
362: this .objectName = objectName;
363: }
364:
365: public String toString() {
366: return sceneName + ":" + objectName;
367: }
368:
369: public boolean equals(Object obj) {
370: if (!(obj instanceof ObjectName)) {
371: return false;
372: }
373:
374: return ((ObjectName) obj).sceneName.equals(sceneName)
375: & ((ObjectName) obj).objectName.equals(objectName);
376: }
377: }
378:
379: }
|