| 1 10 package org.mmbase.module.corebuilders; 11 12 import java.util.*; 13 import org.mmbase.module.core.*; 14 15 import org.mmbase.storage.search.implementation.*; 16 import org.mmbase.storage.search.*; 17 import org.mmbase.util.logging.Logger; 18 import org.mmbase.util.logging.Logging; 19 20 48 public class RelDef extends MMObjectBuilder { 49 50 private static final Logger log = Logging.getLoggerInstance(RelDef.class); 51 52 53 public final static int DIR_UNIDIRECTIONAL = 1; 54 55 56 public final static int DIR_BIDIRECTIONAL = 2; 57 58 62 public static boolean usesbuilder = false; 63 64 private Map relCache = new HashMap(); 67 68 private Map relBuilderCache = null; 71 72 private Map rnumberCache = new HashMap(); 74 75 78 public RelDef() { 79 } 80 81 86 public boolean init() { 87 super.init(); 88 usesbuilder = getField("builder") != null; 89 return readCache(); 90 } 91 92 97 private void addToCache(MMObjectNode node) { 98 Integer rnumber = (Integer ) node.getValue("number"); 99 relCache.put(node.getStringValue("sname"), rnumber); 100 relCache.put(node.getStringValue("sname") + "/" + node.getStringValue("dname"), rnumber); 101 102 rnumberCache.put(rnumber, findBuilderName(node)); 103 } 104 105 110 private void removeFromCache(MMObjectNode node) { 111 relCache.remove(node.getStringValue("sname")); 112 relCache.remove(node.getStringValue("sname") + "/" + node.getStringValue("dname")); 113 114 rnumberCache.remove(new Integer (node.getNumber())); 115 } 116 117 120 private void removeFromCache(int rnumber) { 121 Integer r = new Integer (rnumber); 122 Iterator i = relCache.entrySet().iterator(); 123 while (i.hasNext()) { 124 Map.Entry entry = (Map.Entry) i.next(); 125 Object value = entry.getValue(); 126 if (r.equals(value)) { 127 i.remove(); 128 } 129 } 130 rnumberCache.remove(r); 131 } 132 133 134 140 private boolean readCache() { 141 rnumberCache.clear(); 142 relCache.clear(); relCache.put("insrel", new Integer (-1)); 144 try { 146 for (Iterator i = getNodes(new NodeSearchQuery(this)).iterator(); i.hasNext();) { 147 MMObjectNode n = (MMObjectNode) i.next(); 148 addToCache(n); 149 } 150 } catch (org.mmbase.storage.search.SearchQueryException sqe) { 151 log.error("Error while reading reldef cache" + sqe.getMessage()); 152 } 153 return true; 154 } 155 156 162 public String getGUIIndicator(MMObjectNode node) { 163 int dir = node.getIntValue("dir"); 164 if (dir == DIR_UNIDIRECTIONAL) { 165 return node.getStringValue("sguiname"); 166 } else { 167 String st1 = node.getStringValue("sguiname"); 168 String st2 = node.getStringValue("dguiname"); 169 return st1 + "/" + st2; 170 } 171 } 172 173 174 178 179 public String getBuilderName(Integer reldefNodeNumber) { 180 return (String ) rnumberCache.get(reldefNodeNumber); 181 } 182 183 184 187 protected String findBuilderName(MMObjectNode node) { 188 String bulname = null; 189 if (usesbuilder) { 190 int builder = node.getIntValue("builder"); 191 if (builder <= 0) { 192 bulname = node.getStringValue("sname"); 193 } else { 194 bulname = mmb.getTypeDef().getValue(builder); 195 } 196 } else { 197 bulname = node.getStringValue("sname"); 199 if (mmb.getMMObject(bulname) == null) bulname=null; 200 } 201 if (bulname == null) { 202 return "insrel"; 203 } else { 204 return bulname; 205 } 206 } 207 208 214 public String getBuilderName(MMObjectNode node) { 215 if (node == null) return "NULL"; 216 return (String ) rnumberCache.get(new Integer (node.getNumber())); 217 } 218 219 220 224 public InsRel getBuilder(int rnumber) { 225 return getBuilder(getNode(rnumber)); 226 } 227 228 232 public InsRel getBuilder(MMObjectNode node) { 233 String builderName = getBuilderName(node); 234 if (builderName == null) { 235 throw new RuntimeException ("Node " + node + " has no builder?"); 236 } 237 MMObjectBuilder builder = mmb.getBuilder(builderName); 238 if (builder == null) { 239 return mmb.getInsRel(); 240 } else { 241 if (builder instanceof InsRel) { 242 return (InsRel) builder; 243 } else { 244 log.warn("The builder " + builderName + " of node " + node.getNumber() + " is no InsRel (but " + builder.getClass() + "). Perhaps it is inactive? Impossible here. Returing InsRel any way."); 245 return mmb.getInsRel(); 246 247 } 248 } 249 } 250 251 256 public MMObjectNode getDefaultForBuilder(InsRel relBuilder) { 257 MMObjectNode node = null; 258 NodeSearchQuery query = new NodeSearchQuery(this); 259 if (usesbuilder) { 260 Integer value = new Integer (relBuilder.getNumber()); 261 Constraint constraint = new BasicFieldValueConstraint(query.getField(getField("builder")), value); 262 query.setConstraint(constraint); 263 } else { 264 Constraint constraint1 = new BasicFieldValueConstraint(query.getField(getField("sname")), relBuilder.getTableName()); 267 Constraint constraint2 = new BasicFieldValueConstraint(query.getField(getField("dname")), relBuilder.getTableName()); 268 BasicCompositeConstraint constraint = new BasicCompositeConstraint(CompositeConstraint.LOGICAL_OR); 269 constraint.addChild(constraint1); 270 constraint.addChild(constraint2); 271 query.setConstraint(constraint); 272 } 273 query.setMaxNumber(1); 274 try { 275 List reldefs = getNodes(query); 276 if (reldefs.size() != 0) { 277 node =(MMObjectNode)reldefs.get(0); 278 } 279 } catch (SearchQueryException sqe) { 280 log.error(sqe); 282 } 283 return node; 284 } 285 286 290 public void testValidData(MMObjectNode node) throws InvalidDataException{ 291 int dir=node.getIntValue("dir"); 292 if ((dir!=DIR_UNIDIRECTIONAL) && (dir!=DIR_BIDIRECTIONAL)) { 293 throw new InvalidDataException("Invalid directionality ("+dir+") specified","dir"); 294 } 295 if (usesbuilder) { 296 int builder=node.getIntValue("builder"); 297 if (builder<=0) { 298 builder=mmb.getInsRel().getNumber(); 299 } 300 if (!isRelationBuilder(builder)) { 301 throw new InvalidDataException("Builder ("+builder+") is not a relationbuilder","builder"); 302 } 303 } 304 }; 305 306 313 public int insert(String owner, MMObjectNode node) { 314 String sname = node.getStringValue("sname"); 316 String dname = node.getStringValue("dname"); 317 if (getNumberByName(sname + '/' + dname) != -1) { 318 throw new RuntimeException ("The reldef with sname=" + sname + " and dname=" + dname + " already exists"); 320 } 321 int number = super.insert(owner,node); 322 log.service("Created new reldef " + sname + "/" + dname); 323 if (number != -1) { 324 addToCache(node); 325 } 326 return number; 327 }; 328 329 330 336 public boolean commit(MMObjectNode node) { 337 boolean success = super.commit(node); 338 if (success) { 339 addToCache(node); 340 } 341 return success; 342 } 343 344 348 public void removeNode(MMObjectNode node) { 349 try { 352 MMObjectBuilder typeRel = mmb.getTypeRel(); 353 NodeSearchQuery query = new NodeSearchQuery(typeRel); 354 Integer value = new Integer (node.getNumber()); 355 Constraint constraint = new BasicFieldValueConstraint(query.getField(typeRel.getField("rnumber")), value); 356 query.setConstraint(constraint); 357 List typerels = typeRel.getNodes(query); 358 if (typerels.size() > 0) { 359 throw new RuntimeException ("Cannot delete reldef, it is referenced by typerels: " + typerels); 360 } 361 } catch (SearchQueryException sqe) { 362 log.error(sqe); 364 } 365 366 try { 368 MMObjectBuilder insRel = mmb.getInsRel(); 369 NodeSearchQuery query = new NodeSearchQuery(insRel); 370 Integer value = new Integer (node.getNumber()); 371 Constraint constraint = new BasicFieldValueConstraint(query.getField(insRel.getField("rnumber")), value); 372 query.setConstraint(constraint); 373 int i = insRel.count(query); 374 if (i > 0) { 375 throw new RuntimeException ("Cannot delete reldef node, it is still used in " + i + " relations"); 376 } 377 } catch (SearchQueryException sqe) { 378 log.error(sqe); 380 } 381 382 super.removeNode(node); 383 removeFromCache(node); 384 } 385 386 391 public void setDefaults(MMObjectNode node) { 392 node.setValue("dir", DIR_BIDIRECTIONAL); 393 if (usesbuilder) { 394 node.setValue("builder", mmb.getInsRel().getNumber()); 395 } 396 } 397 398 406 407 public String getGUIIndicator(String field,MMObjectNode node) { 408 try { 409 if (field.equals("dir")) { 410 switch (node.getIntValue("dir")) { 411 case DIR_BIDIRECTIONAL: 412 return "bidirectional"; 413 414 case DIR_UNIDIRECTIONAL: 415 return "unidirectional"; 416 417 default: 418 return "unknown"; 419 } 420 } else if (field.equals("builder")) { 421 int builder=node.getIntValue("builder"); 422 if (builder<=0) { 423 return "insrel"; 424 } else { 425 return mmb.getTypeDef().getValue(builder); 426 } 427 } 428 } catch (Exception e) {} 429 return null; 430 } 431 432 437 438 public boolean isRelationTable(String name) { 439 Object ob; 440 ob=relCache.get(name); 441 return ob!=null; 442 } 443 444 private Map getRelBuilderCache() { 446 if (relBuilderCache == null) { 448 relBuilderCache = new HashMap(); 449 Iterator buls = mmb.getBuilders().iterator(); 451 while (buls.hasNext()) { 452 MMObjectBuilder fbul = (MMObjectBuilder) buls.next(); 453 if (fbul instanceof InsRel) { 454 relBuilderCache.put(new Integer (fbul.getNumber()), fbul); 455 } 456 } 457 } 458 return relBuilderCache; 459 } 460 461 466 467 public boolean isRelationBuilder(int number) { 468 Object ob; 469 ob = getRelBuilderCache().get(new Integer (number)); 470 return ob != null; 471 } 472 473 477 478 public Enumeration getRelationBuilders() { 479 return Collections.enumeration(getRelBuilderCache().values()); 480 } 481 482 492 public int getGuessedNumber(String role) { 493 return getNumberByName(role, false); 494 } 495 496 505 public int getNumberByName(String role) { 506 return getNumberByName(role, false); 507 } 508 509 523 public int getNumberByName(String role, boolean searchBidirectional) { 524 Integer number = (Integer ) relCache.get(role); 525 if (number != null) { 526 return number.intValue(); 527 } 528 if (searchBidirectional) { 529 NodeSearchQuery query = new NodeSearchQuery(this); 530 Constraint constraint = new BasicFieldValueConstraint(query.getField(getField("dname")), role); 531 query.setConstraint(constraint); 532 query.setMaxNumber(1); 533 try { 534 List reldefs = getNodes(query); 535 if (reldefs.size() != 0) { 536 MMObjectNode node = (MMObjectNode)reldefs.get(0); 537 return node.getNumber(); 538 } 539 } catch (SearchQueryException sqe) { 540 log.error(sqe); 542 } 543 } 544 return -1; 545 } 546 547 557 558 public int getGuessedByName(String role) { 559 return getNumberByName(role,true); 560 } 561 562 572 public int getRelNrByName(String sname, String dname) { 573 int res=getNumberByName(sname+"/"+dname); 574 if (res<-1) { 575 res=getNumberByName(dname+"/"+sname); 576 } 577 return res; 578 } 579 580 590 public boolean nodeRemoteChanged(String machine, String number, String builder, String ctype) { 591 if (builder.equals(getTableName())) { 592 if (ctype.equals("c") || ctype.equals("n")) { 593 int rnumber = Integer.parseInt(number); 595 removeFromCache(rnumber); 596 addToCache(getNode(rnumber)); 597 } else if (ctype.equals("d")) { 598 removeFromCache(Integer.parseInt(number)); 599 } 600 } 601 return super.nodeRemoteChanged(machine, number, builder, ctype); 602 } 603 } 604 605 606 607 608 | Popular Tags |