KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > util > AbstractNode


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10
11 package org.mmbase.bridge.util;
12
13 import java.util.*;
14 import java.io.*;
15
16 import java.text.Collator JavaDoc;
17
18 import org.mmbase.bridge.*;
19 import org.mmbase.bridge.implementation.BasicFieldValue;
20 import org.mmbase.datatypes.DataType;
21 import org.mmbase.util.functions.*;
22 import org.mmbase.util.logging.*;
23 import org.mmbase.util.*;
24
25 import org.w3c.dom.Element JavaDoc;
26 import org.w3c.dom.Document JavaDoc;
27
28 /**
29  * Abstract implementation of Node.
30  * All methods which are based on other methods are implemented
31  * here, to minimalize the implementation effort of fully implemented Nodes.
32  *
33  * @author Michiel Meeuwissen
34  * @version $Id: AbstractNode.java,v 1.14 2006/05/26 18:32:06 nklasens Exp $
35  * @see org.mmbase.bridge.Node
36  * @since MMBase-1.8
37  */

38 public abstract class AbstractNode implements Node {
39     private static final Logger log = Logging.getLoggerInstance(AbstractNode.class);
40
41     protected static final int ACTION_CREATE = 1; // create a node
42
protected static final int ACTION_EDIT = 2; // edit node, or change aliasses
43
protected static final int ACTION_DELETE = 3; // delete node
44
protected static final int ACTION_COMMIT = 10; // commit a node after changes
45

46     protected abstract void edit(int action);
47
48     public boolean isRelation() {
49         return false;
50     }
51
52     public Relation toRelation() {
53         throw new ClassCastException JavaDoc("The node " + this + " is not a relation, (but a " + getClass() + ")");
54     }
55
56     public boolean isNodeManager() {
57         return false;
58     }
59
60     public NodeManager toNodeManager() {
61         throw new ClassCastException JavaDoc("The node " + this + " is not a node manager , (but a " + getClass() + ")");
62     }
63
64     public boolean isRelationManager() {
65         return false;
66     }
67
68     public RelationManager toRelationManager() {
69         throw new ClassCastException JavaDoc("The node " + this + " is not a relation manager , (but a " + getClass() + ")");
70     }
71
72     public boolean isNull(String JavaDoc fieldName) {
73         return getValueWithoutProcess(fieldName) == null;
74     }
75
76     public int getNumber() {
77         return Casting.toInt(getValueWithoutProcess("number"));
78     }
79
80     /**
81      * Setting value with default method (depending on field's type)
82      * @param fieldName name of the field
83      * @param value set value
84      */

85     public final void setValue(String JavaDoc fieldName, Object JavaDoc value) {
86         Field field = getNodeManager().getField(fieldName);
87         if (value == null) {
88             setValueWithoutProcess(fieldName, value);
89         } else {
90             value = field.getDataType().cast(value, this, field);
91             switch(field.getDataType().getBaseType()) {
92             case Field.TYPE_STRING: setStringValue(fieldName, (String JavaDoc) value); break;
93             case Field.TYPE_INTEGER: setIntValue(fieldName, Casting.toInt(value)); break;
94             case Field.TYPE_BINARY: {
95                 long length = getSize(fieldName);
96                 setInputStreamValue(fieldName, Casting.toInputStream(value), length); break;
97             }
98             case Field.TYPE_FLOAT: setFloatValue(fieldName, Casting.toFloat(value)); break;
99             case Field.TYPE_DOUBLE: setDoubleValue(fieldName, Casting.toDouble(value)); break;
100             case Field.TYPE_LONG: setLongValue(fieldName, Casting.toLong(value)); break;
101             case Field.TYPE_XML: setXMLValue(fieldName, (Document JavaDoc) value); break;
102             case Field.TYPE_NODE: setNodeValue(fieldName, Casting.toNode(value, getCloud())); break;
103             case Field.TYPE_DATETIME: setDateValue(fieldName, (Date) value); break;
104             case Field.TYPE_BOOLEAN: setBooleanValue(fieldName, Casting.toBoolean(value)); break;
105             case Field.TYPE_LIST: setListValue(fieldName, (List) value); break;
106             default: setObjectValue(fieldName, value);
107             }
108         }
109     }
110
111     /**
112      * Like setObjectValue, but without processing, this is called by the other set-values.
113      * @param fieldName name of field
114      * @param value new value of the field
115      * @todo setting certain specific fields (i.e. snumber) should be directed to a dedicated
116      * method such as setSource(), where applicable.
117      * @since MMBase-1.7
118      */

119     public void setValueWithoutProcess(String JavaDoc fieldName, Object JavaDoc value) {
120         edit(ACTION_EDIT);
121         if ("owner".equals(fieldName)) {
122             setContext(Casting.toString(value));
123             return;
124         }
125         if ("number".equals(fieldName) || "otype".equals(fieldName)) {
126             throw new BridgeException("Not allowed to change field '" + fieldName + "'.");
127         }
128         setValueWithoutChecks(fieldName, value);
129     }
130
131     protected abstract void setValueWithoutChecks(String JavaDoc fieldName, Object JavaDoc value);
132
133     public final void setObjectValue(String JavaDoc fieldName, Object JavaDoc value) {
134         Field field = getNodeManager().getField(fieldName);
135         value = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_UNKNOWN).process(this, field, value);
136         setValueWithoutProcess(fieldName, value);
137     }
138
139     public final void setBooleanValue(String JavaDoc fieldName,final boolean value) {
140         Field field = getNodeManager().getField(fieldName);
141         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_BOOLEAN).process(this, field, Boolean.valueOf(value));
142         setValueWithoutProcess(fieldName, v);
143     }
144
145     public final void setDateValue(String JavaDoc fieldName, final Date value) {
146         Field field = getNodeManager().getField(fieldName);
147         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_DATETIME).process(this, field, value);
148         setValueWithoutProcess(fieldName, v);
149     }
150
151     public final void setListValue(String JavaDoc fieldName, final List value) {
152         Field field = getNodeManager().getField(fieldName);
153         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_LIST).process(this, field, value);
154         setValueWithoutProcess(fieldName, v);
155     }
156
157     /**
158      * A method to convert an object to an node number.
159      * Default impelmentation is reasonable, but does not support core objects.
160      */

161     protected Integer JavaDoc toNodeNumber(Object JavaDoc v) {
162         if (v == null) {
163             return null;
164         } else if (v instanceof Node) {
165             return new Integer JavaDoc(((Node)v).getNumber());
166         } else {
167             // giving up
168
return new Integer JavaDoc(getCloud().getNode(v.toString()).getNumber());
169         }
170     }
171
172     public final void setNodeValue(String JavaDoc fieldName, final Node value) {
173         Field field = getNodeManager().getField(fieldName);
174         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_NODE).process(this, field, value);
175         setValueWithoutProcess(fieldName, toNodeNumber(v));
176     }
177
178     public final void setIntValue(String JavaDoc fieldName, final int value) {
179         Field field = getNodeManager().getField(fieldName);
180         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_INTEGER).process(this, field, new Integer JavaDoc(value));
181         setValueWithoutProcess(fieldName, v);
182     }
183
184     public final void setLongValue(String JavaDoc fieldName, final long value) {
185         Field field = getNodeManager().getField(fieldName);
186         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_LONG).process(this, field, new Long JavaDoc(value));
187         setValueWithoutProcess(fieldName, v);
188     }
189
190     public final void setFloatValue(String JavaDoc fieldName, final float value) {
191         Field field = getNodeManager().getField(fieldName);
192         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_FLOAT).process(this, field, new Float JavaDoc(value));
193         setValueWithoutProcess(fieldName, v);
194     }
195
196     public final void setDoubleValue(String JavaDoc fieldName, final double value) {
197         Field field = getNodeManager().getField(fieldName);
198         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_DOUBLE).process(this, field, new Double JavaDoc(value));
199         setValueWithoutProcess(fieldName, v);
200     }
201
202     public final void setByteValue(String JavaDoc fieldName, final byte[] value) {
203         Field field = getNodeManager().getField(fieldName);
204         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_BINARY).process(this, field, value);
205         setValueWithoutProcess(fieldName, v);
206     }
207
208     protected abstract void setSize(String JavaDoc fieldName, long size);
209
210     private static final int readLimit = 10 * 1024 * 1024;
211
212     public final void setInputStreamValue(String JavaDoc fieldName, final InputStream value, long size) {
213         setSize(fieldName, size);
214         Field field = getNodeManager().getField(fieldName);
215         if (log.isDebugEnabled()) {
216             log.debug("Setting binary value for " + field);
217         }
218         Object JavaDoc v = value;
219         try {
220             if (value.markSupported() && size < readLimit) {
221                 if (log.isDebugEnabled()) {
222                     log.debug("Mark supported and using " + field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_BINARY));
223                 }
224                 value.mark(readLimit);
225                 v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_BINARY).process(this, field, value);
226                 value.reset();
227             } else {
228                 if (field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_BINARY) != null) {
229                     if (log.isDebugEnabled()) {
230                         log.debug("Mark not supported but using " + field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_BINARY));
231                     }
232                     // well, we must read it to byte-array then, first.
233
ByteArrayOutputStream b = new ByteArrayOutputStream((int) size);
234                     int c;
235                     while((c = value.read()) > -1) {
236                         b.write(c);
237                     }
238                     byte[] byteArray = b.toByteArray();
239                     v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_BINARY).process(this, field, byteArray);
240                 } else {
241                     log.debug("Mark not support but no need for processing");
242                     v = value;
243                 }
244             }
245         } catch (IOException ioe) {
246             log.error(ioe);
247         }
248         setValueWithoutProcess(fieldName, v);
249     }
250
251     public final void setStringValue(final String JavaDoc fieldName, final String JavaDoc value) {
252         Field field = getNodeManager().getField(fieldName);
253         Object JavaDoc setValue = field.getDataType().preCast(value, this, field); // to resolve enumerations
254
Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_STRING).process(this, field, setValue);
255         setValueWithoutProcess(fieldName, v);
256     }
257
258     public final void setXMLValue(String JavaDoc fieldName, final Document JavaDoc value) {
259         Field field = getNodeManager().getField(fieldName);
260         Object JavaDoc v = field.getDataType().getProcessor(DataType.PROCESS_SET, Field.TYPE_XML).process(this, field, value);
261         setValueWithoutProcess(fieldName, v);
262     }
263
264     public final Object JavaDoc getValue(String JavaDoc fieldName) {
265         Object JavaDoc value = getValueWithoutProcess(fieldName);
266         if (value == null) return null;
267         NodeManager nm = getNodeManager();
268         if (nm.hasField(fieldName)) {
269             int type = nm.getField(fieldName).getType();
270             switch(type) {
271                 case Field.TYPE_STRING: return getStringValue(fieldName);
272                 case Field.TYPE_BINARY: return getByteValue(fieldName);
273                 case Field.TYPE_INTEGER: return new Integer JavaDoc(getIntValue(fieldName));
274                 case Field.TYPE_FLOAT: return new Float JavaDoc(getFloatValue(fieldName));
275                 case Field.TYPE_DOUBLE: return new Double JavaDoc(getDoubleValue(fieldName));
276                 case Field.TYPE_LONG: return new Long JavaDoc(getLongValue(fieldName));
277                 case Field.TYPE_XML: return getXMLValue(fieldName);
278                 case Field.TYPE_NODE: {
279                     // number is a NODE field, but should be returned as
280
// a number (in this case, a long)
281
// in the future, we may change the basic MMBase type for the number field to ID
282
if ("number".equals(fieldName)) {
283                         return new Long JavaDoc(getLongValue(fieldName));
284                     } else {
285                         return getNodeValue(fieldName);
286                     }
287                 }
288                 case Field.TYPE_BOOLEAN: return Boolean.valueOf(getBooleanValue(fieldName));
289                 case Field.TYPE_DATETIME:return getDateValue(fieldName);
290                 case Field.TYPE_LIST: return getListValue(fieldName);
291                 default:
292                     log.error("Unknown fieldtype '" + type + "'");
293                     return value;
294             }
295         } else {
296             //log.warn("Requesting value of unknown field '" + fieldName + "')");
297
return value;
298         }
299
300     }
301
302     public final Object JavaDoc getObjectValue(String JavaDoc fieldName) {
303         Object JavaDoc result = getValueWithoutProcess(fieldName);
304         NodeManager nodeManager = getNodeManager();
305         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
306
Field field = nodeManager.getField(fieldName);
307             Object JavaDoc r = field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_UNKNOWN).process(this, field, result);
308             if ((result != null && (! result.equals(r)))) {
309                 log.info("getObjectvalue was processed! " + result + " != " + r);
310                 result = r;
311             }
312         }
313         return result;
314     }
315
316     public boolean getBooleanValue(String JavaDoc fieldName) {
317         Boolean JavaDoc result = Casting.toBoolean(getValueWithoutProcess(fieldName)) ? Boolean.TRUE : Boolean.FALSE; // odd.
318
NodeManager nodeManager = getNodeManager();
319         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
320
Field field = getNodeManager().getField(fieldName);
321             result = (Boolean JavaDoc) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_BOOLEAN).process(this, field, result);
322         }
323         return result.booleanValue();
324     }
325
326     public Date getDateValue(String JavaDoc fieldName) {
327         Date result = Casting.toDate(getValueWithoutProcess(fieldName));
328         NodeManager nodeManager = getNodeManager();
329         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
330
Field field = nodeManager.getField(fieldName);
331             result = (Date) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_DATETIME).process(this, field, result);
332         }
333         return result;
334     }
335
336     public List getListValue(String JavaDoc fieldName) {
337         List result = Casting.toList(getValueWithoutProcess(fieldName));
338         NodeManager nodeManager = getNodeManager();
339         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
340
Field field = nodeManager.getField(fieldName);
341             result = (List) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_LIST).process(this, field, result);
342         }
343         return result;
344     }
345
346     public int getIntValue(String JavaDoc fieldName) {
347         Integer JavaDoc result = Casting.toInteger(getValueWithoutProcess(fieldName));
348         NodeManager nodeManager = getNodeManager();
349         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
350
Field field = nodeManager.getField(fieldName);
351             result = (Integer JavaDoc) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_INTEGER).process(this, field, result);
352         }
353         return result.intValue();
354     }
355
356     public float getFloatValue(String JavaDoc fieldName) {
357         Float JavaDoc result = new Float JavaDoc(Casting.toFloat(getValueWithoutProcess(fieldName)));
358         NodeManager nodeManager = getNodeManager();
359         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
360
Field field = nodeManager.getField(fieldName);
361             result = (Float JavaDoc) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_FLOAT).process(this, field, result);
362         }
363         return result.floatValue();
364     }
365
366     public long getLongValue(String JavaDoc fieldName) {
367         Long JavaDoc result = new Long JavaDoc(Casting.toLong(getValueWithoutProcess(fieldName)));
368         NodeManager nodeManager = getNodeManager();
369         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
370
Field field = nodeManager.getField(fieldName);
371             result = (Long JavaDoc) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_LONG).process(this, field, result);
372         }
373         return result.longValue();
374     }
375
376     public double getDoubleValue(String JavaDoc fieldName) {
377         Double JavaDoc result = new Double JavaDoc(Casting.toDouble(getValueWithoutProcess(fieldName)));
378         NodeManager nodeManager = getNodeManager();
379         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
380
Field field = nodeManager.getField(fieldName);
381             result = (Double JavaDoc) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_DOUBLE).process(this, field, result);
382         }
383         return result.doubleValue();
384     }
385
386     public byte[] getByteValue(String JavaDoc fieldName) {
387         byte[] result = Casting.toByte(getValueWithoutProcess(fieldName));
388         NodeManager nodeManager = getNodeManager();
389         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
390
Field field = nodeManager.getField(fieldName);
391             result = (byte[]) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_BINARY).process(this, field, result);
392         }
393         return result;
394     }
395
396     public java.io.InputStream JavaDoc getInputStreamValue(String JavaDoc fieldName) {
397         java.io.InputStream JavaDoc result = Casting.toInputStream(getValueWithoutProcess(fieldName));
398         NodeManager nodeManager = getNodeManager();
399         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
400
Field field = nodeManager.getField(fieldName);
401             result = (java.io.InputStream JavaDoc) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_BINARY).process(this, field, result);
402         }
403         return result;
404     }
405
406     public String JavaDoc getStringValue(String JavaDoc fieldName) {
407         String JavaDoc result = Casting.toString(getValueWithoutProcess(fieldName));
408         NodeManager nodeManager = getNodeManager();
409         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
410
Field field = nodeManager.getField(fieldName);
411             result = (String JavaDoc) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_STRING).process(this, field, result);
412         }
413         return result;
414     }
415
416     public Document JavaDoc getXMLValue(String JavaDoc fieldName) {
417         Document JavaDoc result = Casting.toXML(getValueWithoutProcess(fieldName));
418         NodeManager nodeManager = getNodeManager();
419         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
420
Field field = nodeManager.getField(fieldName);
421             result = (Document JavaDoc) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_XML).process(this, field, result);
422         }
423         return result;
424     }
425
426     public Node getNodeValue(String JavaDoc fieldName) {
427         Node result = Casting.toNode(getValueWithoutProcess(fieldName), getCloud());
428         NodeManager nodeManager = getNodeManager();
429         if (nodeManager.hasField(fieldName)) { // gui(..) stuff could not work.
430
Field field = nodeManager.getField(fieldName);
431             result = (Node) field.getDataType().getProcessor(DataType.PROCESS_GET, Field.TYPE_NODE).process(this, field, result);
432         }
433         return result;
434     }
435
436     public final FieldValue getFieldValue(String JavaDoc fieldName) throws NotFoundException {
437         return new BasicFieldValue(this, getNodeManager().getField(fieldName));
438     }
439
440     public final FieldValue getFieldValue(Field field) {
441         return new BasicFieldValue(this, field);
442     }
443
444     public final Element JavaDoc getXMLValue(String JavaDoc fieldName, Document JavaDoc tree) {
445         Document JavaDoc doc = getXMLValue(fieldName);
446         if (doc == null) {
447             return null;
448         }
449         return (Element JavaDoc)tree.importNode(doc.getDocumentElement(), true);
450     }
451
452     protected final void processCommit() {
453         FieldIterator fi = getNodeManager().getFields().fieldIterator();
454         while (fi.hasNext()) {
455             Field field = fi.nextField();
456             field.getDataType().getCommitProcessor().commit(this, field);
457         }
458     }
459
460     public Collection validate() {
461         List errors = new ArrayList();
462         FieldIterator fi = getNodeManager().getFields().fieldIterator();
463         Locale locale = getCloud().getLocale();
464         while (fi.hasNext()) {
465             Field field = fi.nextField();
466             if (! field.isReadOnly() && !field.isVirtual()) {
467                 // don't validate read-only fields. Users cannot have edited those. Most noticably,
468
// the _number_ field must not be validated, because for new nodes it does not yet
469
// point to an existing node... I think the number field should not be a NODE field...
470
Object JavaDoc value = getValueWithoutProcess(field.getName());
471                 Collection fieldErrors = field.getDataType().validate(value, this, field);
472                 Iterator i = fieldErrors.iterator();
473                 while(i.hasNext()) {
474                     LocalizedString error = (LocalizedString) i.next();
475                     errors.add("field '" + field.getName() + "' with value '" + value + "': " + // TODO need to i18n this intro too
476
error.get(locale));
477                 }
478             }
479         }
480         return errors;
481     }
482
483     public final void delete() {
484         delete(false);
485     }
486
487     public final void deleteRelations() {
488         deleteRelations("object");
489     }
490
491     public final RelationList getRelations() {
492         return getRelations(null, (String JavaDoc) null);
493     }
494
495     public final RelationList getRelations(String JavaDoc role) {
496         return getRelations(role, (String JavaDoc) null);
497     }
498
499     public final RelationList getRelations(String JavaDoc role, NodeManager nodeManager) {
500         if (nodeManager == null) {
501             return getRelations(role);
502         } else {
503             return getRelations(role, nodeManager.getName());
504         }
505     }
506
507     public final int countRelations() {
508         return countRelatedNodes(getCloud().getNodeManager("object"), null, "BOTH");
509     }
510
511     public final int countRelations(String JavaDoc type) {
512         //err
513
return countRelatedNodes(getCloud().getNodeManager("object"), type, "BOTH");
514     }
515
516     public final NodeList getRelatedNodes() {
517         return getRelatedNodes("object", null, null);
518     }
519
520     public final NodeList getRelatedNodes(String JavaDoc type) {
521         return getRelatedNodes(type, null, null);
522     }
523
524     public final NodeList getRelatedNodes(NodeManager nodeManager) {
525         return getRelatedNodes(nodeManager, null, null);
526     }
527
528     public final NodeList getRelatedNodes(String JavaDoc type, String JavaDoc role, String JavaDoc searchDir) {
529         return getRelatedNodes(getCloud().getNodeManager(type), role, searchDir);
530     }
531
532     public Relation createRelation(Node destinationNode, RelationManager relationManager) {
533         Relation relation = relationManager.createRelation(this, destinationNode);
534         return relation;
535     }
536
537     /**
538      * Compares this node to the passed object.
539      * Returns 0 if they are equal, -1 if the object passed is a NodeManager and larger than this manager,
540      * and +1 if the object passed is a NodeManager and smaller than this manager.
541      * This is used to sort Nodes.
542      * A node is 'larger' than another node if its GUI() result is larger (alphabetically, case sensitive)
543      * than that of the other node. If the GUI() results are the same, the nodes are compared on number,
544      * and (if needed) on their owning clouds.
545      *
546      * @param o the object to compare it with
547      * @return 0 if they are equal, -1 if the object passed is a NodeManager and larger than this manager,
548      * and +1 if the object passed is a NodeManager and smaller than this manager.
549      */

550     public final int compareTo(Object JavaDoc o) {
551         Node n = (Node)o;
552         String JavaDoc s1 = "";
553         if (this instanceof NodeManager) {
554             s1 = ((NodeManager)this).getGUIName();
555         } else {
556             s1 = getFunctionValue("gui", null).toString();
557         }
558         String JavaDoc s2 = "";
559         if (n instanceof NodeManager) {
560             s2 = ((NodeManager)n).getGUIName();
561         } else {
562             s2 = n.getFunctionValue("gui", null).toString();
563         }
564         Collator JavaDoc col = Collator.getInstance(getCloud().getLocale());
565         col.setStrength(Collator.PRIMARY);
566         int res = col.compare(s1, s2);
567         if (res != 0) {
568             return res;
569         } else {
570             res = s1.compareTo(s2);
571             if (res != 0) return res;
572
573             int n1 = getNumber();
574             int n2 = n.getNumber();
575             if (n2 > n1) {
576                 return -1;
577             } else if (n2 < n1) {
578                 return -1;
579             } else {
580                 Cloud c = getCloud();
581                 if (c instanceof Comparable JavaDoc) {
582                     return ((Comparable JavaDoc) c).compareTo(n.getCloud());
583                 } else {
584                     return 0;
585                 }
586             }
587         }
588     }
589
590     public boolean isNew() {
591         return false;
592     }
593
594     public boolean isChanged(String JavaDoc fieldName) {
595         return false;
596     }
597
598     public boolean isChanged() {
599         return false;
600     }
601     public Set getChanged() {
602         return Collections.EMPTY_SET;
603     }
604
605     public void commit() {
606         throw new UnsupportedOperationException JavaDoc("Cannot edit virtual node");
607     }
608
609     public void cancel() {
610     }
611
612     public void delete(boolean deleteRelations) {
613         throw new UnsupportedOperationException JavaDoc("Cannot edit virtual node");
614     }
615
616     public void deleteRelations(String JavaDoc type) throws NotFoundException {
617     }
618
619     public RelationList getRelations(String JavaDoc role, NodeManager nodeManager, String JavaDoc searchDir) throws NotFoundException {
620         return BridgeCollections.EMPTY_RELATIONLIST;
621     }
622     public RelationList getRelations(String JavaDoc role, String JavaDoc nodeManager) throws NotFoundException {
623         return BridgeCollections.EMPTY_RELATIONLIST;
624     }
625
626     public boolean hasRelations() {
627         return false;
628     }
629
630     public int countRelatedNodes(NodeManager otherNodeManager, String JavaDoc role, String JavaDoc direction) {
631         return 0;
632     }
633
634     public int countRelatedNodes(String JavaDoc type) {
635         return 0;
636     }
637
638     public NodeList getRelatedNodes(NodeManager nodeManager, String JavaDoc role, String JavaDoc searchDir) {
639         return BridgeCollections.EMPTY_NODELIST;
640     }
641
642     public StringList getAliases() {
643         return BridgeCollections.EMPTY_STRINGLIST;
644     }
645
646     public void createAlias(String JavaDoc aliasName) {
647         throw new UnsupportedOperationException JavaDoc("Virtual nodes have no aliases");
648     }
649
650     public void deleteAlias(String JavaDoc aliasName) {
651         throw new UnsupportedOperationException JavaDoc("Virtual nodes have no aliases");
652     }
653
654     public void setContext(String JavaDoc context) {
655         throw new UnsupportedOperationException JavaDoc("Virtual nodes have no security context");
656     }
657
658     // javadoc inherited (from Node)
659
public String JavaDoc getContext() {
660         throw new UnsupportedOperationException JavaDoc("Virtual nodes have no security context");
661     }
662
663     // javadoc inherited (from Node)
664
public StringList getPossibleContexts() {
665         return BridgeCollections.EMPTY_STRINGLIST;
666     }
667
668     public boolean mayWrite() {
669         return false;
670     }
671
672     public boolean mayDelete() {
673         return false;
674     }
675
676     public boolean mayChangeContext() {
677         return false;
678     }
679
680     /**
681      * Compares two nodes, and returns true if they are equal.
682      * This effectively means that both objects are nodes, and they both have the same number and cloud
683      * @param o the object to compare it with
684      *
685      * @see java.lang.Object#equals(java.lang.Object)
686      */

687     public final boolean equals(Object JavaDoc o) {
688         return (o instanceof Node) && getNumber() == ((Node)o).getNumber() && getCloud().equals(((Node)o).getCloud());
689     }
690
691
692     public Parameters createParameters(String JavaDoc functionName) {
693         return getNodeFunction(functionName).createParameters();
694     }
695
696     protected FieldValue createFunctionValue(final Object JavaDoc result) {
697         return new AbstractFieldValue(this, getCloud()) {
698             public Object JavaDoc get() {
699                 return result;
700             }
701         };
702     }
703
704     public FieldValue getFunctionValue(String JavaDoc functionName, List parameters) {
705         Function function = getFunction(functionName);
706         Parameters params = function.createParameters();
707         params.setAll(parameters);
708         return createFunctionValue(function.getFunctionValue(params));
709     }
710
711     protected Function getNodeFunction(String JavaDoc functionName) {
712         return null;
713     }
714
715     public final Function getFunction(String JavaDoc functionName) {
716         Function function = getNodeFunction(functionName);
717         if (function == null) {
718             throw new NotFoundException("Function with name " + functionName + " does not exist on node " + getNumber() + " of type " + getNodeManager().getName() + "(known are " + getFunctions() + ")");
719         }
720         return new WrappedFunction(function) {
721                 public final Object JavaDoc getFunctionValue(Parameters params) {
722                     params.setIfDefined(Parameter.NODE, AbstractNode.this);
723                     params.setIfDefined(Parameter.CLOUD, AbstractNode.this.getCloud());
724                     return AbstractNode.this.createFunctionValue(super.getFunctionValue(params)).get();
725                 }
726             };
727     }
728
729 }
730
Popular Tags