KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > core > impl > tree > loader > CMSCacheLoader


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.loader;
10
11 import org.jboss.cache.loader.CacheLoader;
12 import org.jboss.cache.TreeCache;
13 import org.jboss.cache.Fqn;
14 import org.jboss.cache.Modification;
15 import org.jboss.portal.cms.CMS;
16 import org.jboss.portal.cms.NodeFactory;
17 import org.jboss.portal.cms.Node;
18 import org.jboss.portal.cms.Content;
19 import org.jboss.portal.cms.NoSuchURIException;
20 import org.jboss.portal.common.transaction.Transactions;
21 import org.jboss.portal.core.impl.tree.Property;
22 import org.apache.log4j.Logger;
23
24 import java.util.Properties JavaDoc;
25 import java.util.Set JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.io.ObjectStreamException JavaDoc;
33 import java.io.ByteArrayOutputStream JavaDoc;
34 import java.io.ObjectOutputStream JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.io.ByteArrayInputStream JavaDoc;
37 import java.io.ObjectInputStream JavaDoc;
38 import java.io.DataOutputStream JavaDoc;
39 import java.io.DataInputStream JavaDoc;
40
41 /**
42  * @author <a HREF="mailto:julien@jboss.org">Julien Viet</a>
43  * @version $Revision: 1.4 $
44  */

45 public class CMSCacheLoader implements CacheLoader
46 {
47
48    /** Logger. */
49    protected Logger log = Logger.getLogger(CMSCacheLoader.class);
50
51    /** Properties. */
52    protected Properties JavaDoc props;
53
54    /** Cache. */
55    protected TreeCache cache;
56
57    /** The path where to store content in the cms tree. */
58    protected String JavaDoc path;
59
60    /** Modifications keyed to transaction for prepare/commit/rollback operations. */
61    protected Map JavaDoc transactions;
62
63    /** The CMS. */
64    protected CMS cms;
65
66    /** The marshaller map. */
67    protected Map JavaDoc marshallers = new HashMap JavaDoc();
68
69    public CMSCacheLoader()
70    {
71       transactions = new HashMap JavaDoc();
72    }
73
74    public void setConfig(Properties JavaDoc props)
75    {
76       this.props = props;
77       this.path = props.getProperty("cache.cms.path", "/scheme");
78       for (Iterator JavaDoc i = props.keySet().iterator();i.hasNext();)
79       {
80          String JavaDoc propName = (String JavaDoc)i.next();
81          if (propName.startsWith("cache.cms.marshaller."))
82          {
83             String JavaDoc marshallerClassName = props.getProperty(propName);
84             String JavaDoc className = propName.substring("cache.cms.marshaller.".length());
85             log.debug("Associate class " + className + " with marshaller class " + marshallerClassName);
86             try
87             {
88                Class JavaDoc marshallerClass = (Class JavaDoc)Thread.currentThread().getContextClassLoader().loadClass(marshallerClassName);
89                ContentMarshaller marshaller = (ContentMarshaller)marshallerClass.newInstance();
90                marshallers.put(className, marshaller);
91             }
92             catch (ClassNotFoundException JavaDoc e)
93             {
94                log.error("Cannot load marshaller class" + marshallerClassName, e);
95             }
96             catch (InstantiationException JavaDoc e)
97             {
98                log.error("Cannot create marshaller instance " + marshallerClassName, e);
99             }
100             catch (IllegalAccessException JavaDoc e)
101             {
102                log.error("Cannot create marshaller instance " + marshallerClassName, e);
103             }
104          }
105       }
106
107    }
108
109    public void setCache(TreeCache cache)
110    {
111       this.cache = cache;
112    }
113
114    public Set JavaDoc getChildrenNames(final Fqn fqn) throws Exception JavaDoc
115    {
116       return (Set JavaDoc)Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
117       {
118          public Object JavaDoc run() throws Exception JavaDoc
119          {
120             String JavaDoc uri = toURI(fqn);
121             Set JavaDoc names = null;
122             Node node = getFactory().getNode(uri);
123             if (node.exists())
124             {
125                for (Iterator JavaDoc i = node.getChildren().values().iterator(); i.hasNext();)
126                {
127                   Node child = (Node)i.next();
128                   try
129                   {
130                      if (child.isDir())
131                      {
132                         if (names == null)
133                         {
134                            names = new HashSet JavaDoc();
135                         }
136                         names.add(child.getName());
137                      }
138                   }
139                   catch (NullPointerException JavaDoc e)
140                   {
141                      e.printStackTrace();
142                      throw (NullPointerException JavaDoc)e;
143                   }
144                }
145             }
146             return names;
147          }
148       });
149    }
150
151    public Object JavaDoc get(final Fqn fqn, final Object JavaDoc key) throws Exception JavaDoc
152    {
153       return Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
154       {
155          public Object JavaDoc run() throws Exception JavaDoc
156          {
157             String JavaDoc uri = toURI(fqn);
158             Node node = getFactory().getNode(uri);
159             Node child = node.getChild(key.toString());
160             if (child.exists())
161             {
162                Object JavaDoc o = loadContent(child);
163                return o;
164             }
165             else
166             {
167                return null;
168             }
169          }
170       });
171    }
172
173    public Map JavaDoc get(final Fqn fqn) throws Exception JavaDoc
174    {
175       return (Map JavaDoc)Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
176       {
177          public Object JavaDoc run() throws Exception JavaDoc
178          {
179             String JavaDoc uri = toURI(fqn);
180             Node node = getFactory().getNode(uri);
181             Map JavaDoc data = null;
182             if (node.exists())
183             {
184                Map JavaDoc children = node.getChildren();
185                if (children.size() > 0)
186                {
187                   for (Iterator JavaDoc i = children.values().iterator(); i.hasNext();)
188                   {
189                      Node child = (Node)i.next();
190                      if (!child.isDir())
191                      {
192                         if (data == null)
193                         {
194                            data = new HashMap JavaDoc();
195                         }
196                         Object JavaDoc o = loadContent(child);
197                         data.put(child.getName(), o);
198                      }
199                   }
200                }
201             }
202             return data;
203          }
204       });
205    }
206
207    public boolean exists(final Fqn fqn) throws Exception JavaDoc
208    {
209       Boolean JavaDoc exists = (Boolean JavaDoc)Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
210       {
211          public Object JavaDoc run() throws Exception JavaDoc
212          {
213             String JavaDoc uri = toURI(fqn);
214             Node node = getFactory().getNode(uri);
215             boolean exists = node.exists();
216             return Boolean.valueOf(exists);
217          }
218       });
219       return exists.booleanValue();
220    }
221
222    public Object JavaDoc put(final Fqn fqn, final Object JavaDoc key, final Object JavaDoc value) throws Exception JavaDoc
223    {
224       return Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
225       {
226          public Object JavaDoc run() throws Exception JavaDoc
227          {
228             String JavaDoc uri = toURI(fqn);
229             Node node = getFactory().getNode(uri);
230             Node child = node.getChild(key.toString());
231             if (child.exists())
232             {
233                Object JavaDoc o = loadContent(child);
234                storeContent(child, (Property)value);
235                return o;
236             }
237             else
238             {
239                storeContent(child, (Property)value);
240                return null;
241             }
242          }
243       });
244    }
245
246    public void put(Fqn fqn, Map JavaDoc data) throws Exception JavaDoc
247    {
248       put(fqn, data, false);
249    }
250
251    public void put(final Fqn fqn, final Map JavaDoc data, final boolean erase) throws Exception JavaDoc
252    {
253       Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
254       {
255          public Object JavaDoc run() throws Exception JavaDoc
256          {
257             String JavaDoc uri = toURI(fqn);
258             Node node = getFactory().getNode(uri);
259             node.createDir(true);
260             if (erase)
261             {
262                for (Iterator JavaDoc i = node.getChildren().values().iterator(); i.hasNext();)
263                {
264                   Node child = (Node)i.next();
265                   if (!child.isDir())
266                   {
267                      child.delete();
268                   }
269                }
270             }
271             if (data != null)
272             {
273                for (Iterator JavaDoc i = data.entrySet().iterator(); i.hasNext();)
274                {
275                   Map.Entry JavaDoc entry = (Map.Entry JavaDoc)i.next();
276                   String JavaDoc key = entry.getKey().toString();
277                   Object JavaDoc value = entry.getValue();
278                   Node child = getFactory().getNode(uri + "/" + key);
279                   storeContent(child, (Property)value);
280                }
281             }
282             return null;
283          }
284       });
285    }
286
287    public Object JavaDoc remove(final Fqn fqn, final Object JavaDoc key) throws Exception JavaDoc
288    {
289       return Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
290       {
291          public Object JavaDoc run() throws Exception JavaDoc
292          {
293             String JavaDoc uri = toURI(fqn);
294             Node node = getFactory().getNode(uri);
295             Node child = node.getChild(key.toString());
296             if (child.exists())
297             {
298                Object JavaDoc value = loadContent(child);
299                child.delete();
300                return value;
301             }
302             else
303             {
304                return null;
305             }
306          }
307       });
308    }
309
310    public void remove(final Fqn fqn) throws Exception JavaDoc
311    {
312       Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
313       {
314          public Object JavaDoc run() throws Exception JavaDoc
315          {
316             String JavaDoc uri = toURI(fqn);
317             Node node = getFactory().getNode(uri);
318             try
319             {
320                node.delete();
321             }
322             catch (NoSuchURIException e)
323             {
324                //
325
}
326             return null;
327          }
328       });
329    }
330
331    public void removeData(final Fqn fqn) throws Exception JavaDoc
332    {
333       Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
334       {
335          public Object JavaDoc run() throws Exception JavaDoc
336          {
337             String JavaDoc uri = toURI(fqn);
338             Node node = getFactory().getNode(uri);
339             Map JavaDoc children = node.getChildren();
340             for (Iterator JavaDoc i = children.values().iterator(); i.hasNext();)
341             {
342                Node child = (Node)i.next();
343                if (!child.isDir())
344                {
345                   child.delete();
346                }
347             }
348             return null;
349          }
350       });
351    }
352
353    public void put(final List JavaDoc modifications) throws Exception JavaDoc
354    {
355       Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
356       {
357          public Object JavaDoc run() throws Exception JavaDoc
358          {
359             for (Iterator JavaDoc it = modifications.iterator(); it.hasNext();)
360             {
361                Modification m = (Modification)it.next();
362                switch (m.getType())
363                {
364                case Modification.PUT_DATA:
365                   put(m.getFqn(), m.getData());
366                   break;
367                case Modification.PUT_DATA_ERASE:
368                   put(m.getFqn(), m.getData(), true);
369                   break;
370                case Modification.PUT_KEY_VALUE:
371                   put(m.getFqn(), m.getKey(), m.getValue());
372                   break;
373                case Modification.REMOVE_DATA:
374                   removeData(m.getFqn());
375                   break;
376                case Modification.REMOVE_KEY_VALUE:
377                   remove(m.getFqn(), m.getKey());
378                   break;
379                case Modification.REMOVE_NODE:
380                   remove(m.getFqn());
381                   break;
382                default:
383                   log.error("modification type " + m.getType() + " not known");
384                   break;
385                }
386             }
387             return null;
388          }
389       });
390    }
391
392    public void prepare(Object JavaDoc tx, List JavaDoc modifications, boolean onePhase) throws Exception JavaDoc
393    {
394       if (onePhase)
395       {
396          put(modifications);
397       }
398       else
399       {
400          transactions.put(tx, modifications);
401       }
402    }
403
404    public void commit(Object JavaDoc tx) throws Exception JavaDoc
405    {
406       final List JavaDoc modifications = (List JavaDoc)transactions.get(tx);
407       Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
408       {
409          public Object JavaDoc run() throws Exception JavaDoc
410          {
411             put(modifications);
412             return null;
413          }
414       });
415    }
416
417    public void rollback(Object JavaDoc tx)
418    {
419       transactions.remove(tx);
420    }
421
422    public byte[] loadEntireState() throws Exception JavaDoc
423    {
424       return (byte[])Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
425       {
426          public Object JavaDoc run() throws Exception JavaDoc
427          {
428             String JavaDoc uri = toURI(new Fqn());
429             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
430             DataOutputStream JavaDoc dos = new DataOutputStream JavaDoc(baos);
431             loadState(uri, dos);
432             dos.close();
433             byte[] bytes = baos.toByteArray();
434             return bytes;
435          }
436       });
437    }
438
439    public void storeEntireState(final byte[] state) throws Exception JavaDoc
440    {
441       Transactions.required(cms.getNodeFactory().getTransactionManager(), new Transactions.Runnable()
442       {
443          public Object JavaDoc run() throws Exception JavaDoc
444          {
445             ByteArrayInputStream JavaDoc bais = new ByteArrayInputStream JavaDoc(state);
446             DataInputStream JavaDoc dis = new DataInputStream JavaDoc(bais);
447             storeState(dis);
448             return null;
449          }
450       });
451    }
452
453    /**
454     * Retrieve CMS during.
455     */

456    public void create() throws Exception JavaDoc
457    {
458       cms = CMS.getCMS();
459    }
460
461    public void start() throws Exception JavaDoc
462    {
463
464    }
465
466    public void stop()
467    {
468
469    }
470
471    public void destroy()
472    {
473    }
474
475    /**
476     * Load the state for the given URI and append it in the stream.
477     *
478     * @param uri the content uri to load
479     * @param out where to push the data
480     */

481    protected void loadState(String JavaDoc uri, final DataOutputStream JavaDoc out) throws Exception JavaDoc
482    {
483       // Prepare
484
Node node = getFactory().getNode(uri);
485       if (node.exists())
486       {
487          Map JavaDoc children = node.getChildren();
488          List JavaDoc contentNodes = new ArrayList JavaDoc();
489          List JavaDoc dirNodes = new ArrayList JavaDoc();
490          for (Iterator JavaDoc i = children.values().iterator(); i.hasNext();)
491          {
492             Node child = (Node)i.next();
493             if (child.isDir())
494             {
495                dirNodes.add(child);
496             }
497             else
498             {
499                contentNodes.add(child);
500             }
501          }
502
503          //
504
out.writeUTF(uri);
505
506          //
507
out.writeInt(contentNodes.size());
508          for (int i = 0; i < contentNodes.size(); i++)
509          {
510             Node contentNode = (Node)contentNodes.get(i);
511             Content content = contentNode.getContent();
512             out.writeUTF(contentNode.getURI());
513             out.writeUTF(content.getMimeType());
514             byte[] bytes = content.getBytes();
515             out.writeInt(bytes.length);
516             out.write(bytes);
517          }
518
519          //
520
out.writeInt(dirNodes.size());
521          for (int i = 0; i < dirNodes.size(); i++)
522          {
523             Node dirNode = (Node)dirNodes.get(i);
524             loadState(dirNode.getURI(), out);
525          }
526       }
527    }
528
529    /**
530     * Store the state in the store.
531     *
532     * @param in the data to read
533     */

534    protected void storeState(final DataInputStream JavaDoc in) throws Exception JavaDoc
535    {
536       String JavaDoc uri = in.readUTF();
537       Node node = getFactory().getNode(uri);
538       node.createDir(true);
539
540       //
541
for (int contentSize = in.readInt(); contentSize > 0; contentSize--)
542       {
543          String JavaDoc contentURI = in.readUTF();
544          String JavaDoc contentType = in.readUTF();
545          int length = in.readInt();
546          byte[] bytes = new byte[length];
547          in.read(bytes, 0, length);
548          Node contentNode = getFactory().getNode(contentURI);
549          contentNode.createContent(new Content(bytes, contentType), true);
550       }
551
552       //
553
for (int dirSize = in.readInt(); dirSize > 0; dirSize--)
554       {
555          storeState(in);
556       }
557    }
558
559    /**
560     * Convert a cache fqn to a CMS URI.
561     *
562     * @param fqn the fqn
563     * @return an URI
564     */

565    protected String JavaDoc toURI(Fqn fqn)
566    {
567       StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(path);
568       for (int i = 0; i < fqn.size(); i++)
569       {
570          buffer.append("/").append(fqn.get(i));
571       }
572       return buffer.toString();
573    }
574
575    /**
576     * Load content from a node. This implementation does :<br/>
577     * <p>get the property named jboss:classname</p>
578     * <p>lookup for a marshaller registered under the classname. If it is found then it is used
579     * to unmarshall the content</p>
580     * <p>otherwise calls the method <code>defaultUnmarshall</code> to unmarshall the content</p>
581     *
582     * @param node the node
583     * @return the corresponding content
584     */

585    protected Property loadContent(Node node) throws Exception JavaDoc
586    {
587       Content content = node.getContent();
588
589       // First get the class name
590
String JavaDoc className = node.getProperty("jboss", "classname");
591
592       // Lookup for a marshaller
593
ContentMarshaller marshaller = (ContentMarshaller)marshallers.get(className);
594
595       // Unmarshall
596
Object JavaDoc value = null;
597       if (marshaller != null)
598       {
599          value = marshaller.unmarshall(content);
600       }
601       else
602       {
603          byte[] bytes = content.getBytes();
604          value = defaultUnmarshall(bytes);
605       }
606       Property prop = new Property(node.getName(), value);
607       return prop;
608    }
609
610    /**
611     * Store the content in the given node. The implementation does :<br/>
612     * <p>Get the classname of the contained object</p>
613     * <p>Get a registered marshaller for this classname. If it is found then it is used to
614     * get the content</p>
615     * <p>Otherwise it calls the method <code>defaultMarshall</code> to get the content</p>
616     *
617     * @param node the stored node
618     * @param prop the value to store
619     */

620    protected void storeContent(Node node, Property prop) throws Exception JavaDoc
621    {
622       Object JavaDoc value = prop.getValue();
623       String JavaDoc className = value.getClass().getName();
624
625       Content content = null;
626       ContentMarshaller marshaller = (ContentMarshaller)marshallers.get(className);
627       if (marshaller != null)
628       {
629          content = marshaller.marshall(value);
630       }
631       else
632       {
633          byte[] bytes = defaultMarshall(value);
634          content = new Content(bytes, "text/plain");
635       }
636
637       node.createContent(content, true);
638       node.setProperty("jboss", "classname", className);
639    }
640
641    /**
642     * Called whenever no marshaller is found. The default implementation uses java serialization to marshall the content.
643     *
644     * @param o the object to marshall
645     * @return the marshalled object
646     * @throws ObjectStreamException
647     */

648    protected byte[] defaultMarshall(Object JavaDoc o) throws ObjectStreamException JavaDoc
649    {
650       ByteArrayOutputStream JavaDoc baos = null;
651       try
652       {
653          baos = new ByteArrayOutputStream JavaDoc();
654          ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(baos);
655          oos.writeObject(o);
656          oos.close();
657          return baos.toByteArray();
658       }
659       catch (IOException JavaDoc e)
660       {
661          if (e instanceof ObjectStreamException JavaDoc)
662          {
663             throw (ObjectStreamException JavaDoc)e;
664          }
665          throw new Error JavaDoc("Impossible", e);
666       }
667    }
668
669    /**
670     * Called whenever no marshaller is found. The default implementation uses java serialization to unmarshall the content.
671     * The classloader used is the thread context classloader.
672     *
673     * @param bytes the bytes to unmarshall
674     * @return the unmarshalled object.
675     * @throws ClassNotFoundException
676     * @throws ObjectStreamException
677     */

678    protected Object JavaDoc defaultUnmarshall(byte[] bytes) throws ClassNotFoundException JavaDoc, ObjectStreamException JavaDoc
679    {
680       try
681       {
682          ByteArrayInputStream JavaDoc bais = new ByteArrayInputStream JavaDoc(bytes);
683          ObjectInputStream JavaDoc ois = new ObjectInputStream JavaDoc(bais);
684          return ois.readObject();
685       }
686       catch (IOException JavaDoc e)
687       {
688          if (e instanceof ObjectStreamException JavaDoc)
689          {
690             throw (ObjectStreamException JavaDoc)e;
691          }
692          throw new Error JavaDoc("Impossible", e);
693       }
694    }
695
696    private NodeFactory getFactory()
697    {
698       return cms.getNodeFactory();
699    }
700 }
701
Popular Tags