1 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 34 public class InsRel extends MMObjectBuilder { 35 36 37 public static final String INSREL_BUILDER = "insrel"; 38 39 40 public static final String FIELD_SNUMBER = "snumber"; 41 42 public static final String FIELD_SOURCE = FIELD_SNUMBER; 43 44 public static final String FIELD_DNUMBER = "dnumber"; 45 46 public static final String FIELD_DESTINATION = FIELD_DNUMBER; 47 48 public static final String FIELD_RNUMBER = "rnumber"; 49 50 public static final String FIELD_ROLE = FIELD_RNUMBER; 51 52 public static final String FIELD_DIR = "dir"; 53 54 public static final String FIELD_DIRECTIONALITY = FIELD_DIR; 55 56 private static final Logger log = Logging.getLoggerInstance(InsRel.class); 57 58 64 public static boolean usesdir = true; 65 66 69 public int relnumber = -1; 70 71 76 77 private Cache relatedCache = new Cache(25) { 78 public String getName() { return "RelatedCache"; } 79 public String getDescription() { return "Cache for Related Nodes"; } 80 }; 81 82 83 89 90 91 94 public InsRel() { 95 relatedCache.putCache(); 96 } 98 99 106 public boolean init() { 107 CoreField dirField = getField(FIELD_DIRECTIONALITY); 108 boolean hasDirField = dirField != null && dirField.inStorage(); 109 if (!created()) { 110 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 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 166 public int insert(String 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 187 public int insert(String 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 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 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 240 public Enumeration getRelations(int source) { 241 return getRelations(source,-1); 242 } 243 244 251 public Enumeration getRelations(int source, int role) { 252 return getRelationsVector(source, role).elements(); 253 } 254 255 263 public Enumeration getRelations(int source, int otype, int role) { 264 return getRelations(source, otype, role, true); 265 } 266 267 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 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 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()); return true; } 328 } 329 330 private BasicFieldValueConstraint getNumberConstraint(NodeSearchQuery query, String fieldName, int value) { 332 return new BasicFieldValueConstraint(query.getField(query.getBuilder().getField(fieldName)), new Integer (value)); 333 } 334 335 343 public List getRelationNodes(int source) throws SearchQueryException { 344 return getRelationNodes(source, -1, usesdir); 345 } 346 347 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()); return new Vector(); } 358 } 359 360 369 public List getRelationNodes(int source, int role) throws SearchQueryException { 370 return getRelationNodes(source, role, usesdir); 371 } 372 373 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()); return new Vector(); } 384 } 385 386 396 public List getRelationNodes(int source, boolean useDirectionality) throws SearchQueryException { 397 return getRelationNodes(source, -1, useDirectionality); 398 } 399 400 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()); return new Vector(); } 411 } 412 413 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 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()); return new Vector(); } 464 } 465 466 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 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()); return null; 509 } 510 } 511 512 517 public Enumeration getRelated(String sourceNode, String nodeType) { 518 try { 519 int source = Integer.parseInt(sourceNode); 520 int otype = mmb.getTypeDef().getIntValue(nodeType); 521 return getRelated(source, otype); 522 } catch(Exception e) { 523 } 525 return null; 526 } 527 528 533 public Enumeration getRelated(int source, String 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 e) { 541 } 543 return null; 544 } 545 546 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 564 public Enumeration getRelated(String sourceNode, String nodeType, String 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 e) {} 571 return null; 572 } 573 574 580 public Enumeration getRelated(int source, String nodeType, String 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 e) {} 586 return null; 587 } 588 589 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 610 public Vector getRelatedVector(int source, int otype) { 611 return getRelatedVector(source,otype,-1); 612 } 613 614 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 (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 (source),list); 645 } 646 } 647 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 getGUIIndicator(MMObjectNode node) { 665 return node.getStringValue(FIELD_SOURCE) + "->" + node.getStringValue(FIELD_DESTINATION); 666 } 667 668 669 678 public String getGUIIndicator(String 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 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 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 e) { 706 } 707 return null; 708 } 709 710 723 public boolean reldefCorrect(int source, int destination, int role) { 724 return mmb.getTypeRel().reldefCorrect(source, destination, role); 725 } 726 727 732 public void deleteRelationCache() { 733 relatedCache.clear(); 734 } 735 736 740 public void deleteRelationCache(int source) { 741 relatedCache.remove(new Integer (source)); 742 } 743 744 751 public int getGuessedNumber(String name) { 752 RelDef reldef = mmb.getRelDef(); 753 if (reldef != null) { 754 return reldef.getNumberByName(name); 755 } 756 return -1; 757 } 758 759 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
|