@Override public boolean init() { if (oType != -1) return true; super.init(); createIfNotExists(); // during init not yet all builder are available so inheritance is not // yet possible // This means that calls to getAllowedRelations do not consider // inheritance during initializion of MMBase. // This occurs e.g. in one of the Community-builders. readCache(false); EventManager.getInstance().addEventListener(this); return true; }
/* * (non-Javadoc) * @see org.mmbase.module.core.MMObjectBuilder#notify(org.mmbase.core.event.NodeEvent) */ @Override public void notify(NodeEvent event) { if (log.isDebugEnabled()) { log.debug( "Changed " + event.getMachine() + " " + event.getNodeNumber() + " " + event.getBuilderName() + " " + NodeEvent.newTypeToOldType(event.getType())); } if (tableName.equals(event.getBuilderName())) { if (event.getType() == Event.TYPE_NEW) { MMObjectNode typeRelNode = getNode(event.getNodeNumber()); if (typeRelNode != null) { Set<MMObjectNode> newTypeRels = addCacheEntry(typeRelNode, true); log.service("Added to typerelcache: " + newTypeRels); } else { log.warn("Could not found typerel node with number " + event.getNodeNumber()); } } else { // something else changed in a typerel node? reread the complete typeRelNodes Set log.service( "Received '" + event + "' which is about typrels. Now re-reading the entire cache"); readCache(); } // also, clear all query-caches, because result may change by this. See MMB-348 for (Cache qc : CacheManager.getMap().values()) { if (qc instanceof QueryResultCache) { qc.clear(); } } } super.notify(event); }
SortedSet<MMObjectNode> getByDestinationSource( MMObjectBuilder source, MMObjectBuilder destination) { return getByDestinationSourceRole(source.getNumber(), destination.getNumber(), 0); }
// find some subsets: SortedSet<MMObjectNode> getBySource(MMObjectBuilder source) { return getBySourceDestinationRole(source.getNumber(), 0, 0); }
/** * Remove a node from the cloud. * * @param node The node to remove. */ @Override public void removeNode(MMObjectNode node) { super.removeNode(node); }
/** * Addes one typerel cache entries, plus inherited relations (if builder are initialized) * * @return A Set with the added entries, which can be used for logging or so, or can be * disregarded * @since MMBase-1.6.2 */ protected TypeRelSet addCacheEntry( final MMObjectNode typeRel, final boolean buildersInitialized) { if (typeRel == null) { throw new IllegalArgumentException("typeRel cannot be null"); } final TypeRelSet added = new TypeRelSet(); // store temporary, which will enable nice logging of what happened // Start to add the actual definition, this is then afterwards again, // except if one of the builders could not be found added.add(typeRel); if (mmb == null) { throw new IllegalStateException("mmb is null"); } final RelDef reldef = mmb.getRelDef(); if (reldef == null) { throw new IllegalStateException("No reldef found"); } final MMObjectNode reldefNode = reldef.getNode(typeRel.getIntValue("rnumber")); if (reldefNode == null) { throw new RuntimeException( "Could not find reldef-node for rnumber= " + typeRel.getIntValue("rnumber")); } final boolean bidirectional = (!InsRel.usesdir) || (reldefNode.getIntValue("dir") > 1); INHERITANCE: if (buildersInitialized) { // handle inheritance, which is // not possible during // initialization of MMBase. final TypeDef typeDef = mmb.getTypeDef(); final String sourceBuilderName = typeDef.getValue(typeRel.getIntValue("snumber")); final MMObjectBuilder sourceBuilder = sourceBuilderName != null ? mmb.getBuilder(sourceBuilderName) : null; final String destinationBuilderName = typeDef.getValue(typeRel.getIntValue("dnumber")); final MMObjectBuilder destinationBuilder = destinationBuilderName != null ? mmb.getBuilder(destinationBuilderName) : null; if (sourceBuilder == null) { if (destinationBuilder == null) { log.info( "Both source and destination of " + typeRel + " are not active builders. Cannot follow descendants."); } else { log.info( "The source of relation type " + typeRel + " is not an active builder. Cannot follow descendants."); } break INHERITANCE; } if (destinationBuilder == null) { log.warn( "The destination of relation type " + typeRel + " is not an active builder. Cannot follow descendants."); break INHERITANCE; } final int rnumber = typeRel.getIntValue("rnumber"); final List<MMObjectBuilder> sources = new ArrayList<MMObjectBuilder>(sourceBuilder.getDescendants()); sources.add(sourceBuilder); final List<MMObjectBuilder> destinations = new ArrayList<MMObjectBuilder>(destinationBuilder.getDescendants()); destinations.add(destinationBuilder); for (MMObjectBuilder s : sources) { for (MMObjectBuilder d : destinations) { MMObjectNode vnode = new VirtualTypeRelNode(s.getNumber(), d.getNumber(), rnumber); added.add(vnode); } } // seek all parents and store typerels for them // this cache is used by contains(INCLUDE_PARENTS / // INCLUDE_PARENTS_AND_DESCENDANTS)); MMObjectBuilder sourceParent = sourceBuilder; while (sourceParent != null) { MMObjectBuilder destinationParent = destinationBuilder; while (destinationParent != null) { MMObjectNode vnode = new VirtualTypeRelNode( sourceParent.getNumber(), destinationParent.getNumber(), rnumber); parentTypeRelNodes.add(vnode); destinationParent = destinationParent.getParentBuilder(); } sourceParent = sourceParent.getParentBuilder(); } added.add(typeRel); // replaces the ones added in the 'inheritance' // loop (so now not any more Virtual) } for (MMObjectNode node : added) { if (!node.isVirtual()) { // make sure 'real' nodes replace virtual nodes. (real and virtual nodes are equal, so will // not be added to set otherwise) // This is especially essential whey you use STRICT in contains typeRelNodes.remove(node); if (bidirectional) inverseTypeRelNodes.remove(node); } typeRelNodes.add(node); if (bidirectional) inverseTypeRelNodes.add(node); } if (log.isDebugEnabled()) { log.debug("Added to typerelcache: " + added); } return added; }