KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ca > directory > jxplorer > tree > SmartModel


1 package com.ca.directory.jxplorer.tree;
2
3 import com.ca.commons.cbutil.CBIntText;
4 import com.ca.commons.naming.DN;
5 import com.ca.commons.naming.RDN;
6
7 import javax.naming.InvalidNameException JavaDoc;
8 import javax.swing.tree.*;
9 import java.util.Enumeration JavaDoc;
10 import java.util.logging.Level JavaDoc;
11 import java.util.logging.Logger JavaDoc;
12
13 //import javax.naming.directory.*;
14
/**
15  * The intention behind this class is to keep DefaultTreeModel largely
16  * unchanged, but add some utility ftns to make the task of translating
17  * between DNs and objects in the tree (SmartNodes and TreePaths).<p>
18  *
19  *
20  */

21  
22 public class SmartModel extends DefaultTreeModel
23 {
24     private static Logger JavaDoc log = Logger.getLogger(SmartModel.class.getName());
25
26     public SmartModel(TreeNode root) { super(root); }
27     
28     public SmartModel(TreeNode root, boolean asksAllowsChildren) { super(root, asksAllowsChildren); }
29
30     /**
31      * A conversion function. It takes a path and
32      * returns it as the corresponding DN.
33      * @param path a tree path to determine the DN for.
34      * @return the corresponding Distinguished Name
35      */

36      
37     public DN getDNForPath(TreePath path)
38     {
39         if (path==null) return null;
40         
41         DN newDN = new DN();
42         
43         // there *has* to be a better way to cast arrays. I wonder what it is.
44
Object JavaDoc[] cobbleStones = path.getPath();
45         
46         SmartNode myRoot = (SmartNode)cobbleStones[0];
47         
48         try
49         {
50             for (int i=0; i<cobbleStones.length; i++)
51             {
52                 SmartNode sn = ((SmartNode) cobbleStones[i]);
53                 
54                 RDN rdn = sn.getRDN();
55                 if (rdn.isEmpty() == false)
56                 {
57                     newDN.addChildRDN(rdn);
58                 }
59             }
60         }
61         catch (InvalidNameException JavaDoc e)
62         {
63             log.log(Level.WARNING, "ERROR: getDNForPath(TreePath path) can't parse " + path.toString() + "\n ", e);
64             return null;
65         }
66            
67         return newDN;
68     }
69
70     /** A conversion function - returns the current Node as a DN
71      *
72      */

73      
74     public DN getDNForNode(TreeNode node)
75     {
76         return getDNForPath(getPathForNode(node));
77     }
78
79     /**
80      * A conversion function. It takes an array
81      * of tree nodes representing a path and
82      * returns it as the corresponding DN.
83      * @param path an array of tree nodes to convert to a DN.
84      * @return the corresponding Distinguished Name
85      */

86      
87     public DN getDNForPath(TreeNode[] path)
88     {
89         return getDNForPath(new TreePath(path));
90     }
91
92     /**
93      * A conversion function - gets the path to given node.
94      */

95      
96     public TreePath getPathForNode(TreeNode node)
97     {
98         TreeNode[] nodePath = getPathToRoot(node);
99         if (nodePath == null) { return null; }
100         return new TreePath(nodePath);
101     }
102     
103     /**
104      * A conversion function - gets a path for a particular DN
105      */

106      
107     public TreePath getPathForDN(DN nodeDN)
108     {
109         SmartNode node = getNodeForDN(nodeDN);
110         if (node == null) { return null; }
111         return getPathForNode(node);
112     }
113     
114     /**
115      * A conversion function.
116      * Returns the existing smart node corresponding to a DN.
117      * Returns null if the DN does not currently exist in
118      * the client tree, even if it is a valid DN on the server.
119      * (We're only searching the GUI Tree here.)
120      *
121      * @param nodeDN the full DN of the node to be found
122      * @return the final node in the tree corresponding to the lowest
123      * level RDN of the DN.
124      */

125      
126     public SmartNode getNodeForDN(DN nodeDN)
127     {
128         if ((nodeDN==null)) return null;
129     
130         if (nodeDN.size()==0) return (SmartNode)getRoot();
131     
132         SmartNode child = null;
133         SmartNode parent = (SmartNode)getRoot();
134         
135         // for each tree level, grab the current node pointer (parent)
136

137         for (int i=0;i< nodeDN.size();i++)
138         {
139             RDN rdn = nodeDN.getRDN(i);
140
141             Enumeration JavaDoc children = parent.children();
142             parent = null;
143             
144             // search children trying to find matching RDN
145
while (children.hasMoreElements())
146             {
147                 child = (SmartNode)children.nextElement();
148                 
149                 if (child.rdnEquals(rdn))
150                 {
151                     parent = child; // reset parent pointer to current node, prior to next cycle
152
break;
153                 }
154             }
155
156             if (parent == null) // i.e. couldn't find sub-node so...
157
{
158                 return null; // ... fail
159
}
160         }
161         
162         // if we're still here, we should now have the final node.
163
return parent;
164     }
165
166     
167
168     /**
169      * A rare condition occurs when a user tries to copy a
170      * node over an existing node with the same name. This
171      * ftn. emulates the behaviour of many tree editing systems
172      * by allowing the copy, but prepending 'Copy ' or 'Copy (n) of'
173      * to the name. This ftn searches the existing set of
174      * siblings to find a unique name, whether 'Copy ', or
175      * 'Copy (n) of' where n is a unique number.
176      *
177      * @param activeDN the DN of the node into which the
178      * new node is being copied.
179      * @param copyDN the DN of the node being copied.
180      */

181     
182     // - and who would have thought such a simple task could get so nickity -
183

184     protected String JavaDoc getUniqueCopyRDN(DN activeDN, DN copyDN)
185     {
186         RDN testRDN = copyDN.getLowestRDN();
187         String JavaDoc testValue = copyDN.getLowestRDN().getRawVal();
188         String JavaDoc testClass = copyDN.getLowestRDN().getAtt();
189
190         // XXX translation of this is ugly! Can't see how to improve it off hand however.
191
String JavaDoc copyPrefix = testClass + "=" + CBIntText.get("Copy");
192         String JavaDoc copyPrefix2 = CBIntText.get("of");
193         
194         boolean originalExists = false;
195         
196         int copyNumber = 0;
197
198         SmartNode parent = getNodeForDN(activeDN);
199         
200         if (parent != null) // can't think why it *would* equal null, mind you...
201
{
202             Enumeration JavaDoc children = parent.children();
203
204             /**
205              * Loop through all children, doing two things;
206              * a) check if there is already a child with the name
207              * we're going to add (i.e. we need to do find a new name)
208              * b) check if there are already copies (i.e we need to
209              * produce a unique "Copy (512) of ..." name)
210              */

211        
212             SmartNode child;
213             while (children.hasMoreElements())
214             {
215                 child = (SmartNode)children.nextElement();
216                 RDN childRDN = child.getRDN();
217                 String JavaDoc childRDNString = childRDN.toString();
218                 if ((!originalExists ) && childRDN.equals(testRDN)) // test if there is already a doo-dad of this name
219
{
220                     originalExists = true; // ... there is, we have work to do!
221
}
222                 
223                 if (childRDNString.startsWith(copyPrefix)==true) // we have a contender
224
{
225                     if (childRDNString.endsWith(testValue)) // we've found an *existing*
226
{ // copy, and now need to get a
227
// unique ID number for it...
228
int startpos = copyPrefix.length() + 1;
229                         if (childRDNString.charAt(startpos)=='(')
230                         {
231                             int endpos = childRDNString.indexOf(')', startpos);
232                             if (endpos != -1)
233                             {
234                                 String JavaDoc childCopyNumberText = childRDNString.substring(startpos+1,endpos);
235                                 try
236                                 {
237                                     int childCopyNumber = Integer.parseInt(childCopyNumberText);
238                                     if (childCopyNumber >= copyNumber) // make sure copyNumber always
239
copyNumber = childCopyNumber + 1; // one greater than largest existing
240
}
241                                 catch (NumberFormatException JavaDoc e) // if it wasn't a number between the brackets...
242
{
243                                     if (copyNumber == 0) copyNumber = 2;
244                                 }
245                             }
246                             else
247                             {
248                                 if (copyNumber == 0) copyNumber = 2;
249                             }
250                         }
251                         else // the copy found is unnumbered, so set out copyNumber
252
{ // to '2' if it hasn't already been set.
253
if (copyNumber == 0) copyNumber = 2;
254                         }
255                     }
256                 }
257             }
258             
259             String JavaDoc returnValue;
260             
261             if (originalExists)
262             {
263                 if (copyNumber != 0) // produce numbered 'copy (x) of' version
264
returnValue = copyPrefix + " (" + copyNumber + ") " + copyPrefix2 + " " + testValue;
265                 else // first copy is unnumbered.
266
returnValue = copyPrefix + " " + copyPrefix2 + " " + testValue;
267             }
268             else
269                 returnValue = testRDN.toString();
270             
271             return returnValue;
272         }
273         return testRDN.toString(); // only if parent is null...not sure how this could happen :-)
274
}
275     
276
277
278     /**
279     * This method checks if a node that is represented by a DN exists
280     * below its parent. In otherwords it gets this DNs parent then gets
281     * all the parent's children and sees if the RDN of the DN exists.
282     * NOTE: if the new DN has already been added to the parent - there will
283     * be two copies of it. This method checks for two copies of the RDN.
284     *
285     * @param nodeDN the full DN of the node to be found
286     * @return true if the node exists, false otherwise (or if there is an error).
287     * .
288     */

289
290     public boolean exists(DN nodeDN)
291     {
292         if ((nodeDN==null)) return false;
293
294         if (nodeDN.size()==0) return false;
295
296         RDN nodeRDN = nodeDN.getLowestRDN();
297         SmartNode parent = getNodeForDN(nodeDN.parentDN());
298         SmartNode child = null;
299
300         Enumeration JavaDoc children = parent.children();
301
302         int matchCount = 0;
303
304         while (children.hasMoreElements()) //TE: iterate thru the children and see if the rdn matches.
305
{
306             child = (SmartNode)children.nextElement();
307
308             if (child.rdnEquals(nodeRDN))
309             {
310                 matchCount++;
311
312                 if(matchCount==2)
313                     return true;
314             }
315         }
316
317         return false;
318     }
319 }
Popular Tags