1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.prefs.impl;
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Vector;
27
28 import org.apache.jetspeed.cache.CacheElement;
29 import org.apache.jetspeed.cache.DistributedCacheObject;
30 import org.apache.jetspeed.cache.JetspeedCache;
31 import org.apache.jetspeed.components.dao.InitablePersistenceBrokerDaoSupport;
32 import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
33 import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
34 import org.apache.jetspeed.prefs.FailedToCreateNodeException;
35 import org.apache.jetspeed.prefs.NodeAlreadyExistsException;
36 import org.apache.jetspeed.prefs.NodeDoesNotExistException;
37 import org.apache.jetspeed.prefs.PreferencesProvider;
38 import org.apache.jetspeed.prefs.om.Node;
39 import org.apache.jetspeed.prefs.om.Property;
40 import org.apache.jetspeed.prefs.om.impl.NodeImpl;
41 import org.apache.jetspeed.prefs.om.impl.PropertyImpl;
42 import org.apache.ojb.broker.query.Criteria;
43 import org.apache.ojb.broker.query.Query;
44 import org.apache.ojb.broker.query.QueryFactory;
45
46 /***
47 * <p>
48 * PersistenceBrokerPreferencesProvider
49 * </p>
50 *
51 * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
52 * @version $Id: PersistenceBrokerPreferencesProvider.java 605797 2007-12-20 03:39:09Z woonsan $
53 */
54 public class PersistenceBrokerPreferencesProvider extends InitablePersistenceBrokerDaoSupport implements
55 PreferencesProvider
56 {
57
58 private static class NodeCache implements DistributedCacheObject
59 {
60 /*** The serial uid. */
61 private static final long serialVersionUID = 1853381807991868844L;
62 NodeImplProxy node = null;
63 String key = null;;
64 Collection children = null;;
65
66 public NodeCache(NodeImplProxy node)
67 {
68
69 this.node = node;
70 this.key = node.getFullPath() + "-" + node.getNodeType();
71 }
72
73 public NodeCache(String fullpath, int type)
74 {
75
76 this.key = fullpath + "-" + type;
77 }
78
79 public boolean isChildrenLoaded()
80 {
81
82 return children != null;
83 }
84
85
86
87 public NodeImplProxy getNode()
88 {
89
90 return node;
91 }
92
93 public void setNode(NodeImplProxy node)
94 {
95
96 this.node = node;
97 }
98
99 public Collection getChildren()
100 {
101
102 return children;
103 }
104
105 public void setChildren(Collection children)
106 {
107
108 this.children = children;
109 }
110
111 public boolean equals(Object obj)
112 {
113 if (obj != null && obj instanceof NodeCache)
114 {
115 NodeCache other = (NodeCache) obj;
116 return getKey().equals(other.getKey());
117 }
118 return false;
119 }
120
121 public int hashCode()
122 {
123 return getKey().hashCode();
124 }
125
126 public String getCacheKey()
127 {
128 return getKey();
129 }
130
131 public String getKey()
132 {
133 return key;
134 }
135
136
137 public void notifyChange(int action)
138 {
139
140 switch (action)
141 {
142 case CacheElement.ActionAdded:
143
144 break;
145 case CacheElement.ActionChanged:
146
147 if (this.node != null)
148 this.node.invalidate();
149 break;
150 case CacheElement.ActionRemoved:
151
152 if (this.node != null)
153 this.node.invalidate();
154 break;
155 case CacheElement.ActionEvicted:
156
157 if (this.node != null)
158 this.node.invalidate();
159 break;
160 case CacheElement.ActionExpired:
161
162 if (this.node != null)
163 this.node.invalidate();
164 break;
165 default:
166 System.out.println("CacheObject - UNKOWN OPRERATION =" + this.getKey());
167 return;
168 }
169 return;
170 }
171 }
172
173 private JetspeedCache preferenceCache;
174 private List preloadedApplications;
175 private boolean preloadEntities = false;
176
177 /***
178 * @param repositoryPath
179 * Location of repository mapping file. Must be available within the classpath.
180 * @throws ClassNotFoundException
181 * if the <code>prefsFactoryImpl</code> argument does not reperesent a Class that exists in the
182 * current classPath.
183 */
184 public PersistenceBrokerPreferencesProvider(String repositoryPath)
185 throws ClassNotFoundException
186 {
187 super(repositoryPath);
188 NodeImplProxy.setProvider(this);
189 this.preloadedApplications = new LinkedList();
190 }
191
192
193 /***
194 * @param repository
195 * Location of repository mapping file. Must be available within the classpath.
196 * @param prefsFactoryImpl
197 * <code>java.util.prefs.PreferencesFactory</code> implementation to use.
198 * @param enablePropertyManager
199 * Whether or not we chould be suing the property manager.
200 * @throws ClassNotFoundException
201 * if the <code>prefsFactoryImpl</code> argument does not reperesent a Class that exists in the
202 * current classPath.
203 */
204 public PersistenceBrokerPreferencesProvider(String repositoryPath, JetspeedCache preferenceCache)
205 throws ClassNotFoundException
206 {
207 this(repositoryPath);
208 this.preferenceCache = preferenceCache;
209 }
210
211 public PersistenceBrokerPreferencesProvider(String repositoryPath, JetspeedCache preferenceCache, List apps, boolean preloadEntities)
212 throws ClassNotFoundException
213 {
214 this(repositoryPath);
215 this.preferenceCache = preferenceCache;
216 this.preloadedApplications = apps;
217 this.preloadEntities = preloadEntities;
218 }
219
220 protected void addToCache(NodeCache content)
221 {
222 CacheElement cachedElement = preferenceCache.createElement(content.getCacheKey(), content);
223 cachedElement.setTimeToIdleSeconds(preferenceCache.getTimeToIdleSeconds());
224 cachedElement.setTimeToLiveSeconds(preferenceCache.getTimeToLiveSeconds());
225 preferenceCache.put(cachedElement);
226 }
227
228 private NodeCache getNode(String cacheKey)
229 {
230 CacheElement cachedElement = preferenceCache.get(cacheKey);
231 if (cachedElement != null)
232 return (NodeCache)cachedElement.getContent();
233 return null;
234 }
235
236
237 public Node getNode(String fullPath, int nodeType) throws NodeDoesNotExistException
238 {
239 NodeCache key = new NodeCache(fullPath, nodeType);
240 NodeCache hit = getNode(key.getCacheKey());
241 if (hit != null)
242 {
243 return hit.getNode();
244 }
245
246 Criteria c = new Criteria();
247 c.addEqualTo("fullPath", fullPath);
248 c.addEqualTo("nodeType", new Integer(nodeType));
249 Query query = QueryFactory.newQuery(NodeImpl.class, c);
250
251 Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery(query);
252 if (null != nodeObj)
253 {
254 NodeImplProxy proxy = new NodeImplProxy(nodeObj);
255 addToCache(new NodeCache(proxy));
256 return proxy;
257
258 }
259 else
260 {
261 throw new NodeDoesNotExistException("No node of type " + nodeType + "found at path: " + fullPath);
262 }
263 }
264 /***
265 * @see org.apache.jetspeed.prefs.PreferencesProvider#getNode(java.lang.String, int)
266 */
267 public void redoNode(NodeImplProxy proxy, String fullPath, int nodeType) throws NodeDoesNotExistException
268 {
269
270 Criteria c = new Criteria();
271 c.addEqualTo("fullPath", fullPath);
272 c.addEqualTo("nodeType", new Integer(nodeType));
273 Query query = QueryFactory.newQuery(NodeImpl.class, c);
274
275 Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery(query);
276 if (null != nodeObj)
277 {
278 proxy.setNode(nodeObj);
279 NodeCache cn = new NodeCache(nodeObj.getFullPath(), nodeObj.getNodeType());
280 cn.setNode(proxy);
281 addToCache(cn);
282 }
283 else
284 {
285 throw new NodeDoesNotExistException("No node of type " + nodeType + "found at path: " + fullPath);
286 }
287 }
288
289 /***
290 * @see org.apache.jetspeed.prefs.PreferencesProvider#nodeExists(java.lang.String, int)
291 */
292 public boolean nodeExists(String fullPath, int nodeType)
293 {
294 NodeCache key = new NodeCache(fullPath, nodeType);
295 if (preferenceCache.isKeyInCache(key))
296 return true;
297 Criteria c = new Criteria();
298 c.addEqualTo("fullPath", fullPath);
299 c.addEqualTo("nodeType", new Integer(nodeType));
300 Query query = QueryFactory.newQuery(NodeImpl.class, c);
301
302 Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery(query);
303 if (null != nodeObj)
304 {
305 NodeImplProxy proxy = new NodeImplProxy(nodeObj);
306 addToCache(new NodeCache(proxy));
307 return true;
308 }
309 else
310 {
311 return false;
312 }
313 }
314
315 /***
316 * @see org.apache.jetspeed.prefs.PreferencesProvider#createNode(org.apache.jetspeed.prefs.om.Node, java.lang.String, int, java.lang.String)
317 */
318 public Node createNode(Node parent, String nodeName, int nodeType, String fullPath)
319 throws FailedToCreateNodeException, NodeAlreadyExistsException
320 {
321 if (nodeExists(fullPath, nodeType))
322 {
323 throw new NodeAlreadyExistsException("Node of type " + nodeType + " already exists at path " + fullPath);
324 }
325 else
326 {
327 Long parentNodeId = null;
328 if (null != parent)
329 {
330 parentNodeId = new Long(parent.getNodeId());
331 }
332
333 Node nodeObj = new NodeImpl(parentNodeId, nodeName, nodeType, fullPath);
334
335 try
336 {
337 getPersistenceBrokerTemplate().store(nodeObj);
338 NodeImplProxy proxy = new NodeImplProxy(nodeObj);
339 addToCache(new NodeCache(proxy));
340 return proxy;
341 }
342 catch (Exception e)
343 {
344 throw new FailedToCreateNodeException("Failed to create node of type " + nodeType + " for the path "
345 + fullPath + ". " + e.toString(), e);
346 }
347
348 }
349 }
350
351 /***
352 * @see org.apache.jetspeed.prefs.PreferencesProvider#getChildren(org.apache.jetspeed.prefs.om.Node)
353 */
354 public Collection getChildren(Node parentNode)
355 {
356 NodeCache key = new NodeCache(parentNode.getFullPath(), parentNode.getNodeType());
357
358 NodeCache hit = getNode(key.getCacheKey());
359 if (hit == null)
360 {
361 NodeImplProxy proxy = new NodeImplProxy(parentNode);
362 hit = new NodeCache(proxy);
363 addToCache(hit);
364 }
365 if (hit.isChildrenLoaded())
366 {
367 return resolveChildren(hit.getChildren());
368 }
369
370 Criteria c = new Criteria();
371 c.addEqualTo("parentNodeId", new Long(parentNode.getNodeId()));
372 Query query = QueryFactory.newQuery(NodeImpl.class, c);
373 Collection children = getPersistenceBrokerTemplate().getCollectionByQuery(query);
374 hit.setChildren(cacheChildren(children));
375
376 return children;
377 }
378
379
380 private Collection resolveChildren(Collection children)
381 {
382 if (children == null)
383 return null;
384 try
385 {
386 Iterator it = children.iterator();
387 Vector v = new Vector();
388 while (it.hasNext())
389 {
390 String s = (String) it.next();
391 NodeCache hit = getNode(s);
392 if (hit != null)
393 {
394 v.add(hit.getNode());
395 }
396 else
397 {
398 int index = s.lastIndexOf("-");
399 if (index > 0)
400 {
401 String fullPath = s.substring(0, index);
402 int type = Integer.parseInt(s.substring(index + 1));
403 Node node = getNode(fullPath, type);
404 if (node != null)
405 {
406 v.add(node);
407 }
408 }
409 }
410 }
411 return v;
412 }
413 catch (Exception e)
414 {
415 e.printStackTrace();
416 return null;
417 }
418 }
419
420
421 private Collection cacheChildren(Collection children)
422 {
423 Iterator it = children.iterator();
424 Vector v = new Vector();
425 while (it.hasNext())
426 {
427 Node key = (Node)it.next();
428 NodeCache nodeKey = new NodeCache(key.getFullPath(),key.getNodeType());
429 NodeCache hit = getNode(nodeKey.getCacheKey());
430 if (hit == null)
431 {
432 NodeImplProxy proxy = new NodeImplProxy(key);
433 nodeKey.setNode(proxy);
434 addToCache(nodeKey);
435 hit= nodeKey;
436 }
437 v.add(hit.getCacheKey());
438 }
439 return v;
440 }
441
442 /***
443 * @see org.apache.jetspeed.prefs.PreferencesProvider#storeNode(org.apache.jetspeed.prefs.om.Node)
444 */
445 public void storeNode(Node node)
446 {
447 NodeImplProxy hit = null;
448 if (node instanceof NodeImplProxy)
449 {
450 hit = (NodeImplProxy)node;
451 }
452 else
453 {
454
455 hit = new NodeImplProxy(node);
456 }
457
458 NodeCache key = new NodeCache(hit);
459 getPersistenceBrokerTemplate().store(hit.getNode());
460
461 preferenceCache.remove(key.getCacheKey());
462 addToCache(key);
463 }
464
465 /***
466 * @see org.apache.jetspeed.prefs.PreferencesProvider#removeNode(org.apache.jetspeed.prefs.om.Node, org.apache.jetspeed.prefs.om.Node)
467 */
468 public void removeNode(Node parentNode, Node node)
469 {
470 NodeImplProxy hit = null;
471 NodeImplProxy parentHit = null;
472
473 if (node instanceof NodeImplProxy)
474 {
475 getPersistenceBrokerTemplate().delete(((NodeImplProxy)node).getNode());
476 }
477 else
478 getPersistenceBrokerTemplate().delete(node);
479
480 if (node instanceof NodeImplProxy)
481 {
482 hit = (NodeImplProxy)node;
483 }
484 else
485 {
486
487 hit = new NodeImplProxy(node);
488 }
489 NodeCache key = new NodeCache(hit);
490 preferenceCache.remove(key.getCacheKey());
491 if ( parentNode != null )
492 {
493 if (parentNode instanceof NodeImplProxy)
494 {
495 parentHit = (NodeImplProxy)parentNode;
496 }
497 else
498 {
499
500 parentHit = new NodeImplProxy(parentNode);
501 }
502 NodeCache parentKey = new NodeCache(parentHit);
503 parentKey = getNode(parentKey.getCacheKey());
504 if ( parentKey != null && parentKey.isChildrenLoaded() )
505 {
506 parentKey.getChildren().remove(key.getCacheKey());
507 }
508 }
509 }
510
511 /***
512 * @see org.apache.jetspeed.prefs.PreferencesProvider#lookupPreference(java.lang.String, java.lang.String, java.lang.String)
513 */
514 public Collection lookupPreference(String nodeName, String propertyName, String propertyValue)
515 {
516 Criteria c = new Criteria();
517 if (nodeName != null)
518 {
519 c.addEqualTo("nodeName", nodeName);
520 }
521 if (propertyName != null)
522 {
523 c.addEqualTo("nodeProperties.propertyName", propertyName);
524 }
525 if (propertyValue != null)
526 {
527 c.addEqualTo("nodeProperties.propertyValue", propertyValue);
528 }
529 Query query = QueryFactory.newQuery(NodeImpl.class, c);
530 Collection children = getPersistenceBrokerTemplate().getCollectionByQuery(query);
531 Collection proxied = new ArrayList();
532 Iterator iter = children.iterator();
533 while (iter.hasNext())
534 {
535 NodeImpl node = (NodeImpl)iter.next();
536 NodeCache key = new NodeCache(node.getFullPath(), node.getNodeType());
537 NodeCache hit = getNode(key.getCacheKey());
538 if (hit == null)
539 {
540 NodeImplProxy proxy = new NodeImplProxy(node);
541 addToCache(new NodeCache(proxy));
542 proxied.add(proxy);
543 }
544 else
545 {
546 proxied.add(hit.getNode());
547 }
548 }
549 return proxied;
550 }
551
552 public Property createProperty(Node node, String name, Object value)
553 {
554 return new PropertyImpl(node.getNodeId(), name, value);
555 }
556
557 public void init() throws Exception
558 {
559 super.init();
560 Iterator apps = this.preloadedApplications.iterator();
561 while (apps.hasNext())
562 {
563 String appName = (String)apps.next();
564 preloadApplicationPreferences(appName);
565 }
566 if (preloadEntities)
567 preloadAllEntities();
568 }
569
570 public void preloadApplicationPreferences(String portletApplicationName) throws NodeDoesNotExistException
571 {
572 String portletDefPrefPath = "/" + MutablePortletApplication.PREFS_ROOT + "/" + portletApplicationName + "/";
573
574
575
576
577
578
579
580
581
582 long start = System.currentTimeMillis();
583 int count = loadNodeAndAllChildren(portletDefPrefPath);
584 long elapsed = System.currentTimeMillis() - start;
585 System.out.println("++++ PREFS:PA loaded " + count + " pref nodes for app " + portletDefPrefPath + " in " + elapsed + " milliseconds.");
586 }
587
588 protected int loadNodeAndAllChildren(String path)
589 {
590 int count = 0;
591 NodeCache root = null;
592 Criteria c = new Criteria();
593 c.addLike("fullPath", path + "%");
594
595 Query query = QueryFactory.newQuery(NodeImpl.class, c);
596 Collection result = getPersistenceBrokerTemplate().getCollectionByQuery(query);
597
598 if (result == null || result.isEmpty())
599 {
600 return count;
601 }
602 Iterator ri = result.iterator();
603 if (ri.hasNext())
604 {
605 Node n = (Node)ri.next();
606 NodeImplProxy proxy = new NodeImplProxy(n);
607 root = new NodeCache(proxy);
608 addToCache(root);
609 count++;
610 }
611 else
612 {
613 return count;
614 }
615 Map parents = new HashMap();
616 parents.put(new Long(root.getNode().getNodeId()), root);
617 while (ri.hasNext())
618 {
619
620 Node subNode = (Node)ri.next();
621
622
623 NodeCache nodeKey = new NodeCache(subNode.getFullPath(), subNode.getNodeType());
624 NodeCache lookup = getNode(nodeKey.getCacheKey());
625 if (lookup == null)
626 {
627 NodeImplProxy proxy = new NodeImplProxy(subNode);
628 nodeKey.setNode(proxy);
629 addToCache(nodeKey);
630 lookup = nodeKey;
631 }
632 NodeCache parent = (NodeCache)parents.get(subNode.getParentNodeId());
633 if (parent != null)
634 {
635 if (parent.getChildren() == null)
636 parent.setChildren(new ArrayList());
637 parent.getChildren().add(lookup.getCacheKey());
638 count += parent.getChildren().size();
639 }
640 parents.put(new Long(subNode.getNodeId()), lookup);
641 count++;
642 }
643 return count;
644 }
645
646 public void preloadAllEntities() throws NodeDoesNotExistException
647 {
648 String entitiesRoot = "/" + MutablePortletEntity.PORTLET_ENTITY_ROOT + "/";
649 long start = System.currentTimeMillis();
650 int count = loadNodeAndAllChildren(entitiesRoot);
651 long elapsed = System.currentTimeMillis() - start;
652 System.out.println("++++ PREFS:ENTITIES loaded " + count + " total entity pref nodes in " + elapsed + " milliseconds.");
653 }
654
655 }