KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > core > impl > tree > TreeImpl


1 /*****************************************
2  * *
3  * JBoss Portal: The OpenSource Portal *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  *****************************************/

9 package org.jboss.portal.core.impl.tree;
10
11 import org.jboss.cache.Fqn;
12 import org.jboss.cache.TreeCacheListener;
13 import org.jboss.cache.TreeCache;
14 import org.jboss.cache.CacheException;
15 import org.jboss.cache.PropertyConfigurator;
16 import org.jboss.cache.DummyTransactionManagerLookup;
17 import org.jboss.cache.TransactionManagerLookup;
18 import org.jboss.cache.loader.CacheLoader;
19 import org.jboss.cache.interceptors.Interceptor;
20 import org.jboss.cache.lock.IsolationLevel;
21 import org.jboss.portal.server.util.Service;
22 import org.jboss.portal.common.transaction.TransactionManagerProvider;
23 import org.jboss.portal.common.FQN;
24 import org.jboss.portal.common.util.Tools;
25 import org.jboss.portal.common.tree.Tree;
26 import org.jboss.portal.common.tree.NodeChangeListener;
27 import org.jboss.portal.common.tree.Session;
28 import org.jboss.portal.common.tree.Node;
29 import org.jboss.portal.core.impl.tree.tm.TransactionManagerObserver;
30 import org.jboss.util.StringPropertyReplacer;
31 import org.jgroups.View;
32 import org.jgroups.blocks.MethodCall;
33 import org.apache.log4j.Logger;
34
35 import java.util.Map JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.ArrayList JavaDoc;
38 import java.util.LinkedList JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.Collections JavaDoc;
42 import java.util.Set JavaDoc;
43 import java.util.HashSet JavaDoc;
44 import java.lang.reflect.Method JavaDoc;
45 import java.io.ObjectOutputStream JavaDoc;
46 import java.io.ByteArrayOutputStream JavaDoc;
47 import java.io.IOException JavaDoc;
48 import java.io.ByteArrayInputStream JavaDoc;
49 import java.io.ObjectInputStream JavaDoc;
50 import java.io.File JavaDoc;
51
52 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
53
54 import javax.transaction.TransactionManager JavaDoc;
55 import javax.transaction.Transaction JavaDoc;
56 import javax.transaction.NotSupportedException JavaDoc;
57 import javax.transaction.SystemException JavaDoc;
58
59 /**
60  * Implementation of tree that delegates to JBoss Cache.
61  *
62  * @author <a HREF="mailto:julien@jboss.org">Julien Viet</a>
63  * @version $Revision: 1.5 $
64  * @jmx.mbean
65  * @jboss.xmbean
66  */

67 public class TreeImpl
68    extends Service
69    implements Tree,
70    TreeCacheListener,
71    TransactionManagerProvider,
72    NodeStateEventListener
73 {
74
75    /** Logger. */
76    private Logger log = Logger.getLogger(TreeImpl.class);
77
78    /** Underlying cache. */
79    private TreeCache cache;
80
81    /** List of listeners. */
82    private List JavaDoc listeners;
83
84    /** Fqn->NodeImpl map. */
85    private Map JavaDoc nodeMap;
86
87    /** Root node. */
88    private NodeImpl root;
89
90    /** . */
91    private TransactionManagerObserver observer;
92
93    /** Helper to keep track of changes. */
94    private NodeStateEventAdapter eventAdapter;
95
96    /** The cache configuration in the jboss-service.xml format. */
97    private String JavaDoc cacheConfiguration;
98
99    public TreeImpl()
100    {
101       try
102       {
103          listeners = new LinkedList JavaDoc();
104          nodeMap = new ConcurrentReaderHashMap();
105          root = new NodeImpl(this, new Fqn());
106          nodeMap.put(root.fqn, root);
107       }
108       catch (Exception JavaDoc e)
109       {
110          throw new Error JavaDoc(e);
111       }
112    }
113
114    //
115

116    public void handle(NodeStateEvent[] events)
117    {
118       try
119       {
120          // Iterate over all the events
121
for (int i = 0; i < events.length; i++)
122          {
123             NodeStateEvent nodeStateEvent = events[i];
124             switch (nodeStateEvent.getStatus())
125             {
126             case NodeStateEvent.STATUS_CREATED:
127                {
128                   Fqn childFqn = nodeStateEvent.getFqn();
129                   Fqn parentFqn = getParentFqn(childFqn);
130                   FQN parentID = toFQN(parentFqn);
131                   NodeImpl child = (NodeImpl)nodeMap.get(childFqn);
132                   String JavaDoc childName = child.getName();
133
134                   // Setup state on the node object
135
Map JavaDoc properties = ((org.jboss.cache.Node)cache.get(childFqn)).getData();
136                   for (Iterator JavaDoc j = properties.values().iterator(); j.hasNext();)
137                   {
138                      Property prop = (Property)j.next();
139
140                      // Get property name and id
141
String JavaDoc propName = prop.getName();
142                      String JavaDoc propID = prop.getID();
143
144                      // Put the property in the node directly
145
child.ids.put(propName, propID);
146                   }
147
148                   // Notify listeners of the event
149
for (Iterator JavaDoc j = listeners.iterator(); j.hasNext();)
150                   {
151                      NodeChangeListener listener = (NodeChangeListener)j.next();
152                      listener.childAdded(parentID, childName);
153                   }
154                   break;
155                }
156             case NodeStateEvent.STATUS_MODIFIED:
157                {
158                   Fqn fqn = nodeStateEvent.getFqn();
159                   NodeImpl node = (NodeImpl)nodeMap.get(fqn);
160
161                   // node
162
Set JavaDoc addedProps = new HashSet JavaDoc();
163                   Set JavaDoc changedProps = new HashSet JavaDoc();
164                   Map JavaDoc tmp = new HashMap JavaDoc(node.ids);
165                   Map JavaDoc properties = ((org.jboss.cache.Node)cache.get(fqn)).getData();
166                   for (Iterator JavaDoc j = properties.values().iterator(); j.hasNext();)
167                   {
168                      Property prop = (Property)j.next();
169                      String JavaDoc id = (String JavaDoc)tmp.remove(prop.getName());
170                      if (id == null)
171                      {
172                         addedProps.add(prop.getName());
173                      }
174                      else if (!id.equals(prop.getID()))
175                      {
176                         changedProps.add(prop.getName());
177                      }
178                   }
179                   Set JavaDoc removedProps = tmp.keySet();
180
181                   //
182
for (Iterator JavaDoc j = addedProps.iterator(); j.hasNext();)
183                   {
184                      String JavaDoc key = (String JavaDoc)j.next();
185                      for (Iterator JavaDoc k = listeners.iterator(); k.hasNext();)
186                      {
187                         NodeChangeListener listener = (NodeChangeListener)k.next();
188                         listener.propertyAdded(node.getID(), key);
189                      }
190                   }
191                   for (Iterator JavaDoc j = changedProps.iterator(); j.hasNext();)
192                   {
193                      String JavaDoc key = (String JavaDoc)j.next();
194                      for (Iterator JavaDoc k = listeners.iterator(); k.hasNext();)
195                      {
196                         NodeChangeListener listener = (NodeChangeListener)k.next();
197                         listener.propertyChanged(node.getID(), key);
198                      }
199                   }
200                   for (Iterator JavaDoc j = removedProps.iterator(); j.hasNext();)
201                   {
202                      String JavaDoc key = (String JavaDoc)j.next();
203                      for (Iterator JavaDoc k = listeners.iterator(); k.hasNext();)
204                      {
205                         NodeChangeListener listener = (NodeChangeListener)k.next();
206                         listener.propertyRemoved(node.getID(), key);
207                      }
208                   }
209
210                   //
211
node.ids.clear();
212                   for (Iterator JavaDoc j = properties.values().iterator(); j.hasNext();)
213                   {
214                      Property prop = (Property)j.next();
215                      node.ids.put(prop.getName(), prop.getID());
216                   }
217
218                   break;
219                }
220             case NodeStateEvent.STATUS_REMOVED:
221                {
222                   Fqn childFqn = nodeStateEvent.getFqn();
223                   Fqn parentFqn = getParentFqn(childFqn);
224                   FQN parentID = toFQN(parentFqn);
225                   String JavaDoc childName = (String JavaDoc)childFqn.get(childFqn.size() - 1);
226
227                   // Notify listeners of the event
228
for (Iterator JavaDoc j = listeners.iterator(); j.hasNext();)
229                   {
230                      NodeChangeListener listener = (NodeChangeListener)j.next();
231                      listener.childRemoved(parentID, childName);
232                   }
233                   break;
234                }
235             default:
236                throw new Error JavaDoc();
237             }
238          }
239       }
240       catch (CacheException e)
241       {
242          log.error("", e);
243       }
244    }
245
246    //
247

248    protected void createService() throws Exception JavaDoc
249    {
250       cache = new FixedTreeCache();
251       if (cacheConfiguration == null)
252       {
253          // Use local configuration
254
cache.setCacheMode(TreeCache.LOCAL);
255          cache.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
256          cache.setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
257       }
258       else
259       {
260          String JavaDoc config = StringPropertyReplacer.replaceProperties(cacheConfiguration);
261          log.debug("Cache configuration " + config);
262          PropertyConfigurator configurator = new PropertyConfigurator();
263          configurator.configure(cache, config);
264       }
265
266       // Get configured class and build the wrapper around the transaction manager
267
Class JavaDoc lookupClass = Thread.currentThread().getContextClassLoader().loadClass(cache.getTransactionManagerLookupClass());
268       TransactionManagerLookup lookup = (TransactionManagerLookup)lookupClass.newInstance();
269       TransactionManagerProvider provider = new JBossCacheTransactionManagerAdapter(lookup);
270       observer = new TransactionManagerObserver(provider.getTransactionManager());
271
272       // Override the transaction manager with the wrapper
273
cache.setTransactionManagerLookup(observer);
274
275       // Build the change broadcaster
276
eventAdapter = new NodeStateEventAdapter(observer, this);
277
278       //
279
cache.create();
280
281       // Add ourself as listener of cache events
282
cache.addTreeCacheListener(this);
283    }
284
285    protected void startService() throws Exception JavaDoc
286    {
287       cache.start();
288    }
289
290    protected void stopService()
291    {
292       cache.stop();
293    }
294
295    protected void destroyService()
296    {
297       cache.destroy();
298       cache = null;
299       eventAdapter = null;
300       observer = null;
301    }
302
303    public TreeCache getCache()
304    {
305       return cache;
306    }
307
308    /**
309     * @jmx.managed-attribute
310     */

311    public String JavaDoc getCacheConfiguration()
312    {
313       return cacheConfiguration;
314    }
315
316    /**
317     * @jmx.managed-attribute
318     */

319    public void setCacheConfiguration(String JavaDoc cacheConfiguration)
320    {
321       this.cacheConfiguration = cacheConfiguration;
322    }
323
324    //
325

326    /**
327     * @jmx.managed-operation
328     * @jmx.managed-parameter name="fqn"
329     * type="org.jboss.portal.common.FQN"
330     */

331    public Node getNode(FQN fqn)
332    {
333       return (Node)nodeMap.get(toFqn(fqn));
334    }
335
336    /**
337     * @jmx.managed-attribute
338     * access="read-only"
339     */

340    public Session getSession()
341    {
342       try
343       {
344          TransactionManager JavaDoc tm = cache.getTransactionManager();
345          tm.begin();
346          Transaction JavaDoc tx = tm.getTransaction();
347          return new SessionImpl(this, tx);
348       }
349       catch (NotSupportedException JavaDoc e)
350       {
351          log.error("", e);
352          return null;
353       }
354       catch (SystemException JavaDoc e)
355       {
356          log.error("", e);
357          return null;
358       }
359    }
360
361    /**
362     * @jmx.managed-attribute
363     * access="read-only"
364     */

365    public Node getRoot()
366    {
367       return root;
368    }
369
370    /**
371     * @jmx.managed-operation
372     * @jmx.managed-parameter name="listener"
373     * type="org.jboss.portal.server.util.tree.NodeChangeListener"
374     */

375    public void addNodeChangeListener(NodeChangeListener listener)
376    {
377       synchronized (listeners)
378       {
379          List JavaDoc listeners = new ArrayList JavaDoc(this.listeners);
380          listeners.add(listener);
381          this.listeners = listeners;
382       }
383    }
384
385    /**
386     * @jmx.managed-operation
387     * @jmx.managed-parameter name="listener"
388     * type="org.jboss.portal.server.util.tree.NodeChangeListener"
389     */

390    public void removeNodeChangeListener(NodeChangeListener listener)
391    {
392       synchronized (listeners)
393       {
394          List JavaDoc listeners = new ArrayList JavaDoc(this.listeners);
395          listeners.remove(listener);
396          this.listeners = listeners;
397       }
398    }
399
400    //
401

402    Object JavaDoc getProperty(NodeImpl node, String JavaDoc name)
403    {
404       try
405       {
406          Property prop = (Property)cache.get(node.fqn, name);
407          if (prop == null)
408          {
409             return null;
410          }
411          else
412          {
413             return prop.getValue();
414          }
415       }
416       catch (CacheException e)
417       {
418          log.error("", e);
419          return null;
420       }
421    }
422
423    void setProperty(NodeImpl node, String JavaDoc key, Object JavaDoc value)
424    {
425       try
426       {
427          Property prop = new Property(key, value);
428          cache.put(node.fqn, key, prop);
429       }
430       catch (CacheException e)
431       {
432          log.error("", e);
433       }
434    }
435
436    void removeProperty(NodeImpl node, String JavaDoc key)
437    {
438       try
439       {
440          cache.remove(node.fqn, key);
441       }
442       catch (CacheException e)
443       {
444          log.error("", e);
445       }
446    }
447
448    NodeImpl getChild(NodeImpl node, String JavaDoc key)
449    {
450       return (NodeImpl)nodeMap.get(new Fqn(node.fqn, key));
451    }
452
453    Map JavaDoc getChildren(NodeImpl node)
454    {
455       try
456       {
457          Map JavaDoc children = new HashMap JavaDoc();
458          for (Iterator JavaDoc i = cache.getChildrenNames(node.fqn).iterator(); i.hasNext();)
459          {
460             String JavaDoc key = (String JavaDoc)i.next();
461             Node child = (Node)nodeMap.get(new Fqn(node.fqn, key));
462             children.put(key, child);
463          }
464          return children;
465       }
466       catch (CacheException e)
467       {
468          log.error("", e);
469          return Collections.EMPTY_MAP;
470       }
471    }
472
473    NodeImpl addChild(NodeImpl parent, String JavaDoc key, Map JavaDoc properties)
474    {
475       try
476       {
477          //
478
Fqn childFqn = new Fqn(parent.fqn, key);
479
480          // Transform property format
481
properties = formatProperties(properties);
482
483          //
484
cache.put(childFqn, properties);
485          return (NodeImpl)nodeMap.get(childFqn);
486       }
487       catch (CacheException e)
488       {
489          log.error("", e);
490          return null;
491       }
492    }
493
494    void removeChild(NodeImpl parent, String JavaDoc key)
495    {
496       try
497       {
498          Fqn childFqn = new Fqn(parent.fqn, key);
499          cache.remove(childFqn);
500       }
501       catch (CacheException e)
502       {
503          log.error("", e);
504       }
505    }
506
507    NodeImpl addNode(FQN id, Map JavaDoc properties)
508    {
509       Fqn fqn = toFqn(id);
510       if (nodeMap.containsKey(fqn))
511       {
512          throw new IllegalArgumentException JavaDoc("Duplicate node");
513       }
514       try
515       {
516          properties = formatProperties(properties);
517          cache.put(fqn, properties);
518          return (NodeImpl)nodeMap.get(fqn);
519       }
520       catch (Exception JavaDoc e)
521       {
522          log.error("", e);
523          return null;
524       }
525    }
526
527    // TransactionManagerProvider implementation ************************************************************************
528

529    public TransactionManager JavaDoc getTransactionManager()
530    {
531       return observer;
532    }
533
534    // ModelManager implementation **************************************************************************************
535

536    public void nodeCreated(Fqn fqn)
537    {
538       // We don't track root creation
539
if (!fqn.equals(new Fqn()))
540       {
541          // Create a new node object and insert it
542
NodeImpl child = new NodeImpl(this, fqn);
543          nodeMap.put(fqn, child);
544
545          // Track change of the node
546
try
547          {
548             eventAdapter.created(fqn);
549          }
550          catch (IllegalStateException JavaDoc e)
551          {
552             log.error("An error occured during node created", e);
553          }
554       }
555    }
556
557    public void nodeRemoved(Fqn fqn)
558    {
559       // We don't track root removal
560
if (!fqn.equals(new Fqn()))
561       {
562          // Remove the node object
563
nodeMap.remove(fqn);
564
565          // Track change of the node
566
try
567          {
568             eventAdapter.removed(fqn);
569          }
570          catch (Exception JavaDoc e)
571          {
572             log.error("An error occured during node removed", e);
573          }
574       }
575    }
576
577    public void nodeModified(Fqn fqn)
578    {
579       // Track change of the node
580
try
581       {
582          eventAdapter.modified(fqn);
583       }
584       catch (IllegalStateException JavaDoc e)
585       {
586          log.error("An error occured during node modified", e);
587       }
588    }
589
590    public void nodeLoaded(Fqn fqn)
591    {
592       nodeCreated(fqn);
593    }
594
595    public void nodeEvicted(Fqn fqn)
596    {
597 // throw new UnsupportedOperationException();
598
}
599
600    public void nodeVisited(Fqn fqn)
601    {
602    }
603
604    public void cacheStarted(TreeCache cache)
605    {
606    }
607
608    public void cacheStopped(TreeCache cache)
609    {
610    }
611
612    public void viewChange(View view)
613    {
614    }
615
616    /**
617     * Return the parent fqn of the given fqn.
618     */

619    public static Fqn getParentFqn(Fqn childFqn)
620    {
621       Object JavaDoc[] parentObjects = new Object JavaDoc[childFqn.size() - 1];
622       for (int j = 0; j < parentObjects.length; j++)
623       {
624          Object JavaDoc parentObject = childFqn.get(j);
625          parentObjects[j] = parentObject;
626       }
627       Fqn parentFqn = new Fqn(parentObjects);
628       return parentFqn;
629    }
630
631    public static Fqn toFqn(FQN fqn)
632    {
633       return new Fqn(fqn.toArray());
634    }
635
636    public static FQN toFQN(Fqn fqn)
637    {
638       String JavaDoc[] names = new String JavaDoc[fqn.size()];
639       for (int i = 0; i < names.length; i++)
640       {
641          names[i] = (String JavaDoc)fqn.get(i);
642       }
643       return new FQN(names);
644    }
645
646    private Map JavaDoc formatProperties(Map JavaDoc properties)
647    {
648       properties = new HashMap JavaDoc(properties);
649       for (Iterator JavaDoc i = properties.entrySet().iterator(); i.hasNext();)
650       {
651          Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
652          String JavaDoc name = (String JavaDoc)entry.getKey();
653          Object JavaDoc value = entry.getValue();
654          entry.setValue(new Property(name, value));
655       }
656       return properties;
657    }
658
659    // ******************************************************************************************************************
660

661    /**
662     * Override createInterceptorChain() in order to replace cache loader interceptor with the fixed version one.
663     */

664    protected class FixedTreeCache extends TreeCache
665    {
666       public FixedTreeCache() throws Exception JavaDoc
667       {
668       }
669
670       protected void createInterceptorChain() throws IllegalAccessException JavaDoc, InstantiationException JavaDoc, ClassNotFoundException JavaDoc
671       {
672          super.createInterceptorChain();
673
674          // Temporary fix until we have fixed version that should be in JBoss-4.0.3
675
// Find cache loader interceptor and replace it
676
Interceptor previous = null;
677          for (Interceptor current = interceptor_chain; current != null; current = current.getNext())
678          {
679             log.debug("Iterating cache interceptors " + current.getClass().getName());
680             if ("org.jboss.cache.interceptors.CacheLoaderInterceptor".equals(current.getClass().getName()))
681             {
682                log.debug("Replacing current cache loader interceptor with fixed version one");
683
684                // Create and configure new interceptor
685
Interceptor interceptor = new FixedCacheLoaderInterceptor();
686                interceptor.setCache(this);
687
688                // Link interceptors
689
interceptor.setNext(current.getNext());
690                if (previous == null)
691                {
692                   interceptor_chain = interceptor;
693                }
694                else
695                {
696                   previous.setNext(interceptor);
697                }
698                break;
699             }
700             else
701             {
702                previous = current;
703             }
704          }
705       }
706    }
707
708    /**
709     * This is a copy paste of the cache loader interceptor in 4.0.2RC1 + the fix that notify node loaded
710     * after the entire node has been loaded from the store.
711     */

712    private static class FixedCacheLoaderInterceptor extends Interceptor
713    {
714       private CacheLoader loader = null;
715       private TreeCache cache = null;
716       private Logger log = null;
717
718       public FixedCacheLoaderInterceptor()
719       {
720          log = Logger.getLogger(FixedCacheLoaderInterceptor.class);
721       }
722
723       public void setCache(TreeCache cache)
724       {
725          super.setCache(cache);
726          this.cache = cache;
727          this.loader = cache.getCacheLoader();
728       }
729
730       /**
731        * Makes sure a node is loaded into memory before a call executes (no-op if node is already loaded). If attributes
732        * of a node are to be accessed by the method, the attributes are also loaded.
733        *
734        * @param m
735        * @return
736        * @throws Throwable
737        */

738       public Object JavaDoc invoke(MethodCall m) throws Throwable JavaDoc
739       {
740          Fqn fqn = null;
741          org.jboss.cache.Node n = null;
742          Method JavaDoc meth = m.getMethod();
743          Object JavaDoc[] args = m.getArgs();
744          boolean load_attributes = false; // load all attrs of a given node as well
745

746
747          /* On the way in: load elements into cache from the CacheLoader if not yet in the cache. We need to synchronize
748          this so only 1 thread attempts to load a given element */

749          synchronized (this)
750          {
751
752             if (meth.equals(TreeCache.putDataMethodLocal) || meth.equals(TreeCache.putDataEraseMethodLocal) ||
753                meth.equals(TreeCache.putKeyValMethodLocal))
754             {
755                fqn = (Fqn)args[1];
756                load_attributes = true;
757             }
758             else if (meth.equals(TreeCache.removeNodeMethodLocal))
759             {
760                // fqn=(Fqn)args[1]; // we don't need to load a node if it will be removed (bela Dec 3 2004)
761
}
762             else if (meth.equals(TreeCache.removeKeyMethodLocal) || meth.equals(TreeCache.removeDataMethodLocal))
763             {
764                fqn = (Fqn)args[1];
765                load_attributes = true;
766             }
767             else if (meth.equals(TreeCache.addChildMethodLocal))
768             {
769                fqn = (Fqn)args[1];
770             }
771             else if (meth.equals(TreeCache.getKeyValueMethodLocal))
772             {
773                fqn = (Fqn)args[0];
774                load_attributes = true;
775             }
776             else if (meth.equals(TreeCache.getNodeMethodLocal))
777             {
778                fqn = (Fqn)args[0];
779             }
780             else if (meth.equals(TreeCache.getKeysMethodLocal))
781             {
782                fqn = (Fqn)args[0];
783                load_attributes = true;
784             }
785             else if (meth.equals(TreeCache.getChildrenNamesMethodLocal) || meth.equals(TreeCache.releaseAllLocksMethodLocal) ||
786                meth.equals(TreeCache.printMethodLocal))
787             {
788                fqn = (Fqn)args[0];
789             }
790
791             if (fqn != null)
792             {
793                n = loadNode(fqn, load_attributes);
794                if (load_attributes && n != null)
795                {
796                   loadAttributesFromCacheLoader(n);
797                }
798             }
799
800             // special case: node is loaded, but children nodes haven't: check with CacheLoader if children nodes are
801
// present and load if yes
802
if (meth.equals(TreeCache.getChildrenNamesMethodLocal) && n != null && fqn != null)
803             {
804                Map JavaDoc children = n.getChildren();
805
806                if (children == null)
807                {
808                   Set JavaDoc children_names = null;
809                   try
810                   {
811                      children_names = loader.getChildrenNames(fqn);
812                   }
813                   catch (Exception JavaDoc e)
814                   {
815                      log.error("failed getting the children names for " + fqn + " from the cache loader", e);
816                   }
817                   if (children_names != null)
818                   {
819                      // create one Node per child, don't load attributes yet (marked as UNINITIALIZED)
820
for (Iterator JavaDoc it = children_names.iterator(); it.hasNext();)
821                      {
822                         String JavaDoc child_name = (String JavaDoc)it.next();
823                         Fqn child_fqn = new Fqn(n.getFqn(), child_name);
824                         n.createChild(child_name, child_fqn, n, TreeCache.UNINITIALIZED, null);
825                      }
826                   }
827                }
828             }
829          }
830
831          return super.invoke(m);
832       }
833
834
835       private org.jboss.cache.Node loadNode(Fqn fqn, boolean willAttrsBeLoaded)
836       {
837          org.jboss.cache.Node n, child_node = null;
838          Object JavaDoc child_name;
839          Fqn tmp_fqn = new Fqn();
840
841          if (fqn == null)
842          {
843             return null;
844          }
845          int treeNodeSize = fqn.size();
846
847          n = cache.getRoot();
848          for (int i = 0; i < treeNodeSize && n != null; i++)
849          {
850             child_name = fqn.get(i);
851             tmp_fqn = new Fqn(tmp_fqn, child_name);
852             child_node = n.getChild(child_name);
853
854             // try CacheLoader if node is not in cache
855
if (child_node == null)
856             {
857                try
858                {
859                   if (loader.exists(fqn))
860                   {
861                      child_node = n.createChild(child_name, tmp_fqn, n, TreeCache.UNINITIALIZED, null);
862                      if (willAttrsBeLoaded == false)
863                      {
864                         cache.notifyNodeLoaded(tmp_fqn);
865                      }
866                   }
867                }
868                catch (Throwable JavaDoc t)
869                {
870                   log.error("failure loading node " + fqn + " from CacheLoader", t);
871                }
872             }
873             n = child_node;
874          }
875          return n;
876       }
877
878
879       private void loadAttributesFromCacheLoader(org.jboss.cache.Node n)
880       {
881          if (n == null || !n.containsKey(TreeCache.UNINITIALIZED))
882          {
883             return;
884          }
885
886          // lazily load attributes before the method is executed
887
try
888          {
889             Map JavaDoc m = loader.get(n.getFqn());
890             n.remove(TreeCache.UNINITIALIZED); // all attributes have been loaded
891
n.put(m);
892             cache.notifyNodeLoaded(n.getFqn());
893          }
894          catch (Throwable JavaDoc t)
895          {
896             log.error("failure when lazily loading attributes of " + n.getFqn(), t);
897          }
898       }
899    }
900 }
901
Popular Tags