[jboss-user] [JBossCache] - Re: PojoCacheListener: modify

supi do-not-reply at jboss.com
Tue Apr 10 15:58:59 EDT 2007


"jason.greene at jboss.com" wrote : 
  | Also, there is a known design flaw, where notifications are only dispatched locally.
  | http://jira.jboss.com/jira/browse/JBCACHE-774
  | 
Yes, I realized this too. Unfortunately, I need to have it now, so I'm trying to do everything from the outside by converting (tree) cache notifications to pojo cache notifications.

anonymous wrote : 
  | Is PojoCache.findAll(String id) what you are looking for?
  | 
No, exactly the opposite. For example, if I get notified of address object changes, how can the person the address belongs to be determined? I think that I should be able to look up all (cycle-free) paths.

Could look something like this:


  |   public List<String> findPojoIds(Object inPojo) {
  |     List<String> result = new ArrayList<String>();
  |     
  |     if (inPojo instanceof Advised) {
  |       PojoInstance instance = null;
  |       
  |       // retrieve instance object
  |       BaseInterceptor interceptor = (BaseInterceptor)AopUtil.findCacheInterceptor(((Advised)inPojo)._getInstanceAdvisor());
  |       if (interceptor != null) {
  |         NodeSPI node = cache_.getRoot().getChildDirect(interceptor.getFqn());
  |         if (node != null) {
  |           instance = (PojoInstance)node.getDirect(PojoInstance.KEY);
  |         }
  |       }
  |       
  |       // find ids recursively
  |       Set<Fqn> visited = new HashSet<Fqn>();
  |       visited.add(interceptor.getFqn());
  |       result = getVirtualIds((CacheImpl)_cacheL.getCache(), instance, new Fqn(), visited);
  |     }
  |     
  |     return result;
  |   }
  |   
  |   private static List<String> getVirtualIds(CacheSPI inCache, PojoInstance inInstance, Fqn inVirtualTail, Set<Fqn> inVisited) {
  |     List<String> result = new ArrayList<String>();
  |     
  |     if (inInstance != null) {
  |       List<Fqn> refs = inInstance.getReferencedBy(); // not currently accessible
  |       for(Fqn ref : refs) {
  |         if (isInternal(ref)) {
  |           Object element = ref.getLastElement();
  |           Fqn oneLevelUp = ref.getSubFqn(0, ref.size() - 1);
  |           if (!inVisited.contains(oneLevelUp)) {
  |             // read instance, recurse
  |             NodeSPI node = (NodeSPI)inCache.getRoot().getChildDirect(oneLevelUp);
  |             PojoInstance instance = (PojoInstance)node.getDirect(PojoInstance.KEY);
  |             Set<Fqn> visited = new HashSet<Fqn>(inVisited); // we want a complete list of cycle-free paths
  |             visited.add(oneLevelUp);
  |             result.addAll(getVirtualIds(inCache, instance, new Fqn(new Fqn(element), inVirtualTail), visited));
  |           }
  |         } else {
  |           // found something
  |           result.add(new Fqn(ref, inVirtualTail).toString());
  |         }
  |       }
  |     }
  |     return result;
  |   }
  | 

For symmetry reasons, find() would also have to be changed to take virtual paths into account: (should be anyway, IMO)


  |   public Object find(Fqn inFqn) {
  |     Object result = null;
  |     Fqn fqn = inFqn;
  |     LinkedList<Object> fqn2 = new LinkedList<Object>();
  |     while (!_cache.getCache().getRoot().hasChild(fqn) && fqn.size() > 0) {
  |       fqn2.addFirst(fqn.getLastElement());
  |       fqn = fqn.getSubFqn(0, fqn.size() - 1);
  |     }
  |     if (fqn.size() > 0) {
  |       while (!fqn2.isEmpty()) {
  |         NodeSPI node = cache_.getRoot().getChildDirect(fqn);
  |         fqn = new Fqn(((PojoReference)node.get(PojoReference.KEY)).getFqn(), fqn2.removeFirst());
  |       }
  |       // now that we have the internal fqn, retrieve the object as usual
  |       result = getObject(fqn);
  |     }
  |     return result;
  |   }
  |   
  | 

So, this is more or less what I am looking for :) I guess that in many cases the object itself contains some kind of identifier, or even a reference back to its owner. However, I think people shouldn't be forced to include this information in their pojos. findPojoId() can't be used because the internal fqn isn't exactly useful. Neither is a randomly chosen external one.

Basil
Achermann


View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4036109#4036109

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4036109



More information about the jboss-user mailing list