KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > jawe > xml > XMLCollection


1 /* XMLCollection.java
2  *
3  * Authors:
4  * Stefanovic Nenad chupo@iis.ns.ac.yu
5  * Bojanic Sasa sasaboy@neobee.net
6  * Puskas Vladimir vpuskas@eunet.yu
7  * Pilipovic Goran zboniek@uns.ac.yu
8  *
9  */

10
11
12 package org.enhydra.jawe.xml;
13
14 import org.enhydra.jawe.xml.ToNameMutableTreeNode;
15 import org.enhydra.jawe.xml.panels.*;
16
17 import javax.swing.tree.*;
18 import javax.swing.text.*;
19 import java.util.*;
20 import org.w3c.dom.*;
21 import org.apache.xerces.util.XMLChar;
22
23 /**
24 * XMLCollection class instance represents program equivalence to
25 * the collection of elements defined in some XML XML. It is used
26 * to enable user to visually create new element and put it into
27 * collection, and also to edit it and modify.
28 *
29 * <p>NOTE: Although this class is not declared abstract, it is
30 * uselles without redefining it's methods (especially
31 * {@link #generateNewElement} method}.
32 */

33 public class XMLCollection extends XMLElement {
34    /** Used as a textual prefix for a generated numerical ID */
35    protected transient String JavaDoc IDPrefix="";
36    /** Used to generate a unique ID for some element */
37    private transient long nextID=0;
38
39    /** The collection of elements. */
40    protected transient ArrayList refCollectionElements=new ArrayList();
41    /**
42    * Visually presents the collection of elements. The default panel is
43    * instance of {@link XMLTablePanel} class.
44    */

45    protected transient XMLPanel controlledPanel;
46    /**
47    * The panel consisted of control buttons. It controls the process
48    * of adding, deleting and modifying the elements of collection.
49    * The default panel is instance of {@link XMLTableControlPanel} class.
50    */

51    protected transient XMLControlPanel controlPanel;
52
53    /** The owner class which element is this class instance. */
54    protected transient XMLComplexElement myOwner;
55
56    protected boolean coloringTable=false;
57
58    /**
59    * Create collection which is owned by specified owner.
60    *
61    * @param myOwner the program equivalence to an XML schema defined
62    * element that holds the XML schema collection presented
63    * by this class instance.
64    */

65    public XMLCollection (XMLComplexElement myOwner) {
66       super();
67       this.myOwner=myOwner;
68    }
69
70    public XMLCollection (XMLComplexElement myOwner,String JavaDoc name) {
71       super(name);
72       this.myOwner=myOwner;
73    }
74
75    public XMLComplexElement getOwner () {
76       return myOwner;
77    }
78
79    /** Adds new element to collection. */
80    public void add (XMLElement el) {
81       refCollectionElements.add(el);
82    }
83
84    /** Removes specified element from collection. */
85    public void remove (Object JavaDoc el) {
86       refCollectionElements.remove(el);
87    }
88
89    /** Gets the element that is placed at specified no. from collection. */
90    public Object JavaDoc get (int no) {
91       try {
92          return refCollectionElements.get(no);
93       } catch (Exception JavaDoc ex) {
94          return null;
95       }
96    }
97
98    /** Returns the number of elements within collection. */
99    public int size () {
100       return refCollectionElements.size();
101    }
102
103    /** Clears the collection. */
104    public void clear () {
105       refCollectionElements.clear();
106    }
107
108    /**
109    * Refreshes the collection.
110    *
111    * @param elementsToAddOrRemove Set of elements that has to be added to or
112    * removed from collection.
113    * @param append <tt>true</tt> if adding elements to collection,
114    * <tt>false</tt> otherwise.
115    */

116    public void refreshCollection (Set elementsToAddOrRemove,boolean append) {
117       if (append) {
118          refCollectionElements.addAll(elementsToAddOrRemove);
119       } else {
120          refCollectionElements.removeAll(elementsToAddOrRemove);
121       }
122    }
123
124    /**
125    * Returnes the element specified by ID or Name attribute. If this is
126    * collection of XMLCollectionElement objects, element is searched by
127    * ID attribute, otherwise it is searched by Name attribute.
128    *
129    * @param IDOrName ID or Name attribute of wanted element.
130    * @return Wanted element if exist, null otherwise.
131    */

132    public XMLComplexElement getCollectionElement (String JavaDoc IDOrName) {
133       XMLComplexElement ce=null;
134       String JavaDoc ceIDOrName;
135       Iterator it=refCollectionElements.iterator();
136       while (it.hasNext()) {
137          try {
138             XMLComplexElement cetmp=(XMLComplexElement)it.next();
139             if (cetmp instanceof XMLCollectionElement) {
140                ceIDOrName=((XMLCollectionElement)cetmp).getID();
141             } else {
142                ceIDOrName=cetmp.get("Name").toString();
143             }
144             if (ceIDOrName.equals(IDOrName)) {
145                ce=cetmp;
146                break;
147             }
148          } catch (ClassCastException JavaDoc cce) {} // just catch it
149
}
150       return ce;
151    }
152
153    /**
154    * Gets the structure of elements contained within collection,
155    * that is the all elements that element is made of.
156    */

157    public Collection getElementStructure () {
158       XMLElement el=generateNewElement();
159       if (el instanceof XMLCollectionElement) {
160          try {
161             decrementID();
162             ((XMLCollectionElement)el).set("Id","-1");
163          }
164          catch (Exception JavaDoc ex) {}
165       }
166       if (el instanceof XMLComplexElement) {
167          return ((XMLComplexElement)el).toComplexType();
168       } else {
169          java.util.List JavaDoc l=new ArrayList();
170          l.add(el);
171          return l;
172       }
173    }
174
175    /**
176    * Returns the ordinal numbers of elements not to be displayed
177    * within table panel. The ordinal numbers of elements corresponds
178    * to the inserting order within {@link XMLComplexElement#fillStructure}
179    * method.
180    */

181    public int[] getInvisibleTableFieldOrdinals () {
182       return null;
183    }
184
185    /**
186    * Sets the collection and all contained elements to be read only or not.
187    */

188    public void setReadOnly (boolean ro) {
189       isReadOnly=ro;
190       Iterator it=refCollectionElements.iterator();
191       while (it.hasNext()) {
192          XMLElement el=(XMLElement)it.next();
193          el.setReadOnly(ro);
194       }
195    }
196
197    /** Returns the collection of all elements within collection. */
198    public Collection toCollection() {
199       return refCollectionElements;
200    }
201
202    /**
203    * Gets elements that can be choosed within table. Default
204    * implementation returns all elements within collection.
205    */

206    public Collection getTableElements() {
207       return refCollectionElements;
208    }
209
210    /**
211    * Gets elements that can be choosed within some combo box. Default
212    * implementation returns all elements within collection.
213    */

214    public Collection getChoosable() {
215       return refCollectionElements;
216    }
217
218    /**
219    * Generates the new element that made collection. Derived classes
220    * has to implement this method to create it's collection element.
221    */

222    public XMLElement generateNewElement() {
223       return new XMLElement();
224    }
225
226    /**
227    * Some specific things to be done after element is created.
228    * Default implementation is nothing to do, and derived classes
229    * should implement it's specific actions.
230    */

231    public void onElementCreated (XMLElement el) {
232       return;
233    }
234
235    /**
236    * Some specific things to be done after element is inserted.
237    * into collection. Default implementation is nothing to do,
238    * and derived classes should implement it's specific actions.
239    */

240    public void onElementInserted (XMLElement el) {
241       return;
242    }
243
244    /**
245    * Some specific things to be done after element from collection
246    * is modified. Default implementation is nothing to do, and derived
247    * classes should implement it's specific actions.
248    */

249    public void onElementModified (XMLElement el) {
250       return;
251    }
252
253    /**
254    * Some specific things to be done after element is deleted from
255    * collection. Default implementation is nothing to do, and derived
256    * classes should implement it's specific actions.
257    */

258    public void onElementDeleted (XMLElement el) {
259       return;
260    }
261
262    /**
263    * Some specific things to be done after element is removed from
264    * collection. Default implementation is nothing to do, and derived
265    * classes should implement it's specific actions.
266    */

267    public void onElementRemoved (XMLElement el) {
268       return;
269    }
270
271    /**
272    * Returns <tt>true</tt> if element can be inserted into collection.
273    * Default implementation returns <tt>true</tt>, and derived classes
274    * should implement it's specific check.
275    */

276    public boolean canInsertElement (XMLElement el) {
277       return true;
278    }
279
280    /**
281    * Returns <tt>true</tt> if element can be removed from collection.
282    * Default implementation returns <tt>true</tt>, and derived classes
283    * should implement it's specific check.
284    */

285    public boolean canRemoveElement (XMLElement el) {
286       return true;
287    }
288
289    public XMLPanel getControlledPanel () {
290       return controlledPanel;
291    }
292
293    public XMLPanel getControlPanel () {
294       return controlPanel;
295    }
296
297    /**
298    * Returns <tt>true</tt> if there is no elements within collection.
299    */

300    public boolean isEmpty () {
301       return size()==0;
302    }
303
304    // First, the controlled panel must be created, and then the control panel
305
public XMLPanel getPanel () {
306       controlledPanel=new XMLTablePanel(this,"",false,false,false,coloringTable,true);
307       controlPanel=new XMLTableControlPanel(this,"",true,false);
308       return new XMLGroupPanel(this,new XMLPanel[]{
309          controlledPanel,controlPanel},toLabel(),XMLPanel.BOX_LAYOUT,
310          false,true);
311    }
312
313    public void toXML(Node parent) throws DOMException {
314       if (!isEmpty() || isRequired()) {
315          if (parent!=null) {
316             Node node = (parent.getOwnerDocument()).createElement(name);
317             for (Iterator it = refCollectionElements.iterator(); it.hasNext();) {
318                ((XMLElement) it.next()).toXML(node);
319             }
320             parent.appendChild(node);
321          }
322       }
323    }
324
325    public void fromXML(Node node) {
326       String JavaDoc nameSpacePrefix=node.getPrefix();
327       if (nameSpacePrefix!=null) {
328          nameSpacePrefix+=":";
329       } else {
330          nameSpacePrefix="";
331       }
332
333       XMLElement newOne=generateNewElement();
334       if (newOne instanceof XMLCollectionElement) {
335          try {
336             decrementID();
337             ((XMLCollectionElement)newOne).set("Id","-1");
338          }
339          catch (Exception JavaDoc ex) {}
340       }
341
342       String JavaDoc elName=newOne.name;
343
344       if (node!=null) {
345          if (node.hasChildNodes()) {
346             NodeList children = node.getChildNodes();
347             int lng=children.getLength();
348 //System.out.println("The length of collection"+node.getNodeName()+" is "+lng);
349
for (int i = 0; i<lng; i++) {
350                Node child=children.item(i);
351                if (child.getNodeName().equals(nameSpacePrefix+elName)) {
352 //System.out.println("I="+i);
353
newOne = generateNewElement();
354                   decrementID();
355 //System.out.println("Now the collection element of collection "+node.getNodeName()+" will be processed");
356
newOne.fromXML(children.item(i));
357                   //refCollectionElements.add(newOne);
358
add(newOne); //Harald Meister, call overwritten add()'s also
359
}
360             }
361          } /*else {
362             // FIXME: this is temporary /debug/ output, remove it as needed
363             System.err.println("Collection: " + name
364                             + " hasn't got any elements!");
365          }
366          if (node.hasAttributes()) {
367             // FIXME: this is temporary /debug/ output, remove it as needed
368             System.err.println("Collection: " + name + " HAS "
369                             + (node.getAttributes()).getLength()
370                             + " attribute(s)!");
371          }*/

372       }
373 //System.out.println("The length of collection "+name+" after importing is"+size());
374
}
375
376    public String JavaDoc toString () {
377       if (labelName!=null) {
378          return labelName;
379       } else {
380          return "";
381       }
382    }
383
384    /**
385    * Returns the name of the message defined within property file
386    * that explains the reason why element marked as read only
387    * can't be deleted.
388    */

389    public String JavaDoc getReadOnlyMessageName (XMLElement el) {
390       return "WarningCannotDeleteReadOnlyElement";
391    }
392
393    /**
394    * Returns the name of the message defined within property file
395    * that explains the reason why element that is in use
396    * can't be deleted.
397    */

398    public String JavaDoc getInUseMessageName (XMLElement el) {
399       return "WarningCannotDeleteElementThatIsInUse";
400    }
401
402    // must make new collection that consists of the same elements as
403
// previous one
404
public Object JavaDoc clone () {
405       XMLCollection d=(XMLCollection)super.clone();
406       d.refCollectionElements=new ArrayList();
407       Iterator it=this.refCollectionElements.iterator();
408       while (it.hasNext()) {
409          XMLElement el=(XMLElement)it.next();
410          Object JavaDoc cloned=el.clone();
411          d.refCollectionElements.add(cloned);
412          if (cloned instanceof XMLCollectionElement) {
413             ((XMLCollectionElement)cloned).myCollection=d;
414          }
415       }
416       d.myOwner=this.myOwner;
417       d.coloringTable=this.coloringTable;
418       return d;
419    }
420
421    // INTERFACE FOR GENERATING IDS
422
/** Sets the prefix for some ID generated by #generateID. */
423    public void setIDPrefix (String JavaDoc idPref) {
424       IDPrefix=idPref;
425    }
426
427    /** Returns the prefix of some ID generated by #generateID. */
428    public String JavaDoc getIDPrefix () {
429       return IDPrefix;
430    }
431
432    /** Sets the ID upon further IDs are generated. */
433    protected void setCurrentID (long ID) {
434       nextID=ID;
435    }
436
437    /** Gets the ID upon further IDs are generated. */
438    public long getCurrentID () {
439       return nextID;
440    }
441
442    /**
443    * Generates numerical ID for elements that need it, and
444    * converts that ID to string by adding it a prefix that
445    * is set using #setIDPrefix method. ID is generated by
446    * incrementing the previously generated numerical ID.
447    *
448    * @return The string representation of ID.
449    */

450    public String JavaDoc generateID () {
451       if (IDPrefix==null) IDPrefix="";
452       String JavaDoc ID;
453       do {
454          ID=IDPrefix+new Long JavaDoc(++nextID).toString();
455       } while (getCollectionElement(ID)!=null);
456       return ID;
457    }
458
459    /**
460    * Resets an ID generator. Used when opening an existing XML file
461    * or when creating a new file.
462    */

463    protected void resetID () {
464       nextID=0;
465    }
466
467    /**
468    * Decrements an ID. Used when the temporary element is created. This
469    * avoids unnecessary incrementation of IDs.
470    */

471    protected void decrementID () {
472       nextID--;
473    }
474
475    /**
476    * Updates an ID. Used when importing an existing XML file.
477    * The method updates ID and prepares it for generation of new ID.
478    *
479    * @param someID the ID value upon the update is performed.
480    */

481    protected void updateID (String JavaDoc someID) {
482       // try to get ID as if it is ours
483
try {
484          long val;
485          if (someID.startsWith(IDPrefix)) {
486             String JavaDoc ID=someID.substring(IDPrefix.length(),someID.length());
487             val=Long.parseLong(ID);
488             if (val>nextID) {
489                nextID=val;
490             }
491          }
492       // then try to update someID as if it is only number
493
} catch (Exception JavaDoc ex) {
494          return;
495       }
496    }
497
498    public void refreshLabelName() {
499       super.refreshLabelName();
500       Iterator it = refCollectionElements.iterator();
501       while(it.hasNext()) {
502          XMLElement el = (XMLElement) it.next();
503          el.refreshLabelName();
504       }
505    }
506
507    /**
508    * Checks if Id is valid NMTOKEN string.
509    */

510    public static boolean isIdValid (String JavaDoc id) {
511       return XMLChar.isValidNmtoken(id);
512    }
513
514    public DefaultMutableTreeNode getNode() {
515       DefaultMutableTreeNode node = new ToNameMutableTreeNode(this);
516       for(int i = 0; i < this.refCollectionElements.size(); i++) {
517          node.add(
518              ((XMLElement)this.refCollectionElements.get(i)).getNode()
519              );
520       }
521       return node;
522    }
523
524    /**
525     * Make print description of this element and all subelements and attributes.
526     * @return print description of element
527     */

528    public String JavaDoc getPrintDescription( String JavaDoc indent, StyledDocument doc ) {
529       String JavaDoc retVal = "";
530       try {
531          StringBuffer JavaDoc all = new StringBuffer JavaDoc();
532          all.append( toName() + " : " );
533          doc.insertString( doc.getLength(), all.toString(), atts );
534
535          //only extended nodes should be displayed
536
if ( !this.isCollapsed() ) {
537             //subelements
538
String JavaDoc value;
539             for ( int i = 0; i < this.refCollectionElements.size(); i++ ) {
540                value = ( ( XMLElement )this.refCollectionElements.get( i ) ).getPrintDescription(
541                    indent + OFFSET, doc );
542                if ( value != null && !value.trim().equals( "" ) ) {
543                   all.append( NEWLINE );
544                   all.append( indent );
545                   all.append( value );
546                }
547             }
548          }
549          retVal = all.toString();
550       }catch(Exception JavaDoc e) {
551          e.printStackTrace();
552       }
553       return retVal;
554    }
555
556
557
558
559 }
560
Popular Tags