KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > structure > ObjectNode


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/structure/ObjectNode.java,v 1.27.2.2 2004/09/26 14:12:45 luetzkendorf Exp $
3  * $Revision: 1.27.2.2 $
4  * $Date: 2004/09/26 14:12:45 $
5  *
6  * ====================================================================
7  *
8  * Copyright 1999-2002 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */

23
24 package org.apache.slide.structure;
25
26 import java.io.Serializable JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.Enumeration JavaDoc;
29 import java.util.Vector JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.HashSet JavaDoc;
32 import org.apache.slide.common.ObjectValidationFailedException;
33 import org.apache.slide.common.UriPath;
34 import org.apache.slide.util.EmptyEnumeration;
35 import org.apache.slide.util.Messages;
36
37 /**
38  * Represents any kind of object node.
39  * <p/>
40  * This includes actors, activities and collections.
41  *
42  * @version $Revision: 1.27.2.2 $
43  */

44 public abstract class ObjectNode
45     implements Serializable JavaDoc, Cloneable JavaDoc {
46     
47
48     /**
49      * For tracking which bindings need to be updated.
50      */

51     private Set JavaDoc updatedBindings = null;
52
53     /**
54      * Uniform ressource identifier (URI) of the object.
55      */

56     protected String JavaDoc uri;
57     
58     /**
59      * Unique URI of the object. Enables clients to determine
60      * whether two bindings are to the same resource.
61      * The UURI is a URI and may use any registered URI scheme.
62      * If binding is enabled, several object URIs may represent the same resource,
63      * while the UURI must be really unique.
64      */

65     private String JavaDoc uuri;
66     
67     /**
68      * Vector of inbound links' Uris. Before modifying this vector you must check
69      * wheter {@link #linksShared} is true. In this case clone the vector
70      * and set the shared state to false.
71      */

72     private Vector JavaDoc links = null;
73     
74     /*
75      * If true then the {@link #links} vector is shared between multiple
76      * ObjectNode-instances and thus must not be modified.
77      *
78      *FIXME Never read! Do we need to implement linkSharing
79      */

80     //private boolean linksShared;
81

82     /**
83      * Vector of bindings. Before modifying this vector you must check
84      * whether {@link #bindingsShared} is true. In this case clone the vector
85      * and set the shared state to false.
86      */

87     private BindingList bindings;
88     private ParentBindingList parentBindings;
89     
90     /**
91      * If true then the {@link #bindings} vector is shared between multiple
92      * ObjectNode-instances and thus must not be modified.
93      */

94     private boolean bindingsShared;
95     
96     private Vector JavaDoc childrenCache = null;
97     
98     private transient UriPath path = null;
99
100     
101     /**
102      * Default constructor.
103      */

104     public ObjectNode() {
105         this.bindings = new BindingList();
106         this.parentBindings = new ParentBindingList();
107     }
108     
109     /**
110      * Default constructor.
111      */

112     public ObjectNode(String JavaDoc uri) {
113         this();
114         this.uri = uri;
115     }
116     
117     /**
118      * Default constructor.
119      * NOTE: this constructor should not be used if binding is enabled for the
120      * store associated to the specified URI.
121      */

122     public ObjectNode(String JavaDoc uri, Vector JavaDoc children, Vector JavaDoc links) {
123         this( uri );
124         this.links = links;
125         addChildren(children);
126     }
127     
128     /**
129      * Contructor to be used by stores supporting binding.
130      */

131     public ObjectNode(String JavaDoc uuri, Vector JavaDoc bindings, Vector JavaDoc parentBindings, Vector JavaDoc links) {
132         this();
133         this.uuri = uuri;
134         this.bindings = new BindingList(bindings);
135         this.parentBindings = new ParentBindingList(parentBindings);
136         this.links = links;
137         Enumeration JavaDoc e = bindings.elements();
138         if (e.hasMoreElements()) this.updatedBindings = new HashSet JavaDoc();
139         while(e.hasMoreElements()) {
140              updatedBindings.add(((ObjectNode.Binding)e.nextElement()).getUuri());
141           }
142     }
143     
144     /**
145      * Get object's unique resource identifier.
146      *
147      * @return String Uri
148      */

149     public String JavaDoc getUri() {
150         return this.uri;
151     }
152     
153     /**
154      * Set object's unique identifier.
155      *
156      * @param uri Object Uri
157      */

158     public void setUri(String JavaDoc uri) {
159         this.uri = uri;
160         this.path = null;
161     }
162     
163     /**
164      * Get the unique URI.
165      *
166      * @return an URI
167      *
168      */

169     public String JavaDoc getUuri() {
170         if (uuri != null) {
171             return uuri;
172         } else {
173             if (uri == null) {
174                 throw new IllegalStateException JavaDoc(toString());
175             }
176             return uri;
177         }
178     }
179     
180     /**
181      * Set the unique URI.
182      */

183     public void setUuri(String JavaDoc uuri) {
184         if (uuri == null) {
185             throw new IllegalArgumentException JavaDoc();
186         }
187         this.uuri = uuri;
188     }
189     
190
191     public Set JavaDoc getUpdatedBindings() {
192         if (this.updatedBindings == null) {
193             return Collections.EMPTY_SET;
194         } else {
195             return Collections.unmodifiableSet(updatedBindings);
196         }
197     }
198
199     public void resetUpdatedBindings() {
200         this.updatedBindings = null;
201     }
202
203     /**
204      * Return this object's children
205      *
206      * @return Enumeration Children's uris
207      */

208     public Vector JavaDoc getChildren() {
209         if (childrenCache == null) {
210             computeChildren();
211         }
212         return childrenCache;
213     }
214     
215     /**
216      * Return this object's children
217      *
218      * @return Enumeration Children's uris
219      */

220     public Enumeration JavaDoc enumerateChildren() {
221         return getChildren().elements();
222     }
223     
224     /**
225      * Return this object's bindings
226      *
227      * @return Enumeration of the bindings (Binding instances)
228      */

229     public Enumeration JavaDoc enumerateBindings() {
230         return bindings.elements();
231     }
232     
233     /**
234      * Return this object's binding parent-set
235      *
236      * @return Enumeration of the binding parent-set (Binding instances)
237      */

238     public Enumeration JavaDoc enumerateParentBindings() {
239         return parentBindings.elements();
240     }
241     
242     /**
243      * Return the UURI of the specified binding.
244      *
245      * @param bindingName a String
246      * @return UURI of the bound member
247      */

248     public String JavaDoc getBindingUuri( String JavaDoc bindingName ) {
249         String JavaDoc result = null;
250         Binding b = bindings.get(bindingName);
251         if (b != null) {
252             result = b.getUuri();
253         }
254         return result;
255     }
256     
257     /**
258      * Test if object has the specified child.
259      *
260      * @param uri Child's uri
261      * @return boolean true if this object has the specified child,
262      * false otherwise
263      */

264     public boolean hasChild(String JavaDoc uri) {
265         return getChildren().contains(uri);
266     }
267     
268     /**
269      * Test if this object has the specified child.
270      *
271      * @param child Child object
272      * @return boolean true if this object has the specified child,
273      * false otherwise
274      */

275     public boolean hasChild(ObjectNode child) {
276         boolean result = false;
277         if (child != null) {
278             result = getChildren().contains(child.getUri());
279         }
280         return result;
281     }
282     
283     /**
284      * Test if this object has the specified binding.
285      *
286      * @param bindingName the binding name
287      * @return boolean true if this object has the specified binding,
288      * false otherwise
289      */

290     public boolean hasBinding( String JavaDoc bindingName ) {
291         boolean result = false;
292         if (bindingName != null) {
293             result = (bindings.get(bindingName) != null);
294         }
295         return result;
296     }
297     
298     /**
299      * Test if this object has the specified parent binding.
300      *
301      * @param bindingName the binding name
302      * @return boolean true if this object has the specified binding,
303      * false otherwise
304      */

305     public boolean hasParentBinding( String JavaDoc bindingName ) {
306         boolean result = false;
307         if (bindingName != null) {
308             result = (parentBindings.get(bindingName) != null);
309         }
310         return result;
311     }
312     
313     /**
314      * Test if this object has the specified binding.
315      *
316      * @param child an ObjectNode
317      *
318      * @return true if this object has the specified binding,
319      * false otherwise
320      */

321     public boolean hasBinding( ObjectNode child ) {
322         if (child != null) {
323             Enumeration JavaDoc benum = enumerateBindings();
324             while (benum.hasMoreElements()) {
325                 Binding b = (Binding)benum.nextElement();
326                 if (b.getUuri().equals(child.getUuri())) {
327                     return true;
328                 }
329             }
330         }
331         return false;
332     }
333     
334     /**
335      * Return the number of binding parents (i.e. of nodes having a binding to this node)
336      */

337     public int numberOfParentBindings() {
338         return parentBindings.size();
339     }
340     
341     /**
342      * Test if object has children.
343      *
344      * @return boolean true if this object has children, false otherwise
345      */

346     public boolean hasChildren() {
347         return !(getChildren().isEmpty());
348     }
349
350     
351     /**
352      * Test if object has links.
353      *
354      * @return boolean true if this object has links, false otherwise
355      */

356     public boolean hasLinks() {
357         if (this.links == null) {
358             return false;
359         } else {
360             return !( links.isEmpty());
361         }
362     }
363     /**
364      * Return this object's inbound links
365      *
366      * @return Enumeration Inbound links uris
367      */

368     public Enumeration JavaDoc enumerateLinks() {
369         if (this.links == null) {
370             return EmptyEnumeration.INSTANCE;
371         } else {
372             return links.elements();
373         }
374     }
375     
376     
377     // --------------------------------------------------------- Object Methods
378
/**
379      * Equals.
380      *
381      * @param obj Object to test
382      * @return boolean True if the two object are equal :
383      * <li>obj is of type ObjectNode and is not null</li>
384      * <li>The Uris are equal</li>
385      */

386     public boolean equals(Object JavaDoc obj) {
387         if (obj == this) {
388             return true;
389         }
390         if (obj instanceof ObjectNode) {
391             return getPath().equals(((ObjectNode)obj).getPath());
392         }
393         else {
394             return false;
395         }
396     }
397     
398     public int hashCode() {
399         return getPath().hashCode();
400     }
401     
402     /**
403      * Clone.
404      *
405      * @return Object clone
406      */

407     public ObjectNode cloneObject() {
408         ObjectNode result = null;
409         
410         try {
411             // init the shared fields to let clone() copy them
412
//this.linksShared=true;
413
this.bindingsShared=true;
414             result = (ObjectNode) super.clone();
415         } catch(CloneNotSupportedException JavaDoc e) {
416             e.printStackTrace();
417         }
418         
419         return result;
420     }
421     
422     /**
423      * Copy.
424      *
425      * @return Object copy
426      */

427     public ObjectNode copyObject() {
428         ObjectNode result = null;
429         childrenCache = null;
430         
431         try {
432             result = (ObjectNode) super.clone();
433             //result.linksShared=false;
434
result.bindingsShared=false;
435             result.links = new Vector JavaDoc();
436             result.bindings = new BindingList();
437             result.parentBindings = new ParentBindingList();
438         } catch(CloneNotSupportedException JavaDoc e) {
439             e.printStackTrace();
440         }
441         
442         return result;
443     }
444     
445     /**
446      * Validate an ObjectNode.
447      *
448      * @param expectedUri Uri
449      */

450     public void validate(String JavaDoc expectedUri) {
451         
452         if (uri == null)
453             throw new ObjectValidationFailedException
454                 (expectedUri, Messages.message
455                      (ObjectNode.class.getName() + ".nullUri"));
456         
457         if (!uri.equals(expectedUri) && !uuri.equals(expectedUri))
458             throw new ObjectValidationFailedException
459                 (expectedUri, Messages.message
460                      (ObjectNode.class.getName() + ".incorrectUri"));
461         
462         if (bindings == null || parentBindings == null)
463             throw new ObjectValidationFailedException
464                 (uri, Messages.message
465                      (ObjectNode.class.getName() + ".nullBindingsVector"));
466                 
467     }
468     
469     /**
470      * Add a child.
471      * @param child an ObjectNode
472      */

473     public void addChild( ObjectNode child ) {
474         addBinding( child.getPath().lastSegment(), child );
475     }
476
477     
478     /**
479      * Add a link.
480      * @param link an LinkNode
481      */

482     public void addLink( LinkNode link ) {
483         if (this.links == null) this.links = new Vector JavaDoc();
484         links.add(link.getUri());
485     }
486     
487     /**
488      * Add a new binding.
489      * @param bindingName a String
490      * @param source the child ObjectNode
491      */

492     public void addBinding( String JavaDoc bindingName, ObjectNode source ) {
493         if (this.updatedBindings == null) this.updatedBindings = new HashSet JavaDoc();
494           updatedBindings.add(source.getUri());
495           
496         if (!hasBinding(bindingName)) {
497             if(bindingsShared) {
498                 // Lazy cloning on first write access
499
bindings=(BindingList)bindings.clone();
500                 parentBindings=(ParentBindingList)parentBindings.clone();
501                 bindingsShared=false;
502             }
503             bindings.put(bindingName, source);
504             childrenCache = null;
505             source.addParentBinding(bindingName, this);
506         }
507         else {
508             throw new IllegalStateException JavaDoc(
509                 "Existing binding "+bindingName+" at "+this.uri+" has to be removed first");
510         }
511     }
512     
513     /**
514      * Remove child.
515      *
516      * @param child The child to remove
517      */

518     public void removeChild(ObjectNode child) {
519         if (this.updatedBindings == null) this.updatedBindings = new HashSet JavaDoc();
520         updatedBindings.add(child.getUri());
521         
522         if (child == null) {
523             return;
524         }
525         
526         if(bindingsShared) {
527             // Lazy cloning on first write access
528
bindings=(BindingList)bindings.clone();
529             bindingsShared=false;
530         }
531         String JavaDoc bindingName = lastUriSegment( child.getUri() );
532         bindings.remove(bindingName);
533         childrenCache = null;
534         child.removeParentBinding(bindingName, this);
535     }
536
537     /**
538      * Remove link.
539      *
540      * @param link
541      */

542     public void removeLink(LinkNode link) {
543         if (this.links != null) {
544             links.remove(link.getUri());
545         }
546     }
547     
548     /**
549      * Get the path of this object node.
550      *
551      * @return an UriPath
552      */

553     public UriPath getPath() {
554         if (path == null) {
555             path = new UriPath(getUri());
556         }
557         return path;
558     }
559     
560     /**
561      * Get the last segment of the specified uri.
562      *
563      * @param uri a String
564      *
565      * @return a String
566      *
567      */

568     private String JavaDoc lastUriSegment( String JavaDoc uri ) {
569         return new UriPath(uri).lastSegment();
570     }
571     
572     private void computeChildren() {
573         childrenCache = new Vector JavaDoc();
574         Enumeration JavaDoc e = bindings.elements();
575         while (e.hasMoreElements()) {
576             Binding b = (Binding)e.nextElement();
577             StringBuffer JavaDoc buf = new StringBuffer JavaDoc(uri);
578             if (!uri.endsWith("/")) {
579                 buf.append("/");
580             }
581             buf.append(b.getName());
582             childrenCache.add( buf.toString() );
583         }
584     }
585     
586     /**
587      * Method computeBindings
588      * NOTE: should not be used if binding is enabled for the
589      * store associated to this object node.
590      */

591     private void addChildren( Vector JavaDoc children ) {
592         Enumeration JavaDoc ch = children.elements();
593         while (ch.hasMoreElements()) {
594             String JavaDoc c = (String JavaDoc)ch.nextElement();
595             ObjectNode s = new SubjectNode(c);
596             s.setUuri( s.getUri() );
597             addBinding( lastUriSegment(c), s );
598         }
599         ObjectNode p = null;
600         UriPath up = new UriPath(uri);
601         UriPath pup = up.parent();
602         if (pup != null) {
603             String JavaDoc pUri = pup.toString();
604             p = new SubjectNode( pUri );
605             p.setUuri( p.getUri() );
606         }
607         addParentBinding( getPath().lastSegment(), p );
608     }
609     
610     public void addParentBinding( String JavaDoc bindingName, ObjectNode parent ) {
611         if(bindingsShared) {
612             // Lazy cloning on first write access
613
bindings=(BindingList)bindings.clone();
614             parentBindings=(ParentBindingList)parentBindings.clone();
615             bindingsShared=false;
616         }
617         parentBindings.put(bindingName, parent);
618     }
619     
620     
621     private void removeParentBinding( String JavaDoc bindingName, ObjectNode parent ) {
622         if(bindingsShared) {
623             // Lazy cloning on first write access
624
bindings=(BindingList)bindings.clone();
625             parentBindings=(ParentBindingList)parentBindings.clone();
626             bindingsShared=false;
627         }
628         parentBindings.remove(bindingName, parent.getUuri() );
629     }
630     
631     public String JavaDoc toString() {
632         StringBuffer JavaDoc b = new StringBuffer JavaDoc(getUri());
633         if (!getUri().equals(getUuri())) {
634             b.append(" [").append(getUuri()).append("]");
635         }
636         return b.toString();
637     }
638     
639     /**
640      * Represents an binding bindingName -> UURI
641      */

642     public static class Binding implements Serializable JavaDoc, Cloneable JavaDoc {
643         
644         protected final String JavaDoc bName;
645         protected final String JavaDoc bUuri;
646         
647         public Binding(String JavaDoc bindingName, String JavaDoc bindingUuri) {
648             this.bName = bindingName;
649             this.bUuri = bindingUuri;
650         }
651         
652         public String JavaDoc getName() {
653             return bName;
654         }
655         
656         public String JavaDoc getUuri() {
657             return bUuri;
658         }
659         
660         public boolean equals( Object JavaDoc o ) {
661             boolean result = false;
662             if (o instanceof Binding) {
663                 Binding b = (Binding)o;
664                 result = getName().equals( b.getName() );
665             }
666             return result;
667         }
668         
669         public String JavaDoc toString() {
670             return bName+"->"+bUuri;
671         }
672     }
673     
674     /**
675      * Represents an binding bindingName -> UURI
676      */

677     public static class ParentBinding extends Binding {
678         
679         public ParentBinding(String JavaDoc bindingName, String JavaDoc bindingUuri) {
680             super(bindingName, bindingUuri);
681         }
682         
683         public boolean equals( Object JavaDoc o ) {
684             boolean result = false;
685             if (o instanceof ParentBinding) {
686                 ParentBinding b = (ParentBinding)o;
687                 result =
688                     getName().equals(b.getName()) &&
689                     this.getUuri().equals(b.getUuri());
690             }
691             return result;
692         }
693         
694         public String JavaDoc toString() {
695             return bName+":"+bUuri;
696         }
697     }
698     
699     public static class ParentBindingList extends BindingList {
700         
701         public ParentBindingList() {
702             super();
703         }
704         
705         public ParentBindingList(Vector JavaDoc container) {
706             super(container);
707         }
708         
709         protected Enumeration JavaDoc elements() {
710             return container.elements();
711         }
712         
713         protected Binding put(String JavaDoc bindingName, ObjectNode source) {
714             String JavaDoc uuri = "";
715             if (source != null && source.getUuri() != null) {
716                 uuri = source.getUuri();
717             }
718             int i = container.indexOf( new ParentBinding(bindingName, uuri) );
719             ParentBinding result = null;
720             if (i >= 0) {
721                 result = (ParentBinding)container.get(i);
722                 container.set( i, new ParentBinding(bindingName, uuri) );
723             }
724             else {
725                 container.add( new ParentBinding(bindingName, uuri) );
726             }
727             return result;
728         }
729         
730         protected void remove(String JavaDoc bindingName, String JavaDoc uuri) {
731             container.removeElement( new ParentBinding(bindingName, uuri) );
732         }
733         
734         public synchronized Object JavaDoc clone() {
735             return new ParentBindingList( (Vector JavaDoc)container.clone() );
736         }
737         
738         public String JavaDoc toString() {
739             return String.valueOf(container);
740         }
741     }
742     
743     public static class BindingList implements Serializable JavaDoc, Cloneable JavaDoc {
744         
745         protected Vector JavaDoc container;
746         
747         public BindingList() {
748             this.container = new Vector JavaDoc();
749         }
750         
751         public BindingList(Vector JavaDoc container) {
752             this.container = container;
753         }
754         
755         protected Enumeration JavaDoc elements() {
756             return container.elements();
757         }
758         
759         public Binding get(String JavaDoc bindingName) {
760             Binding b = null;
761             int i = container.indexOf( new Binding(bindingName, null) );
762             if (i >= 0) {
763                 b = (Binding)container.get(i);
764             }
765             return b;
766         }
767         
768         protected Binding put(String JavaDoc bindingName, ObjectNode source) {
769             Binding result = null;
770             String JavaDoc uuri = "";
771             if (source != null && source.getUuri() != null) {
772                 uuri = source.getUuri();
773             }
774             int i = container.indexOf( new Binding(bindingName, null) );
775             if (i >= 0) {
776                 result = (Binding)container.get(i);
777                 container.set( i, new Binding(bindingName, uuri) );
778             }
779             else {
780                 container.add( new Binding(bindingName, uuri) );
781             }
782             return result;
783         }
784         
785         protected void remove(String JavaDoc bindingName) {
786             container.removeElement( new Binding(bindingName, null) );
787         }
788         
789         public synchronized Object JavaDoc clone() {
790             return new BindingList( (Vector JavaDoc)container.clone() );
791         }
792         
793         public String JavaDoc toString() {
794             return String.valueOf(container);
795         }
796         
797         public int size() {
798             return container.size();
799         }
800     }
801 }
802
803
Popular Tags