KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > module > corebuilders > InsRel


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 package org.mmbase.module.corebuilders;
11
12 import java.util.*;
13
14 import org.mmbase.core.CoreField;
15 import org.mmbase.storage.search.*;
16 import org.mmbase.storage.search.implementation.*;
17 import org.mmbase.cache.Cache;
18 import org.mmbase.module.core.*;
19 import org.mmbase.util.logging.*;
20
21 /**
22  *
23  * InsRel, the main relation object, holds relations, and methods to
24  * handle them. An insrel defines a relation between two objects.
25  * <p>
26  * This class can be extended to create insrels that can also hold
27  * extra values and custom methods (named relations for example).
28  * </p>
29  *
30  * @author Daniel Ockeloen
31  * @author Pierre van Rooden
32  * @version $Id: InsRel.java,v 1.49.2.2 2006/10/12 11:33:42 pierre Exp $
33  */

34 public class InsRel extends MMObjectBuilder {
35
36     /** Base 'insrel' builder name */
37     public static final String JavaDoc INSREL_BUILDER = "insrel";
38
39     /** Name of the field containing the source object number */
40     public static final String JavaDoc FIELD_SNUMBER = "snumber";
41     /** Name of the field containing the source object number */
42     public static final String JavaDoc FIELD_SOURCE = FIELD_SNUMBER;
43     /** Name of the field containing the destination object number */
44     public static final String JavaDoc FIELD_DNUMBER = "dnumber";
45     /** Name of the field containing the destination object number */
46     public static final String JavaDoc FIELD_DESTINATION = FIELD_DNUMBER;
47     /** Name of the field containing the role (reldef) object number */
48     public static final String JavaDoc FIELD_RNUMBER = "rnumber";
49     /** Name of the field containing the role (reldef) object number */
50     public static final String JavaDoc FIELD_ROLE = FIELD_RNUMBER;
51     /** Name of the field containing the directionality */
52     public static final String JavaDoc FIELD_DIR = "dir";
53     /** Name of the field containing the directionality */
54     public static final String JavaDoc FIELD_DIRECTIONALITY = FIELD_DIR;
55
56     private static final Logger log = Logging.getLoggerInstance(InsRel.class);
57
58     /**
59      * Indicates whether the relations use the 'dir' field (that is, whether the
60      * field has been defined in the xml file). Used for backward compatibility.
61      * The default is <code>true</code> - the value is set to <code>false</code> if any of the
62      * relation builders does not contain a <code>dir</code> field (a warning is issued).
63      */

64     public static boolean usesdir = true;
65
66     /**
67      * Hold the relnumber to use when creating a node of this builder.
68      */

69     public int relnumber = -1;
70
71     /**
72      * Cache system, holds the relations from the 25
73      * most used relations
74      * @todo Is this cache still used?
75      */

76
77     private Cache relatedCache = new Cache(25) {
78         public String JavaDoc getName() { return "RelatedCache"; }
79         public String JavaDoc getDescription() { return "Cache for Related Nodes"; }
80         };
81
82
83     /* perhaps this would be nice?
84     private Cache relationsCache = new Cache(25) {
85         public String getName() { return "RelationsCache"; }
86         public String getDescription() { return "Cache for Relations"; }
87         };
88     */

89
90
91     /**
92      * needed for autoload
93      */

94     public InsRel() {
95         relatedCache.putCache();
96         // relationsCache.putCache();
97
}
98
99     /**
100      * Initializes the builder. Determines whether the <code>dir</code> field is defined (and thus whether directionality is supported).
101      * If the field cannot be found, a <em>"Warning: No dir field. Directionality support turned off."</em> warning message is issued.
102      * @return A <code>boolean</code> value, always success (<code>true</code>), as any exceptions are
103      * caught and logged.
104      * @see #usesdir
105      */

106     public boolean init() {
107         CoreField dirField = getField(FIELD_DIRECTIONALITY);
108         boolean hasDirField = dirField != null && dirField.inStorage();
109         if (!created()) {
110             // check whether directionality is in use, and whether a dir field is present.
111
// if a non-dir supporting builder is attempted to be used, a fatal error is logged.
112
// the table is not created. MMbase continues, but anny atept to use this builder will fail
113
// (one way or the other).
114
// If the builder to be created is insrel (the basic builder), the system ignores the error
115
// and continues without directionality (backward compatibility).
116
//
117
if (usesdir && !hasDirField && (!getTableName().equals(INSREL_BUILDER))) {
118                 log.fatal("FATAL ERROR: Builder "+getTableName()+" has no dir field but directionality support was turned on.");
119                 log.fatal("Table for "+getTableName()+" was NOT created.");
120                 log.fatal("MMBase continues, but use of the "+getTableName()+" builder will fail.");
121                 return false;
122             }
123         }
124         boolean res=super.init();
125         checkAddTmpField("_dnumber");
126         checkAddTmpField("_snumber");
127         if (res && usesdir && !hasDirField) {
128             log.warn("No dir field. Directionality support turned off.");
129             usesdir = false;
130         }
131         return res;
132     }
133
134     /**
135      * Fixes a relation node. Determines the source and destination numbers, and checks the object
136      * types against the types specified in the relation definition ( {@link TypeRel} ). If the
137      * types differ, the source and destination are likely mis-aligned, and if the relation in the
138      * other direction is indeed allowed, then they are swapped to produce a correct relation node.
139      *
140      * @param node The node to fix
141      * @return The node again
142      */

143     private MMObjectNode alignRelNode(MMObjectNode node) {
144         int source = getNodeType(node.getIntValue(FIELD_SOURCE));
145         int destination = getNodeType(node.getIntValue(FIELD_DESTINATION));
146         int role = node.getIntValue(FIELD_ROLE);
147         TypeRel typeRel = mmb.getTypeRel();
148         if (!typeRel.reldefCorrect(source, destination, role) && typeRel.reldefCorrect(destination, source, role)) {
149             destination = node.getIntValue(FIELD_SOURCE);
150             node.setValue(FIELD_SOURCE, node.getIntValue(FIELD_DESTINATION));
151             node.setValue(FIELD_DESTINATION, destination);
152         }
153         return node;
154     }
155
156
157     /**
158      * Insert a new Instance Relation.
159      * @param owner Administrator
160      * @param source Identifying number of the source object
161      * @param destination Identifying number of the destination object
162      * @param role Identifying number of the relation defintition
163      * @return A <code>integer</code> value identifying the newly inserted relation
164      * @deprecated Use insert(String, MMObjectNode) instead.
165      */

166     public int insert(String JavaDoc owner, int source, int destination, int role) {
167         int result = -1;
168         MMObjectNode node = getNewNode(owner);
169         if( node != null ) {
170             node.setValue(FIELD_SOURCE, source);
171             node.setValue(FIELD_DESTINATION, destination);
172             node.setValue(FIELD_ROLE, role);
173             result = insert(owner, node);
174         } else {
175             log.error("insert(" + owner + "," + source + "," + destination + "," + role + "): Cannot create new node(" + node + ")!");
176         }
177         return result;
178     }
179
180
181     /**
182      * Insert a new Instance Relation.
183      * @param owner Administrator
184      * @param node Relation node to add
185      * @return A <code>integer</code> value identifying the newly inserted relation
186      */

187     public int insert(String JavaDoc owner, MMObjectNode node) {
188         int result = -1;
189         int source = node.getIntValue(FIELD_SOURCE);
190         if( source >= 0 ) {
191             int destination = node.getIntValue(FIELD_DESTINATION);
192             if( destination >= 0 ) {
193                 int role = node.getIntValue(FIELD_ROLE);
194                 if( role > 0 ) {
195                     if (usesdir) {
196                         MMObjectNode reldef = getNode(role);
197                         int dir = reldef.getIntValue(FIELD_DIRECTIONALITY);
198                         if (dir <= 0) dir = 2;
199                         node.setValue(FIELD_DIRECTIONALITY,dir);
200                     }
201                     node=alignRelNode(node);
202                     if (log.isDebugEnabled()) {
203                         log.debug("insert(" + owner + "," + node + ")");
204                     }
205                     result = super.insert(owner,node);
206                     // remove cache for these nodes (enforce update)
207
deleteRelationCache(source);
208                     deleteRelationCache(destination);
209                 } else {
210                     log.error("insert("+owner+","+node+"): rnumber("+ role +") is not greater than 0! (something is seriously wrong)");
211                 }
212             } else {
213                 log.error("insert("+owner+","+node+"): dnumber("+ destination +" is not greater than 0! (something is seriously wrong)");
214             }
215         } else {
216             log.error("insert("+owner+","+node+"): snumber(" + source + ") is not greater than 0! (something is seriously wrong)");
217         }
218         return result;
219     }
220
221     /**
222      * Remove a node from the cloud.
223      * @param node The node to remove.
224      */

225     public void removeNode(MMObjectNode node) {
226         int source = node.getIntValue(FIELD_SOURCE);
227         int destination = node.getIntValue(FIELD_DESTINATION);
228         super.removeNode(node);
229         deleteRelationCache(source);
230         deleteRelationCache(destination);
231     }
232
233     /**
234      * Get relation(s) for a MMObjectNode
235      * @param source Identifying number of the object to find the relations of.
236      * @return If succesful, an <code>Enumeration</code> listing the relations.
237      * If no relations exist, the method returns <code>null</code>.
238      * @see #getRelationsVector(int)
239      */

240     public Enumeration getRelations(int source) {
241         return getRelations(source,-1);
242     }
243
244     /**
245      * Get relation(s) for a MMObjectNode, using a specified role (reldef) as a filter
246      * @param source Identifying number of the object to find the relations of.
247      * @param role The number of the relation definition (role) to filter on
248      * @return an <code>Enumeration</code> listing the relations.
249      * @see #getRelationsVector(int, int)
250      */

251     public Enumeration getRelations(int source, int role) {
252         return getRelationsVector(source, role).elements();
253     }
254
255     /**
256      * Get relations for a specified MMObjectNode
257      * @param source this is the number of the MMObjectNode requesting the relations
258      * @param otype the object type of the nodes you want to have. -1 means any node.
259      * @param role Identifying number of the role (reldef)
260      * @return An <code>Enumeration</code> whose enumeration consists of <code>MMObjectNode</code> object related to the source
261      * according to the specified filter(s).
262      */

263     public Enumeration getRelations(int source, int otype, int role) {
264         return getRelations(source, otype, role, true);
265     }
266
267     /**
268      * Gets relations for a specified MMObjectNode
269      * @param source this is the number of the MMObjectNode requesting the relations
270      * @param otype the object type of the nodes you want to have. -1 means any node.
271      * @param role Identifying number of the role (reldef)
272      * @param usedirectionality if <code>true</code> teh result si filtered on unidirectional relations.
273      * specify <code>false</code> if you want to show unidoerctional relations
274      * from destination to source.
275      * @return An <code>Enumeration</code> whose enumeration consists of <code>MMObjectNode</code> object related to the source
276      * according to the specified filter(s).
277      */

278     public Enumeration getRelations(int source, int otype, int role, boolean usedirectionality) {
279         List re;
280         if (usedirectionality) {
281              re = getRelationsVector(source, role);
282         } else {
283              re = getAllRelationsVector(source, role);
284         }
285         if (otype==-1) {
286             return Collections.enumeration(re);
287         } else {
288             TypeDef typedef = mmb.getTypeDef();
289             MMObjectBuilder wantedBuilder = mmb.getBuilder(typedef.getValue(otype));
290             List list = new ArrayList();
291             for(Iterator e = re.iterator(); e.hasNext(); ) {
292                 MMObjectNode node = (MMObjectNode) e.next();
293                 int nodenr = node.getIntValue(FIELD_SOURCE);
294                 if (nodenr == source) {
295                     nodenr = node.getIntValue(FIELD_DESTINATION);
296                 }
297                 String JavaDoc tableName = typedef.getValue(getNodeType(nodenr));
298                 if (tableName != null) {
299                     MMObjectBuilder nodeBuilder = mmb.getBuilder(tableName);
300                     if (nodeBuilder != null && (nodeBuilder.equals(wantedBuilder) || nodeBuilder.isExtensionOf(wantedBuilder))) {
301                         list.add(node);
302                     }
303                 }
304             }
305             return Collections.enumeration(list);
306         }
307     }
308
309     /**
310      * Checks whether any relations exist for a MMObjectNode.
311      * This includes unidirection relations which would otherwise not be counted.
312      * If the query fails to execute, the system will assume that relations exists.
313      * @param source Identifying number of the object to find the relations of.
314      * @return <code>true</code> if any relations exist, <code>false</code> otherwise.
315      */

316     public boolean hasRelations(int source) {
317         try {
318             NodeSearchQuery query = new NodeSearchQuery(this);
319             BasicCompositeConstraint constraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_OR);
320             constraint.addChild(getNumberConstraint(query,FIELD_SOURCE, source));
321             constraint.addChild(getNumberConstraint(query,FIELD_DESTINATION, source));
322             query.setConstraint(constraint);
323             return count(query) != 0;
324         } catch (SearchQueryException sqe) {
325             log.error(sqe.getMessage()); // should not happen
326
return true; // perhaps yes?
327
}
328     }
329
330     // creates a constraint for a numeric field on a query
331
private BasicFieldValueConstraint getNumberConstraint(NodeSearchQuery query, String JavaDoc fieldName, int value) {
332         return new BasicFieldValueConstraint(query.getField(query.getBuilder().getField(fieldName)), new Integer JavaDoc(value));
333     }
334
335     /**
336      * Get relation(s) for an MMObjectNode, using a specified role (reldef) as a filter.
337      * This function returns all relations based on this role in which the node is either a source, or where the node is
338      * the destination, but the direction is bidirectional.
339      * @param source Identifying number of the object to find the relations of.
340      * @return A <code>List</code> containing the relation nodes.
341      * @throws SearchQueryException if a storage error occurs
342      */

343     public List getRelationNodes(int source) throws SearchQueryException {
344         return getRelationNodes(source, -1, usesdir);
345     }
346
347     /**
348      * Get relation(s) for a MMObjectNode.
349      * @deprecated use {@link #getRelationNodes(int)}
350      */

351     public Vector getRelationsVector(int source) {
352         try {
353             return new Vector(getRelationNodes(source, -1, usesdir));
354         } catch (SearchQueryException sqe) {
355             log.error(sqe.getMessage()); // should not happen
356
return new Vector(); //
357
}
358     }
359
360     /**
361      * Get relation(s) for an MMObjectNode, using a specified role (reldef) as a filter.
362      * This function returns all relations based on this role in which the node is either a source, or where the node is
363      * the destination, but the direction is bidirectional.
364      * @param source Identifying number of the object to find the relations of.
365      * @param role The number of the relation definition (role) to filter on, <code>-1</code> means any role
366      * @return A <code>List</code> containing the relation nodes.
367      * @throws SearchQueryException if a storage error occurs
368      */

369     public List getRelationNodes(int source, int role) throws SearchQueryException {
370         return getRelationNodes(source, role, usesdir);
371     }
372
373     /**
374      * Get relation(s) for a MMObjectNode, using a specified role.
375      * @deprecated use {@link #getRelationNodes(int, int, boolean)}
376      */

377     public Vector getRelationsVector(int source, int role) {
378         try {
379             return new Vector(getRelationNodes(source, role, usesdir));
380         } catch (SearchQueryException sqe) {
381             log.error(sqe.getMessage()); // should not happen
382
return new Vector(); //
383
}
384     }
385
386     /**
387      * Get all relation(s) for an MMObjectNode.
388      * This function returns all relations in which the node is either a source or
389      * the destination.
390      * @param source Identifying number of the object to find the relations of.
391      * @param useDirectionality if <code>truie</code>, take directionality into account.
392      * If <code>false</code>, returns all relations, even if the direction is unidirectional.
393      * @return A <code>List</code> containing the relation nodes.
394      * @throws SearchQueryException if a storage error occurs
395      */

396     public List getRelationNodes(int source, boolean useDirectionality) throws SearchQueryException {
397         return getRelationNodes(source, -1, useDirectionality);
398     }
399
400     /**
401      * Get all relation(s) for a MMObjectNode.
402      * @deprecated use {@link #getRelationNodes(int, boolean)}
403      */

404     public Vector getAllRelationsVector(int source) {
405         try {
406             return new Vector(getRelationNodes(source, -1, false));
407         } catch (SearchQueryException sqe) {
408             log.error(sqe.getMessage()); // should not happen
409
return new Vector(); //
410
}
411     }
412
413     /**
414      * Get all relation(s) for a MMObjectNode
415      * This function returns all relations in which the node is either a source or
416      * the destination.
417      * @param source Identifying number of the object to find the relations of.
418      * @param role The number of the relation definition (role) to filter on, <code>-1</code> means any role
419      * @param useDirectionality if <code>truie</code>, take directionality into account.
420      * If <code>false</code>, returns all relations, even if the direction is unidirectional.
421      * @return A <code>List</code> containing the relation nodes.
422      * @throws SearchQueryException if a storage error occurs
423      */

424     public List getRelationNodes(int source, int role, boolean useDirectionality) throws SearchQueryException {
425         MMObjectBuilder builder = this;
426         if (role != -1) {
427             builder = mmb.getRelDef().getBuilder(role);
428         }
429         NodeSearchQuery query = new NodeSearchQuery(builder);
430         BasicCompositeConstraint constraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_OR);
431         constraint.addChild(getNumberConstraint(query,FIELD_SOURCE, source));
432         Constraint destinationConstraint = getNumberConstraint(query,FIELD_DESTINATION, source);
433         if (useDirectionality) {
434             BasicFieldValueConstraint dirConstraint = getNumberConstraint(query,FIELD_DIRECTIONALITY, 1);
435             dirConstraint.setOperator(FieldCompareConstraint.NOT_EQUAL);
436             BasicCompositeConstraint compositeConstraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND);
437             compositeConstraint.addChild(destinationConstraint);
438             compositeConstraint.addChild(dirConstraint);
439             destinationConstraint = compositeConstraint;
440         }
441         constraint.addChild(destinationConstraint);
442         if (role != -1) {
443             BasicCompositeConstraint roleConstraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND);
444             roleConstraint.addChild(constraint);
445             roleConstraint.addChild(getNumberConstraint(query,FIELD_ROLE, role));
446             constraint = roleConstraint;
447         }
448         query.setConstraint(constraint);
449         List nodes = builder.getNodes(query);
450         return nodes;
451     }
452
453     /**
454      * Get all relation(s) for a MMObjectNode.
455      * @deprecated use {@link #getRelationNodes(int, int, boolean)}
456      */

457     public Vector getAllRelationsVector(int source, int role) {
458         try {
459             return new Vector(getRelationNodes(source, role, false));
460         } catch (SearchQueryException sqe) {
461             log.error(sqe.getMessage()); // should not happen
462
return new Vector(); //
463
}
464     }
465
466     /**
467      * Test whether a relation exists and returns the corresponding node.
468      * Note that this test is strict: it determines whether a relation exists from a source to a destination
469      * with a specific role. If only a role-relation exists where source and destination are reversed, this method
470      * assumed that this is a different relation type, and it returns <code>null</code>.
471      * @param source Identifying number of the source object
472      * @param destination Identifying number of the destination object
473      * @param role Identifying number of the role (reldef)
474      * @throws SearchQueryException if a storage error occurs
475      * @return The corresponding <code>MMObjectNode</code> if the exact relation exists,<code>null</code> otherwise
476      */

477     public MMObjectNode getRelationNode(int source, int destination, int role) throws SearchQueryException {
478         MMObjectNode result = null;
479         MMObjectBuilder builder = mmb.getRelDef().getBuilder(role);
480         NodeSearchQuery query = new NodeSearchQuery(builder);
481         BasicCompositeConstraint constraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_AND);
482         constraint.addChild(getNumberConstraint(query,FIELD_SOURCE, source));
483         constraint.addChild(getNumberConstraint(query,FIELD_DESTINATION, destination));
484         constraint.addChild(getNumberConstraint(query,FIELD_ROLE, role));
485         query.setConstraint(constraint);
486         Iterator i = builder.getNodes(query).iterator();
487         if (i.hasNext()) {
488             result = (MMObjectNode)i.next();
489         }
490         return result;
491     }
492
493     /**
494      * Test whether a relation exists and returns the corresponding node.
495      * Note that this test is strict: it determines whether a relation exists from a source to a destination
496      * with a specific role. If only a role-relation exists where source and destination are reversed, this method
497      * assumed that this is a different relation type, and it returns <code>null</code>.
498      * @param source Identifying number of the source object
499      * @param destination Identifying number of the destination object
500      * @param role Identifying number of the role (reldef)
501      * @return The corresponding <code>MMObjectNode</code> if the exact relation exists,<code>null</code> otherwise
502      */

503     public MMObjectNode getRelation(int source, int destination, int role) {
504         try {
505             return getRelationNode(source, destination, role);
506         } catch (SearchQueryException sqe) {
507             log.error(sqe.getMessage()); // should not happen
508
return null;
509         }
510     }
511
512     /**
513     * get MMObjectNodes related to a specified MMObjectNode
514     * @param sourceNode this is the source MMObjectNode
515     * @param nodeType Specifies the type of the nodes you want to have e.g. "pools"
516     */

517     public Enumeration getRelated(String JavaDoc sourceNode, String JavaDoc nodeType) {
518         try {
519             int source = Integer.parseInt(sourceNode);
520             int otype = mmb.getTypeDef().getIntValue(nodeType);
521             return getRelated(source, otype);
522         } catch(Exception JavaDoc e) {
523             // why is this silentely catched ?
524
}
525         return null;
526     }
527
528     /**
529     * get MMObjectNodes related to a specified MMObjectNode
530     * @param source this is the number of the source MMObjectNode
531     * @param nodeType Specifies the type of the nodes you want to have e.g. "pools"
532     */

533     public Enumeration getRelated(int source, String JavaDoc nodeType) {
534         try {
535             int otype = -1;
536             if (nodeType != null) {
537                 otype = mmb.getTypeDef().getIntValue(nodeType);
538             }
539             return getRelated(source, otype);
540         } catch(Exception JavaDoc e) {
541             // why is this silentely catched ?
542
}
543         return null;
544     }
545
546     /**
547     * Get MMObjectNodes of a specified type related to a specified MMObjectNode
548     * @param source this is the number of the source MMObjectNode
549     * @param otype the object type of the nodes you want to have
550     * @return An <code>Enumeration</code> of <code>MMObjectNode</code> object related to the source
551     */

552     public Enumeration getRelated(int source, int otype) {
553         Vector se = getRelatedVector(source,otype);
554         if (se != null) return se.elements();
555         return null;
556     }
557
558     /**
559     * get MMObjectNodes related to a specified MMObjectNode
560     * @param sourceNode this is the number of the source MMObjectNode (in string format)
561     * @param nodeType Specifies the type of the nodes you want to have e.g. "pools"
562     * @param roleName the role of teh relation (name in reldef)
563     */

564     public Enumeration getRelated(String JavaDoc sourceNode, String JavaDoc nodeType, String JavaDoc roleName) {
565         try {
566             int source = Integer.parseInt(sourceNode);
567             int otype = mmb.getTypeDef().getIntValue(nodeType);
568             int role = mmb.getRelDef().getNumberByName(roleName);
569             return getRelated(source, otype, role);
570         } catch(Exception JavaDoc e) {}
571         return null;
572     }
573
574     /**
575     * get MMObjectNodes related to a specified MMObjectNode
576     * @param source this is the number of the source MMObjectNode
577     * @param nodeType Specifies the type of the nodes you want to have e.g. "pools"
578     * @param roleName the name of the role of the relation (name in reldef)
579     */

580     public Enumeration getRelated(int source, String JavaDoc nodeType, String JavaDoc roleName) {
581         try {
582             int otype = mmb.getTypeDef().getIntValue(nodeType);
583             int role = mmb.getRelDef().getNumberByName(roleName);
584             return getRelated(source, otype, role);
585         } catch(Exception JavaDoc e) {}
586         return null;
587     }
588
589     /**
590     * Get MMObjectNodes of a specified type related to a specified MMObjectNode
591     * @param source this is the number of the source MMObjectNode
592     * @param otype the object type of the nodes you want to have
593     * @param role Identifying number of the role (reldef)
594     * @return An <code>Enumeration</code> of <code>MMObjectNode</code> object related to the source
595     */

596     public Enumeration getRelated(int source, int otype, int role) {
597         Vector se = getRelatedVector(source, otype, role);
598         if (se != null) return se.elements();
599         return null;
600     }
601
602     /**
603     * Get MMObjectNodes related to a specified MMObjectNode
604     * @param source this is the number of the MMObjectNode requesting the relations
605     * @param otype the object type of the nodes you want to have. -1 means any node.
606     * @return A <code>Vector</code> whose enumeration consists of <code>MMObjectNode</code> object related to the source
607     * according to the specified filter(s).
608     * @deprecated
609     **/

610     public Vector getRelatedVector(int source, int otype) {
611         return getRelatedVector(source,otype,-1);
612     }
613
614     /**
615      * Get MMObjectNodes related to a specified MMObjectNode
616      * @param source this is the number of the MMObjectNode requesting the relations
617      * @param otype the object type of the nodes you want to have. -1 means any node.
618      * @param role Identifying number of the role (reldef)
619      * @return A <code>Vector</code> whose enumeration consists of <code>MMObjectNode</code> object related to the source
620      * according to the specified filter(s).
621     * @deprecated
622      */

623     public Vector getRelatedVector(int source, int otype, int role) {
624         Vector list = null;
625         if (role == -1) {
626             list = (Vector)relatedCache.get(new Integer JavaDoc(source));
627         }
628         if (list == null) {
629             list = new Vector();
630             MMObjectNode node,node2;
631             int nodenr = -1;
632             for(Enumeration e = getRelations(source, role); e.hasMoreElements(); ) {
633                     node = (MMObjectNode)e.nextElement();
634                     nodenr = node.getIntValue(FIELD_SOURCE);
635                     if (nodenr == source) {
636                         nodenr = node.getIntValue(FIELD_DESTINATION);
637                     }
638                     node2=getNode(nodenr);
639                     if(node2 != null) {
640                         list.addElement(node2);
641                     }
642             }
643             if (role == -1) {
644                 relatedCache.put(new Integer JavaDoc(source),list);
645             }
646         }
647         // oke got the Vector now lets get the correct otypes
648

649         Vector results = null;
650         if (otype == -1) {
651             results = new Vector(list);
652         } else {
653             results = new Vector();
654             for (Enumeration e = list.elements(); e.hasMoreElements();) {
655                 MMObjectNode node = (MMObjectNode)e.nextElement();
656                 if (node.getOType() == otype) {
657                     results.addElement(node);
658                 }
659             }
660         }
661         return results;
662     }
663
664     public String JavaDoc getGUIIndicator(MMObjectNode node) {
665         return node.getStringValue(FIELD_SOURCE) + "->" + node.getStringValue(FIELD_DESTINATION);
666     }
667
668
669     /**
670     * Get the display string for a given field of this node.
671     * Returns for 'snumber' the name of the source object,
672     * for 'dnumber' the name of the destination object, and
673     * for 'rnumber' the name of the relation definition.
674     * @param field name of the field to describe.
675     * @param node Node containing the field data.
676     * @return A <code>String</code> describing the requested field's content
677     **/

678     public String JavaDoc getGUIIndicator(String JavaDoc field, MMObjectNode node) {
679         try {
680             if (field.equals(FIELD_DIRECTIONALITY)) {
681                 int dir=node.getIntValue(FIELD_DIRECTIONALITY);
682                 if (dir == 2) {
683                     return "bidirectional";
684                 } else if (dir==1) {
685                     return "unidirectional";
686                 } else {
687                     return "unknown";
688                 }
689             } else if (field.equals(FIELD_SOURCE)) {
690                 MMObjectNode node2 = getNode(node.getIntValue(FIELD_SOURCE));
691                 String JavaDoc ty = "=" + mmb.getTypeDef().getValue(node2.getOType());
692                 if (node2 != null) {
693                     return "" + node.getIntValue(FIELD_SOURCE) + ty + "(" + node2.getGUIIndicator()+")";
694                 }
695             } else if (field.equals(FIELD_DESTINATION)) {
696                 MMObjectNode node2 = getNode(node.getIntValue(FIELD_DESTINATION));
697                 String JavaDoc ty = "=" + mmb.getTypeDef().getValue(node2.getOType());
698                 if (node2 != null) {
699                     return "" + node.getIntValue(FIELD_DESTINATION) + ty + "(" + node2.getGUIIndicator() + ")";
700                 }
701             } else if (field.equals(FIELD_ROLE)) {
702                 MMObjectNode node2 = mmb.getRelDef().getNode(node.getIntValue(FIELD_ROLE));
703                 return "" + node.getIntValue(FIELD_ROLE) + "=" + node2.getGUIIndicator();
704             }
705         } catch (Exception JavaDoc e) {
706         }
707         return null;
708     }
709
710     /**
711     * Checks whether a specific relation exists.
712     * Maintains a cache containing the last checked relations
713     *
714     * Note that this routine returns false both when a source/destination are swapped, and when a typecombo
715     * does not exist - it is not possible to derive whether one or the other has occurred.
716     *
717     * @param source Number of the source node
718     * @param destination Number of the destination node
719     * @param role Number of the relation definition
720     * @return A <code>boolean</code> indicating success when the relation exists, failure if it does not.
721     * @deprecated Use {@link TypeRel#reldefCorrect} instead
722     */

723     public boolean reldefCorrect(int source, int destination, int role) {
724         return mmb.getTypeRel().reldefCorrect(source, destination, role);
725     }
726
727     /**
728     * Deletes the Relation cache.
729     * This is to be called if caching gives problems.
730     * Make sure that you can't use the deleteRelationCache(int source) instead.
731     **/

732     public void deleteRelationCache() {
733         relatedCache.clear();
734     }
735
736     /**
737     * Delete a specified relation from the relationCache
738     * @param source the number of the relation to remove from the cache
739     **/

740     public void deleteRelationCache(int source) {
741         relatedCache.remove(new Integer JavaDoc(source));
742     }
743
744     /**
745     * Search the relation definition table for the identifying number of
746     * a relation, by name.
747     * Success is dependent on the uniqueness of the relation's name (not enforced, so unpredictable).
748     * @param name The name on which to search for the relation
749     * @return A <code>int</code> value indicating the relation's object number, or -1 if not found.
750     **/

751     public int getGuessedNumber(String JavaDoc name) {
752         RelDef reldef = mmb.getRelDef();
753         if (reldef != null) {
754             return reldef.getNumberByName(name);
755         }
756         return -1;
757     }
758
759     /**
760     * Set defaults for a node.
761     * Tries to determine a default for 'relnumber' by searching the RelDef table for an occurrence of the node's builder.
762     * Uses the table-mapping system, and should be replaced.
763     * @param node The node whose defaults to set.
764     */

765     public void setDefaults(MMObjectNode node) {
766         super.setDefaults(node);
767         if (tableName.equals(INSREL_BUILDER)) return;
768
769         if (relnumber == -1) {
770             MMObjectNode n = mmb.getRelDef().getDefaultForBuilder(this);
771             if (n == null) {
772                 log.warn("Can not determine default reldef for ("+getTableName()+")");
773             } else {
774                 relnumber = n.getNumber();
775             }
776         }
777         node.setValue(FIELD_ROLE,relnumber);
778     }
779 }
780
Popular Tags