Source Code Cross Referenced for InsRel.java in  » Database-ORM » MMBase » org » mmbase » module » corebuilders » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » MMBase » org.mmbase.module.corebuilders 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:        This software is OSI Certified Open Source Software.
004:        OSI Certified is a certification mark of the Open Source Initiative.
005:
006:        The license (Mozilla version 1.0) can be read at the MMBase site.
007:        See http://www.MMBase.org/license
008:
009:         */
010:        package org.mmbase.module.corebuilders;
011:
012:        import java.util.*;
013:
014:        import org.mmbase.core.CoreField;
015:        import org.mmbase.storage.search.*;
016:        import org.mmbase.storage.search.implementation.*;
017:        import org.mmbase.cache.Cache;
018:        import org.mmbase.module.core.*;
019:        import org.mmbase.util.logging.*;
020:
021:        /**
022:         *
023:         * InsRel, the main relation object, holds relations, and methods to
024:         * handle them. An insrel defines a relation between two objects.
025:         * <p>
026:         * This class can be extended to create insrels that can also hold
027:         * extra values and custom methods (named relations for example).
028:         * </p>
029:         *
030:         * @author Daniel Ockeloen
031:         * @author Pierre van Rooden
032:         * @version $Id: InsRel.java,v 1.54 2007/02/11 19:21:12 nklasens Exp $
033:         */
034:        public class InsRel extends MMObjectBuilder {
035:
036:            /** Base 'insrel' builder name */
037:            public static final String INSREL_BUILDER = "insrel";
038:
039:            /** Name of the field containing the source object number */
040:            public static final String FIELD_SNUMBER = "snumber";
041:            /** Name of the field containing the source object number */
042:            public static final String FIELD_SOURCE = FIELD_SNUMBER;
043:            /** Name of the field containing the destination object number */
044:            public static final String FIELD_DNUMBER = "dnumber";
045:            /** Name of the field containing the destination object number */
046:            public static final String FIELD_DESTINATION = FIELD_DNUMBER;
047:            /** Name of the field containing the role (reldef) object number */
048:            public static final String FIELD_RNUMBER = "rnumber";
049:            /** Name of the field containing the role (reldef) object number */
050:            public static final String FIELD_ROLE = FIELD_RNUMBER;
051:            /** Name of the field containing the directionality */
052:            public static final String FIELD_DIR = "dir";
053:            /** Name of the field containing the directionality */
054:            public static final String FIELD_DIRECTIONALITY = FIELD_DIR;
055:
056:            private static final Logger log = Logging
057:                    .getLoggerInstance(InsRel.class);
058:
059:            /**
060:             * Indicates whether the relations use the 'dir' field (that is, whether the
061:             * field has been defined in the xml file). Used for backward compatibility.
062:             * The default is <code>true</code> - the value is set to <code>false</code> if any of the
063:             * relation builders does not contain a <code>dir</code> field (a warning is issued).
064:             */
065:            public static boolean usesdir = true;
066:
067:            /**
068:             * Hold the relnumber to use when creating a node of this builder.
069:             */
070:            public int relnumber = -1;
071:
072:            /**
073:             *  Cache system, holds the relations from the 25
074:             *  most used relations
075:             * @todo Is this cache still used?
076:             */
077:
078:            private Cache<Integer, Vector<MMObjectNode>> relatedCache = new Cache<Integer, Vector<MMObjectNode>>(
079:                    25) {
080:                public String getName() {
081:                    return "RelatedCache";
082:                }
083:
084:                public String getDescription() {
085:                    return "Cache for Related Nodes";
086:                }
087:            };
088:
089:            /* perhaps this would be nice?
090:            private Cache relationsCache = new Cache(25) {
091:                public String getName()        { return "RelationsCache"; }
092:                public String getDescription() { return "Cache for Relations"; }
093:                };
094:             */
095:
096:            /**
097:             * needed for autoload
098:             */
099:            public InsRel() {
100:                relatedCache.putCache();
101:                // relationsCache.putCache();
102:            }
103:
104:            /**
105:             * Initializes the builder. Determines whether the <code>dir</code> field is defined (and thus whether directionality is supported).
106:             * If the field cannot be found, a <em>"Warning: No dir field. Directionality support turned off."</em> warning message is issued.
107:             * @return A <code>boolean</code> value, always success (<code>true</code>), as any exceptions are
108:             *         caught and logged.
109:             * @see #usesdir
110:             */
111:            public boolean init() {
112:                CoreField dirField = getField(FIELD_DIRECTIONALITY);
113:                boolean hasDirField = dirField != null && dirField.inStorage();
114:                if (!created()) {
115:                    // check whether directionality is in use, and whether a dir field is present.
116:                    // if a non-dir supporting builder is attempted to be used, a fatal error is logged.
117:                    // the table is not created. MMbase continues, but anny atept to use this builder will fail
118:                    // (one way or the other).
119:                    // If the builder to be created is insrel (the basic builder), the system ignores the error
120:                    // and continues without directionality (backward compatibility).
121:                    //
122:                    if (usesdir && !hasDirField
123:                            && (!getTableName().equals(INSREL_BUILDER))) {
124:                        log
125:                                .fatal("FATAL ERROR: Builder "
126:                                        + getTableName()
127:                                        + " has no dir field but directionality support was turned on.");
128:                        log.fatal("Table for " + getTableName()
129:                                + " was NOT created.");
130:                        log.fatal("MMBase continues, but use of the "
131:                                + getTableName() + " builder will fail.");
132:                        return false;
133:                    }
134:                }
135:                boolean res = super .init();
136:                checkAddTmpField("_dnumber");
137:                checkAddTmpField("_snumber");
138:                if (res && usesdir && !hasDirField) {
139:                    log
140:                            .warn("No dir field. Directionality support turned off.");
141:                    usesdir = false;
142:                }
143:                return res;
144:            }
145:
146:            /**
147:             * Fixes a relation node.  Determines the source and destination numbers, and checks the object
148:             * types against the types specified in the relation definition ( {@link TypeRel} ).  If the
149:             * types differ, the source and destination are likely mis-aligned, and if the relation in the
150:             * other direction is indeed allowed, then they are swapped to produce a correct relation node.
151:             *
152:             * @param node The node to fix
153:             * @return     The node again
154:             */
155:            private MMObjectNode alignRelNode(MMObjectNode node) {
156:                int source = getNodeType(node.getIntValue(FIELD_SOURCE));
157:                int destination = getNodeType(node
158:                        .getIntValue(FIELD_DESTINATION));
159:                int role = node.getIntValue(FIELD_ROLE);
160:                TypeRel typeRel = mmb.getTypeRel();
161:                if (!typeRel.reldefCorrect(source, destination, role)
162:                        && typeRel.reldefCorrect(destination, source, role)) {
163:                    destination = node.getIntValue(FIELD_SOURCE);
164:                    node.setValue(FIELD_SOURCE, node
165:                            .getIntValue(FIELD_DESTINATION));
166:                    node.setValue(FIELD_DESTINATION, destination);
167:                }
168:                return node;
169:            }
170:
171:            /**
172:             * Insert a new Instance Relation.
173:             * @param owner Administrator
174:             * @param source Identifying number of the source object
175:             * @param destination Identifying number of the destination object
176:             * @param role Identifying number of the relation defintition
177:             * @return A <code>integer</code> value identifying the newly inserted relation
178:             * @deprecated Use insert(String, MMObjectNode) instead.
179:             */
180:            public int insert(String owner, int source, int destination,
181:                    int role) {
182:                int result = -1;
183:                MMObjectNode node = getNewNode(owner);
184:                if (node != null) {
185:                    node.setValue(FIELD_SOURCE, source);
186:                    node.setValue(FIELD_DESTINATION, destination);
187:                    node.setValue(FIELD_ROLE, role);
188:                    result = insert(owner, node);
189:                } else {
190:                    log.error("insert(" + owner + "," + source + ","
191:                            + destination + "," + role
192:                            + "): Cannot create new node(" + node + ")!");
193:                }
194:                return result;
195:            }
196:
197:            /**
198:             * Insert a new Instance Relation.
199:             * @param owner Administrator
200:             * @param node Relation node to add
201:             * @return A <code>integer</code> value identifying the newly inserted relation
202:             */
203:            public int insert(String owner, MMObjectNode node) {
204:                int result = -1;
205:                int source = node.getIntValue(FIELD_SOURCE);
206:                if (source >= 0) {
207:                    int destination = node.getIntValue(FIELD_DESTINATION);
208:                    if (destination >= 0) {
209:                        int role = node.getIntValue(FIELD_ROLE);
210:                        if (role > 0) {
211:                            if (usesdir) {
212:                                MMObjectNode reldef = getNode(role);
213:                                int dir = reldef
214:                                        .getIntValue(FIELD_DIRECTIONALITY);
215:                                if (dir <= 0)
216:                                    dir = 2;
217:                                node.setValue(FIELD_DIRECTIONALITY, dir);
218:                            }
219:                            node = alignRelNode(node);
220:                            if (log.isDebugEnabled()) {
221:                                log.debug("insert(" + owner + "," + node + ")");
222:                            }
223:                            result = super .insert(owner, node);
224:                            // remove cache for these nodes (enforce update)
225:                            deleteRelationCache(source);
226:                            deleteRelationCache(destination);
227:                        } else {
228:                            log
229:                                    .error("insert("
230:                                            + owner
231:                                            + ","
232:                                            + node
233:                                            + "): rnumber("
234:                                            + role
235:                                            + ") is not greater than 0! (something is seriously wrong)");
236:                        }
237:                    } else {
238:                        log
239:                                .error("insert("
240:                                        + owner
241:                                        + ","
242:                                        + node
243:                                        + "): dnumber("
244:                                        + destination
245:                                        + " is not greater than 0! (something is seriously wrong)");
246:                    }
247:                } else {
248:                    log
249:                            .error("insert("
250:                                    + owner
251:                                    + ","
252:                                    + node
253:                                    + "): snumber("
254:                                    + source
255:                                    + ") is not greater than 0! (something is seriously wrong)");
256:                }
257:                return result;
258:            }
259:
260:            /**
261:             * Remove a node from the cloud.
262:             * @param node The node to remove.
263:             */
264:            public void removeNode(MMObjectNode node) {
265:                int source = node.getIntValue(FIELD_SOURCE);
266:                int destination = node.getIntValue(FIELD_DESTINATION);
267:                super .removeNode(node);
268:                deleteRelationCache(source);
269:                deleteRelationCache(destination);
270:            }
271:
272:            /**
273:             * Get relation(s) for a MMObjectNode
274:             * @param source Identifying number of the object to find the relations of.
275:             * @return If succesful, an <code>Enumeration</code> listing the relations.
276:             *         If no relations exist, the method returns <code>null</code>.
277:             * @see #getRelationsVector(int)
278:             */
279:            public Enumeration<MMObjectNode> getRelations(int source) {
280:                return getRelations(source, -1);
281:            }
282:
283:            /**
284:             * Get relation(s) for a MMObjectNode, using a specified role (reldef) as a filter
285:             * @param source Identifying number of the object to find the relations of.
286:             * @param role The number of the relation definition (role) to filter on
287:             * @return an <code>Enumeration</code> listing the relations.
288:             * @see #getRelationsVector(int, int)
289:             */
290:            public Enumeration<MMObjectNode> getRelations(int source, int role) {
291:                return getRelationsVector(source, role).elements();
292:            }
293:
294:            /**
295:             * Get relations for a specified MMObjectNode
296:             * @param source this is the number of the MMObjectNode requesting the relations
297:             * @param otype the object type of the nodes you want to have. -1 means any node.
298:             * @param role Identifying number of the role (reldef)
299:             * @return An <code>Enumeration</code> whose enumeration consists of <code>MMObjectNode</code> object related to the source
300:             *   according to the specified filter(s).
301:             */
302:            public Enumeration<MMObjectNode> getRelations(int source,
303:                    int otype, int role) {
304:                return getRelations(source, otype, role, true);
305:            }
306:
307:            /**
308:             * Gets relations for a specified MMObjectNode
309:             * @param source this is the number of the MMObjectNode requesting the relations
310:             * @param otype the object type of the nodes you want to have. -1 means any node.
311:             * @param role Identifying number of the role (reldef)
312:             * @param usedirectionality if <code>true</code> teh result si filtered on unidirectional relations.
313:             *                          specify <code>false</code> if you want to show unidoerctional relations
314:             *                          from destination to source.
315:             * @return An <code>Enumeration</code> whose enumeration consists of <code>MMObjectNode</code> object related to the source
316:             *   according to the specified filter(s).
317:             */
318:            public Enumeration<MMObjectNode> getRelations(int source,
319:                    int otype, int role, boolean usedirectionality) {
320:                List<MMObjectNode> re;
321:                if (usedirectionality) {
322:                    re = getRelationsVector(source, role);
323:                } else {
324:                    re = getAllRelationsVector(source, role);
325:                }
326:                if (otype == -1) {
327:                    return Collections.enumeration(re);
328:                } else {
329:                    TypeDef typedef = mmb.getTypeDef();
330:                    MMObjectBuilder wantedBuilder = mmb.getBuilder(typedef
331:                            .getValue(otype));
332:                    List<MMObjectNode> list = new ArrayList<MMObjectNode>();
333:                    for (MMObjectNode node : re) {
334:                        int nodenr = node.getIntValue(FIELD_SOURCE);
335:                        if (nodenr == source) {
336:                            nodenr = node.getIntValue(FIELD_DESTINATION);
337:                        }
338:                        String tableName = typedef
339:                                .getValue(getNodeType(nodenr));
340:                        if (tableName != null) {
341:                            MMObjectBuilder nodeBuilder = mmb
342:                                    .getBuilder(tableName);
343:                            if (nodeBuilder != null
344:                                    && (nodeBuilder.equals(wantedBuilder) || nodeBuilder
345:                                            .isExtensionOf(wantedBuilder))) {
346:                                list.add(node);
347:                            }
348:                        }
349:                    }
350:                    return Collections.enumeration(list);
351:                }
352:            }
353:
354:            /**
355:             * Checks whether any relations exist for a MMObjectNode.
356:             * This includes unidirection relations which would otherwise not be counted.
357:             * If the query fails to execute, the system will assume that relations exists.
358:             * @param source Identifying number of the object to find the relations of.
359:             * @return <code>true</code> if any relations exist, <code>false</code> otherwise.
360:             */
361:            public boolean hasRelations(int source) {
362:                try {
363:                    NodeSearchQuery query = new NodeSearchQuery(this );
364:                    BasicCompositeConstraint constraint = new BasicCompositeConstraint(
365:                            CompositeConstraint.LOGICAL_OR);
366:                    constraint.addChild(getNumberConstraint(query,
367:                            FIELD_SOURCE, source));
368:                    constraint.addChild(getNumberConstraint(query,
369:                            FIELD_DESTINATION, source));
370:                    query.setConstraint(constraint);
371:                    return count(query) != 0;
372:                } catch (SearchQueryException sqe) {
373:                    log.error(sqe.getMessage(), sqe); // should not happen
374:                    return true; // perhaps yes?
375:                }
376:            }
377:
378:            // creates a constraint for a numeric field on a query
379:            private BasicFieldValueConstraint getNumberConstraint(
380:                    NodeSearchQuery query, String fieldName, int value) {
381:                return new BasicFieldValueConstraint(query.getField(query
382:                        .getBuilder().getField(fieldName)), Integer
383:                        .valueOf(value));
384:            }
385:
386:            /**
387:             * Get relation(s) for an MMObjectNode, using a specified role (reldef) as a filter.
388:             * This function returns all relations based on this role in which the node is either a source, or where the node is
389:             * the destination, but the direction is bidirectional.
390:             * @param source Identifying number of the object to find the relations of.
391:             * @return A <code>List</code> containing the relation nodes.
392:             * @throws SearchQueryException if a storage error occurs
393:             */
394:            public List<MMObjectNode> getRelationNodes(int source)
395:                    throws SearchQueryException {
396:                return getRelationNodes(source, -1, usesdir);
397:            }
398:
399:            /**
400:             * Get relation(s) for a MMObjectNode.
401:             * @deprecated use {@link #getRelationNodes(int)}
402:             */
403:            public Vector<MMObjectNode> getRelationsVector(int source) {
404:                try {
405:                    return new Vector<MMObjectNode>(getRelationNodes(source,
406:                            -1, usesdir));
407:                } catch (SearchQueryException sqe) {
408:                    log.error(sqe.getMessage(), sqe); // should not happen
409:                    return new Vector<MMObjectNode>(); //
410:                }
411:            }
412:
413:            /**
414:             * Get relation(s) for an MMObjectNode, using a specified role (reldef) as a filter.
415:             * This function returns all relations based on this role in which the node is either a source, or where the node is
416:             * the destination, but the direction is bidirectional.
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:             * @return A <code>List</code> containing the relation nodes.
420:             * @throws SearchQueryException if a storage error occurs
421:             */
422:            public List<MMObjectNode> getRelationNodes(int source, int role)
423:                    throws SearchQueryException {
424:                return getRelationNodes(source, role, usesdir);
425:            }
426:
427:            /**
428:             * Get relation(s) for a MMObjectNode, using a specified role.
429:             * @deprecated use {@link #getRelationNodes(int, int, boolean)}
430:             */
431:            public Vector<MMObjectNode> getRelationsVector(int source, int role) {
432:                try {
433:                    return new Vector<MMObjectNode>(getRelationNodes(source,
434:                            role, usesdir));
435:                } catch (SearchQueryException sqe) {
436:                    log.error(sqe.getMessage(), sqe); // should not happen
437:                    return new Vector<MMObjectNode>(); //
438:                }
439:            }
440:
441:            /**
442:             * Get all relation(s) for an MMObjectNode.
443:             * This function returns all relations in which the node is either a source or
444:             * the destination.
445:             * @param source Identifying number of the object to find the relations of.
446:             * @param useDirectionality if <code>truie</code>, take directionality into account.
447:             *       If <code>false</code>, returns all relations, even if the direction is unidirectional.
448:             * @return A <code>List</code> containing the relation nodes.
449:             * @throws SearchQueryException if a storage error occurs
450:             */
451:            public List<MMObjectNode> getRelationNodes(int source,
452:                    boolean useDirectionality) throws SearchQueryException {
453:                return getRelationNodes(source, -1, useDirectionality);
454:            }
455:
456:            /**
457:             * Get all relation(s) for a MMObjectNode.
458:             * @deprecated use {@link #getRelationNodes(int, boolean)}
459:             */
460:            public Vector<MMObjectNode> getAllRelationsVector(int source) {
461:                try {
462:                    return new Vector<MMObjectNode>(getRelationNodes(source,
463:                            -1, false));
464:                } catch (SearchQueryException sqe) {
465:                    log.error(sqe.getMessage(), sqe); // should not happen
466:                    return new Vector<MMObjectNode>(); //
467:                }
468:            }
469:
470:            /**
471:             * Get all relation(s) for a MMObjectNode
472:             * This function returns all relations in which the node is either a source or
473:             * the destination.
474:             * @param source Identifying number of the object to find the relations of.
475:             * @param role The number of the relation definition (role) to filter on, <code>-1</code> means any role
476:             * @param useDirectionality if <code>truie</code>, take directionality into account.
477:             *       If <code>false</code>, returns all relations, even if the direction is unidirectional.
478:             * @return A <code>List</code> containing the relation nodes.
479:             * @throws SearchQueryException if a storage error occurs
480:             */
481:            public List<MMObjectNode> getRelationNodes(int source, int role,
482:                    boolean useDirectionality) throws SearchQueryException {
483:                MMObjectBuilder builder = this ;
484:                if (role != -1) {
485:                    builder = mmb.getRelDef().getBuilder(role);
486:                }
487:                NodeSearchQuery query = new NodeSearchQuery(builder);
488:                BasicCompositeConstraint constraint = new BasicCompositeConstraint(
489:                        CompositeConstraint.LOGICAL_OR);
490:                constraint.addChild(getNumberConstraint(query, FIELD_SOURCE,
491:                        source));
492:                Constraint destinationConstraint = getNumberConstraint(query,
493:                        FIELD_DESTINATION, source);
494:                if (useDirectionality) {
495:                    BasicFieldValueConstraint dirConstraint = getNumberConstraint(
496:                            query, FIELD_DIRECTIONALITY, 1);
497:                    dirConstraint.setOperator(FieldCompareConstraint.NOT_EQUAL);
498:                    BasicCompositeConstraint compositeConstraint = new BasicCompositeConstraint(
499:                            CompositeConstraint.LOGICAL_AND);
500:                    compositeConstraint.addChild(destinationConstraint);
501:                    compositeConstraint.addChild(dirConstraint);
502:                    destinationConstraint = compositeConstraint;
503:                }
504:                constraint.addChild(destinationConstraint);
505:                if (role != -1) {
506:                    BasicCompositeConstraint roleConstraint = new BasicCompositeConstraint(
507:                            CompositeConstraint.LOGICAL_AND);
508:                    roleConstraint.addChild(constraint);
509:                    roleConstraint.addChild(getNumberConstraint(query,
510:                            FIELD_ROLE, role));
511:                    constraint = roleConstraint;
512:                }
513:                query.setConstraint(constraint);
514:                List<MMObjectNode> nodes = builder.getNodes(query);
515:                return nodes;
516:            }
517:
518:            /**
519:             * Get all relation(s) for a MMObjectNode.
520:             * @deprecated use {@link #getRelationNodes(int, int, boolean)}
521:             */
522:            public Vector<MMObjectNode> getAllRelationsVector(int source,
523:                    int role) {
524:                try {
525:                    return new Vector<MMObjectNode>(getRelationNodes(source,
526:                            role, false));
527:                } catch (SearchQueryException sqe) {
528:                    log.error(sqe.getMessage(), sqe); // should not happen
529:                    return new Vector<MMObjectNode>(); //
530:                }
531:            }
532:
533:            /**
534:             * Test whether a relation exists and returns the corresponding node.
535:             * Note that this test is strict: it determines whether a relation exists from a source to a destination
536:             * with a specific role. If only a role-relation exists where source and destination are reversed, this method
537:             * assumed that this is a different relation type, and it returns <code>null</code>.
538:             * @param source Identifying number of the source object
539:             * @param destination Identifying number of the destination object
540:             * @param role Identifying number of the role (reldef)
541:             * @throws SearchQueryException if a storage error occurs
542:             * @return The corresponding <code>MMObjectNode</code> if the exact relation exists,<code>null</code> otherwise
543:             */
544:            public MMObjectNode getRelationNode(int source, int destination,
545:                    int role) throws SearchQueryException {
546:                MMObjectNode result = null;
547:                MMObjectBuilder builder = mmb.getRelDef().getBuilder(role);
548:                NodeSearchQuery query = new NodeSearchQuery(builder);
549:                BasicCompositeConstraint constraint = new BasicCompositeConstraint(
550:                        CompositeConstraint.LOGICAL_AND);
551:                constraint.addChild(getNumberConstraint(query, FIELD_SOURCE,
552:                        source));
553:                constraint.addChild(getNumberConstraint(query,
554:                        FIELD_DESTINATION, destination));
555:                constraint
556:                        .addChild(getNumberConstraint(query, FIELD_ROLE, role));
557:                query.setConstraint(constraint);
558:                Iterator<MMObjectNode> i = builder.getNodes(query).iterator();
559:                if (i.hasNext()) {
560:                    result = i.next();
561:                }
562:                return result;
563:            }
564:
565:            /**
566:             * Test whether a relation exists and returns the corresponding node.
567:             * Note that this test is strict: it determines whether a relation exists from a source to a destination
568:             * with a specific role. If only a role-relation exists where source and destination are reversed, this method
569:             * assumed that this is a different relation type, and it returns <code>null</code>.
570:             * @param source Identifying number of the source object
571:             * @param destination Identifying number of the destination object
572:             * @param role Identifying number of the role (reldef)
573:             * @return The corresponding <code>MMObjectNode</code> if the exact relation exists,<code>null</code> otherwise
574:             */
575:            public MMObjectNode getRelation(int source, int destination,
576:                    int role) {
577:                try {
578:                    return getRelationNode(source, destination, role);
579:                } catch (SearchQueryException sqe) {
580:                    log.error(sqe.getMessage()); // should not happen
581:                    return null;
582:                }
583:            }
584:
585:            /**
586:             * get MMObjectNodes related to a specified MMObjectNode
587:             * @param sourceNode this is the source MMObjectNode
588:             * @param nodeType Specifies the type of the nodes you want to have e.g. "pools"
589:             */
590:            public Enumeration<MMObjectNode> getRelated(String sourceNode,
591:                    String nodeType) {
592:                try {
593:                    int source = Integer.parseInt(sourceNode);
594:                    int otype = mmb.getTypeDef().getIntValue(nodeType);
595:                    return getRelated(source, otype);
596:                } catch (Exception e) {
597:                    // why is this silentely catched ?
598:                }
599:                return null;
600:            }
601:
602:            /**
603:             * get MMObjectNodes related to a specified MMObjectNode
604:             * @param source this is the number of the source MMObjectNode
605:             * @param nodeType Specifies the type of the nodes you want to have e.g. "pools"
606:             */
607:            public Enumeration<MMObjectNode> getRelated(int source,
608:                    String nodeType) {
609:                try {
610:                    int otype = -1;
611:                    if (nodeType != null) {
612:                        otype = mmb.getTypeDef().getIntValue(nodeType);
613:                    }
614:                    return getRelated(source, otype);
615:                } catch (Exception e) {
616:                    // why is this silentely catched ?
617:                }
618:                return null;
619:            }
620:
621:            /**
622:             * Get MMObjectNodes of a specified type related to a specified MMObjectNode
623:             * @param source this is the number of the source MMObjectNode
624:             * @param otype the object type of the nodes you want to have
625:             * @return An <code>Enumeration</code> of <code>MMObjectNode</code> object related to the source
626:             */
627:            public Enumeration<MMObjectNode> getRelated(int source, int otype) {
628:                Vector<MMObjectNode> se = getRelatedVector(source, otype);
629:                if (se != null)
630:                    return se.elements();
631:                return null;
632:            }
633:
634:            /**
635:             * get MMObjectNodes related to a specified MMObjectNode
636:             * @param sourceNode this is the number of the source MMObjectNode (in string format)
637:             * @param nodeType Specifies the type of the nodes you want to have e.g. "pools"
638:             * @param roleName the role of teh relation (name in reldef)
639:             */
640:            public Enumeration<MMObjectNode> getRelated(String sourceNode,
641:                    String nodeType, String roleName) {
642:                try {
643:                    int source = Integer.parseInt(sourceNode);
644:                    int otype = mmb.getTypeDef().getIntValue(nodeType);
645:                    int role = mmb.getRelDef().getNumberByName(roleName);
646:                    return getRelated(source, otype, role);
647:                } catch (Exception e) {
648:                }
649:                return null;
650:            }
651:
652:            /**
653:             * get MMObjectNodes related to a specified MMObjectNode
654:             * @param source this is the number of the source MMObjectNode
655:             * @param nodeType Specifies the type of the nodes you want to have e.g. "pools"
656:             * @param roleName the name of the role of the relation (name in reldef)
657:             */
658:            public Enumeration<MMObjectNode> getRelated(int source,
659:                    String nodeType, String roleName) {
660:                try {
661:                    int otype = mmb.getTypeDef().getIntValue(nodeType);
662:                    int role = mmb.getRelDef().getNumberByName(roleName);
663:                    return getRelated(source, otype, role);
664:                } catch (Exception e) {
665:                }
666:                return null;
667:            }
668:
669:            /**
670:             * Get MMObjectNodes of a specified type related to a specified MMObjectNode
671:             * @param source this is the number of the source MMObjectNode
672:             * @param otype the object type of the nodes you want to have
673:             * @param role Identifying number of the role (reldef)
674:             * @return An <code>Enumeration</code> of <code>MMObjectNode</code> object related to the source
675:             */
676:            public Enumeration<MMObjectNode> getRelated(int source, int otype,
677:                    int role) {
678:                Vector<MMObjectNode> se = getRelatedVector(source, otype, role);
679:                if (se != null)
680:                    return se.elements();
681:                return null;
682:            }
683:
684:            /**
685:             * Get MMObjectNodes related to a specified MMObjectNode
686:             * @param source this is the number of the MMObjectNode requesting the relations
687:             * @param otype the object type of the nodes you want to have. -1 means any node.
688:             * @return A <code>Vector</code> whose enumeration consists of <code>MMObjectNode</code> object related to the source
689:             *   according to the specified filter(s).
690:             * @deprecated
691:             **/
692:            public Vector<MMObjectNode> getRelatedVector(int source, int otype) {
693:                return getRelatedVector(source, otype, -1);
694:            }
695:
696:            /**
697:             * Get MMObjectNodes related to a specified MMObjectNode
698:             * @param source this is the number of the MMObjectNode requesting the relations
699:             * @param otype the object type of the nodes you want to have. -1 means any node.
700:             * @param role Identifying number of the role (reldef)
701:             * @return A <code>Vector</code> whose enumeration consists of <code>MMObjectNode</code> object related to the source
702:             *   according to the specified filter(s).
703:             * @deprecated
704:             */
705:            public Vector<MMObjectNode> getRelatedVector(int source, int otype,
706:                    int role) {
707:                Vector<MMObjectNode> list = null;
708:                if (role == -1) {
709:                    list = relatedCache.get(Integer.valueOf(source));
710:                }
711:                if (list == null) {
712:                    list = new Vector<MMObjectNode>();
713:                    for (Enumeration<MMObjectNode> e = getRelations(source,
714:                            role); e.hasMoreElements();) {
715:                        MMObjectNode node = e.nextElement();
716:                        int nodenr = node.getIntValue(FIELD_SOURCE);
717:                        if (nodenr == source) {
718:                            nodenr = node.getIntValue(FIELD_DESTINATION);
719:                        }
720:                        MMObjectNode node2 = getNode(nodenr);
721:                        if (node2 != null) {
722:                            list.add(node2);
723:                        }
724:                    }
725:                    if (role == -1) {
726:                        relatedCache.put(Integer.valueOf(source), list);
727:                    }
728:                }
729:                // oke got the Vector now lets get the correct otypes
730:                Vector<MMObjectNode> results = null;
731:                if (otype == -1) {
732:                    results = new Vector<MMObjectNode>(list);
733:                } else {
734:                    results = new Vector<MMObjectNode>();
735:                    for (MMObjectNode node : list) {
736:                        if (node.getOType() == otype) {
737:                            results.addElement(node);
738:                        }
739:                    }
740:                }
741:                return results;
742:            }
743:
744:            public String getGUIIndicator(MMObjectNode node) {
745:                return node.getStringValue(FIELD_SOURCE) + "->"
746:                        + node.getStringValue(FIELD_DESTINATION);
747:            }
748:
749:            /**
750:             * Get the display string for a given field of this node.
751:             * Returns for 'snumber' the name of the source object,
752:             * for 'dnumber' the name of the destination object, and
753:             * for 'rnumber' the name of the relation definition.
754:             * @param field name of the field to describe.
755:             * @param node Node containing the field data.
756:             * @return A <code>String</code> describing the requested field's content
757:             **/
758:            public String getGUIIndicator(String field, MMObjectNode node) {
759:                try {
760:                    if (field.equals(FIELD_DIRECTIONALITY)) {
761:                        int dir = node.getIntValue(FIELD_DIRECTIONALITY);
762:                        if (dir == 2) {
763:                            return "bidirectional";
764:                        } else if (dir == 1) {
765:                            return "unidirectional";
766:                        } else {
767:                            return "unknown";
768:                        }
769:                    } else if (field.equals(FIELD_SOURCE)) {
770:                        MMObjectNode node2 = getNode(node
771:                                .getIntValue(FIELD_SOURCE));
772:                        String ty = "="
773:                                + mmb.getTypeDef().getValue(node2.getOType());
774:                        if (node2 != null) {
775:                            return "" + node.getIntValue(FIELD_SOURCE) + ty
776:                                    + "(" + node2.getGUIIndicator() + ")";
777:                        }
778:                    } else if (field.equals(FIELD_DESTINATION)) {
779:                        MMObjectNode node2 = getNode(node
780:                                .getIntValue(FIELD_DESTINATION));
781:                        String ty = "="
782:                                + mmb.getTypeDef().getValue(node2.getOType());
783:                        if (node2 != null) {
784:                            return "" + node.getIntValue(FIELD_DESTINATION)
785:                                    + ty + "(" + node2.getGUIIndicator() + ")";
786:                        }
787:                    } else if (field.equals(FIELD_ROLE)) {
788:                        MMObjectNode node2 = mmb.getRelDef().getNode(
789:                                node.getIntValue(FIELD_ROLE));
790:                        return "" + node.getIntValue(FIELD_ROLE) + "="
791:                                + node2.getGUIIndicator();
792:                    }
793:                } catch (Exception e) {
794:                }
795:                return null;
796:            }
797:
798:            /**
799:             * Checks whether a specific relation exists.
800:             * Maintains a cache containing the last checked relations
801:             *
802:             * Note that this routine returns false both when a source/destination are swapped, and when a typecombo
803:             * does not exist -  it is not possible to derive whether one or the other has occurred.
804:             *
805:             * @param source Number of the source node
806:             * @param destination Number of the destination node
807:             * @param role  Number of the relation definition
808:             * @return A <code>boolean</code> indicating success when the relation exists, failure if it does not.
809:             * @deprecated Use {@link TypeRel#reldefCorrect} instead
810:             */
811:            public boolean reldefCorrect(int source, int destination, int role) {
812:                return mmb.getTypeRel()
813:                        .reldefCorrect(source, destination, role);
814:            }
815:
816:            /**
817:             * Deletes the Relation cache.
818:             * This is to be called if caching gives problems.
819:             * Make sure that you can't use the deleteRelationCache(int source) instead.
820:             **/
821:            public void deleteRelationCache() {
822:                relatedCache.clear();
823:            }
824:
825:            /**
826:             * Delete a specified relation from the relationCache
827:             * @param source the number of the relation to remove from the cache
828:             **/
829:            public void deleteRelationCache(int source) {
830:                relatedCache.remove(Integer.valueOf(source));
831:            }
832:
833:            /**
834:             * Search the relation definition table for the identifying number of
835:             * a relation, by name.
836:             * Success is dependent on the uniqueness of the relation's name (not enforced, so unpredictable).
837:             * @param name The name on which to search for the relation
838:             * @return A <code>int</code> value indicating the relation's object number, or -1 if not found.
839:             **/
840:            public int getGuessedNumber(String name) {
841:                RelDef reldef = mmb.getRelDef();
842:                if (reldef != null) {
843:                    return reldef.getNumberByName(name);
844:                }
845:                return -1;
846:            }
847:
848:            /**
849:             * Set defaults for a node.
850:             * Tries to determine a default for 'relnumber' by searching the RelDef table for an occurrence of the node's builder.
851:             * Uses the table-mapping system, and should be replaced.
852:             * @param node The node whose defaults to set.
853:             */
854:            public void setDefaults(MMObjectNode node) {
855:                super .setDefaults(node);
856:                if (tableName.equals(INSREL_BUILDER))
857:                    return;
858:
859:                if (relnumber == -1) {
860:                    MMObjectNode n = mmb.getRelDef().getDefaultForBuilder(this );
861:                    if (n == null) {
862:                        log.warn("Can not determine default reldef for ("
863:                                + getTableName() + ")");
864:                    } else {
865:                        relnumber = n.getNumber();
866:                    }
867:                }
868:                node.setValue(FIELD_ROLE, relnumber);
869:            }
870:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.