001: /*
002: * <copyright>
003: *
004: * Copyright 2000-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.tools.csmart.ui.viewer;
028:
029: import org.cougaar.tools.csmart.core.db.ExperimentDB;
030:
031: import javax.swing.*;
032: import javax.swing.tree.DefaultMutableTreeNode;
033: import java.lang.reflect.Array;
034: import java.lang.reflect.Method;
035: import java.util.ArrayList;
036: import java.util.Enumeration;
037: import java.util.List;
038:
039: public class OrganizerNameSet extends UniqueNameSet {
040: private Class[] noTypes = new Class[0];
041: private Method getNameMethod = null;
042: private String prompt;
043: private String databaseCheck;
044: private Method dbCheckMethod = null;
045:
046: /**
047: * The namePrefix is used as the base to generate uniqu names.
048: * The prompt is the prompt to display for the user to get a name.
049: * The databaseCheck method is assumed to be the name of a method
050: * in ExperimentDB that takes the component name as an argument
051: * and returns a boolean indicating if that name is in the database.
052: * @param namePrefix a single word prepended to unique objects
053: * @param prompt a single word describing the object to be named
054: * @param databaseCheck method name to check for name in database or null
055: */
056: public OrganizerNameSet(String namePrefix, String prompt,
057: String databaseCheck) {
058: super (namePrefix);
059: this .prompt = prompt;
060: this .databaseCheck = databaseCheck;
061: }
062:
063: public void init(DefaultMutableTreeNode root, Class leafClass,
064: String getNameMethodName) {
065: try {
066: getNameMethod = leafClass.getMethod(getNameMethodName,
067: noTypes);
068: } catch (Exception e) {
069: if (log.isErrorEnabled()) {
070: log.error("Getting name method: " + e);
071: }
072: return;
073: }
074: Object things[] = getObjects(leafClass, root);
075: init(things, getNameMethod);
076: }
077:
078: public Object getObjectInTree(Class leafClass,
079: DefaultMutableTreeNode root, String name) {
080: Object[] things = getObjects(leafClass, root);
081: Object[] noArgs = new Object[0];
082: for (int i = 0; i < things.length; i++) {
083: try {
084: String thingName = (String) getNameMethod.invoke(
085: things[i], noArgs);
086: if (thingName.equals(name))
087: return things[i];
088: } catch (Exception e) {
089: if (log.isErrorEnabled()) {
090: log.error("Reading: " + things[i], e);
091: }
092: }
093: }
094: return null;
095: }
096:
097: private Object[] getObjects(Class leafClass,
098: DefaultMutableTreeNode root) {
099: List result = new ArrayList();
100: for (Enumeration e = root.depthFirstEnumeration(); e
101: .hasMoreElements();) {
102: DefaultMutableTreeNode node = (DefaultMutableTreeNode) e
103: .nextElement();
104: Object o = node.getUserObject();
105: if (leafClass.isInstance(o))
106: result.add(o);
107: }
108: return result.toArray((Object[]) Array.newInstance(leafClass,
109: result.size()));
110: }
111:
112: /**
113: * Get a name for a folder, experiment, society, recipe, etc.
114: * that is unique in the workspace and in the database.
115: * @param originalName the current name of the object
116: * @param allowExistingName true to allow existing name (true if renaming)
117: * @return String new unique name
118: */
119: protected String getUniqueName(String originalName,
120: boolean allowExistingName) {
121: String name = null;
122: while (true) {
123: // get new name from user
124: String inputPrompt = "Enter " + prompt + " Name";
125: String title = prompt + " Name";
126: name = (String) JOptionPane.showInputDialog(null,
127: inputPrompt, title, JOptionPane.QUESTION_MESSAGE,
128: null, null, originalName);
129: if (name == null)
130: return null;
131:
132: name = name.trim();
133: if (name.equals(""))
134: return null;
135:
136: if (name.equals(originalName) && allowExistingName)
137: return name;
138:
139: // if name is not unique in CSMART, tell user to try again
140: if (contains(name)) {
141: title = prompt + " Name Not Unique";
142: int answer = JOptionPane.showConfirmDialog(null,
143: "Use an unique name", title,
144: JOptionPane.OK_CANCEL_OPTION,
145: JOptionPane.ERROR_MESSAGE);
146: if (answer != JOptionPane.OK_OPTION)
147: return null;
148: } else {
149: // if name is unique in CSMART and not checking database, return name
150: if (databaseCheck == null)
151: return name;
152: // ensure that name is not in the database
153: // if can't reach database, just assume that name is ok
154: boolean inDatabase = isInDatabase(name);
155: if (inDatabase) {
156: title = prompt + " Name Not Unique";
157: int answer = JOptionPane
158: .showConfirmDialog(
159: null,
160: "This name is in the database; use an unique name",
161: title,
162: JOptionPane.OK_CANCEL_OPTION,
163: JOptionPane.ERROR_MESSAGE);
164: if (answer != JOptionPane.OK_OPTION)
165: return null;
166: } else
167: return name; // have unique name
168: } // end if unique in CSMART
169: } // end while loop
170: }
171:
172: private void getDatabaseCheckMethod() {
173: Class[] paramClasses = { String.class };
174: try {
175: dbCheckMethod = ExperimentDB.class.getMethod(databaseCheck,
176: paramClasses);
177: } catch (NoSuchMethodException e) {
178: if (log.isErrorEnabled()) {
179: log.error("No such method", e);
180: }
181: }
182: }
183:
184: // ensure that name is not in the database
185: // if can't reach database, just assume that name is not there
186: private boolean isInDatabase(String name) {
187: if (databaseCheck == null)
188: return false;
189: if (dbCheckMethod == null)
190: getDatabaseCheckMethod();
191: if (dbCheckMethod == null)
192: return false;
193: boolean inDatabase = false;
194: Object[] args = new Object[1];
195: args[0] = name;
196: try {
197: Object result = dbCheckMethod.invoke(null, args);
198: if (result instanceof Boolean)
199: inDatabase = ((Boolean) result).booleanValue();
200: else if (log.isErrorEnabled()) {
201: log
202: .error("In Database Check returned unexpected result: "
203: + inDatabase);
204: }
205: } catch (Exception e) {
206: if (log.isErrorEnabled()) {
207: log
208: .error(
209: "Exception checking for unique name in database",
210: e);
211: }
212: }
213: return inDatabase;
214: }
215:
216: protected boolean isUniqueName(String name) {
217: return !contains(name) && !isInDatabase(name);
218: }
219:
220: /**
221: * Generate a name that is unique in the CSMART workspace,
222: * and in the database. The user is only prompted
223: * for a new name, if the generated name is not unique.
224: */
225:
226: protected String generateUniqueName(String name,
227: boolean allowExistingName) {
228: if (!allowExistingName)
229: name = generateName(name);
230: if (isUniqueName(name))
231: return name;
232: else
233: return getUniqueName(name, allowExistingName);
234: }
235:
236: }
|