svnno****@sourc*****
svnno****@sourc*****
2008年 5月 15日 (木) 22:53:50 JST
Revision: 937 http://svn.sourceforge.jp/cgi-bin/viewcvs.cgi?root=pal&view=rev&rev=937 Author: shinsuke Date: 2008-05-15 22:53:50 +0900 (Thu, 15 May 2008) Log Message: ----------- backport of 643116. Modified Paths: -------------- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PersistenceBrokerPreferencesProvider.java pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/src/webapp/WEB-INF/assembly/prefs.xml Added Paths: ----------- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/commons/src/java/org/apache/jetspeed/util/PreferencesRootWrapper.java pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesProviderWrapper.java -------------- next part -------------- Added: pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/commons/src/java/org/apache/jetspeed/util/PreferencesRootWrapper.java =================================================================== --- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/commons/src/java/org/apache/jetspeed/util/PreferencesRootWrapper.java (rev 0) +++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/commons/src/java/org/apache/jetspeed/util/PreferencesRootWrapper.java 2008-05-15 13:53:50 UTC (rev 937) @@ -0,0 +1,240 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jetspeed.util; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.Observable; +import java.util.Observer; +import java.util.prefs.BackingStoreException; +import java.util.prefs.NodeChangeListener; +import java.util.prefs.PreferenceChangeListener; +import java.util.prefs.Preferences; + +/** + * PreferencesRootWrapper is a lightweight wrapper around the Jetspeed + * persistent PreferencesImpl to allow restarting the Jetspeed Portal. + * <p> + * As the (Sun) Java Preferences implementation only creates a + * PreferencesFactory instance *once* per JVM (as static final), reloading the + * Jetspeed Portal (using a new classloader) requires a wrapper solution to + * prevent ClassCastExceptions and/or out-of-sync kept proxies and caches. + * </p> + * <p> + * As a newly created Jetspeed Portal classloader can no longer cast a previous + * Preferences root to its own PreferencesImpl, a "trick" is used by also + * implementing the Observer interface (which is provided by the Java system + * classloader). The Observer interface is used because it is very lightweight + * and allows passing an Object instance through its update method. That update + * method is used to "inject" the newly created Preferences root instance. + * </p> + * + * @author <a href="mailto:ate****@douma*****">Ate Douma</a> + * @version $Id$ + */ +public class PreferencesRootWrapper extends Preferences implements Observer +{ + + private Preferences root; + + public String absolutePath() + { + return root.absolutePath(); + } + + public void addNodeChangeListener(NodeChangeListener ncl) + { + root.addNodeChangeListener(ncl); + } + + public void addPreferenceChangeListener(PreferenceChangeListener pcl) + { + root.addPreferenceChangeListener(pcl); + } + + public String[] childrenNames() throws BackingStoreException + { + return root.childrenNames(); + } + + public void clear() throws BackingStoreException + { + root.clear(); + } + + public boolean equals(Object obj) + { + return root.equals(obj); + } + + public void exportNode(OutputStream os) throws IOException, + BackingStoreException + { + root.exportNode(os); + } + + public void exportSubtree(OutputStream os) throws IOException, + BackingStoreException + { + root.exportSubtree(os); + } + + public void flush() throws BackingStoreException + { + root.flush(); + } + + public String get(String key, String def) + { + return root.get(key, def); + } + + public boolean getBoolean(String key, boolean def) + { + return root.getBoolean(key, def); + } + + public byte[] getByteArray(String key, byte[] def) + { + return root.getByteArray(key, def); + } + + public double getDouble(String key, double def) + { + return root.getDouble(key, def); + } + + public float getFloat(String key, float def) + { + return root.getFloat(key, def); + } + + public int getInt(String key, int def) + { + return root.getInt(key, def); + } + + public long getLong(String key, long def) + { + return root.getLong(key, def); + } + + public int hashCode() + { + return root.hashCode(); + } + + public boolean isUserNode() + { + return root.isUserNode(); + } + + public String[] keys() throws BackingStoreException + { + return root.keys(); + } + + public String name() + { + return root.name(); + } + + public Preferences node(String pathName) + { + return root.node(pathName); + } + + public boolean nodeExists(String pathName) throws BackingStoreException + { + return root.nodeExists(pathName); + } + + public Preferences parent() + { + return root.parent(); + } + + public void put(String key, String value) + { + root.put(key, value); + } + + public void putBoolean(String key, boolean value) + { + root.putBoolean(key, value); + } + + public void putByteArray(String key, byte[] value) + { + root.putByteArray(key, value); + } + + public void putDouble(String key, double value) + { + root.putDouble(key, value); + } + + public void putFloat(String key, float value) + { + root.putFloat(key, value); + } + + public void putInt(String key, int value) + { + root.putInt(key, value); + } + + public void putLong(String key, long value) + { + root.putLong(key, value); + } + + public void remove(String key) + { + root.remove(key); + } + + public void removeNode() throws BackingStoreException + { + root.removeNode(); + } + + public void removeNodeChangeListener(NodeChangeListener ncl) + { + root.removeNodeChangeListener(ncl); + } + + public void removePreferenceChangeListener(PreferenceChangeListener pcl) + { + root.removePreferenceChangeListener(pcl); + } + + public void sync() throws BackingStoreException + { + root.sync(); + } + + public String toString() + { + return root.toString(); + } + + public void update(Observable o, Object arg) + { + root = (Preferences) arg; + } +} Property changes on: pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/commons/src/java/org/apache/jetspeed/util/PreferencesRootWrapper.java ___________________________________________________________________ Name: svn:eol-style + native Modified: pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PersistenceBrokerPreferencesProvider.java =================================================================== --- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PersistenceBrokerPreferencesProvider.java 2008-05-15 13:51:07 UTC (rev 936) +++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PersistenceBrokerPreferencesProvider.java 2008-05-15 13:53:50 UTC (rev 937) @@ -49,62 +49,71 @@ * </p> * * @author <a href="mailto:weave****@apach*****">Scott T. Weaver </a> - * @version $Id: PersistenceBrokerPreferencesProvider.java 605797 2007-12-20 03:39:09Z woonsan $ + * @version $Id$ */ -public class PersistenceBrokerPreferencesProvider extends InitablePersistenceBrokerDaoSupport implements - PreferencesProvider +public class PersistenceBrokerPreferencesProvider extends + InitablePersistenceBrokerDaoSupport implements PreferencesProvider { - + private static class NodeCache implements DistributedCacheObject { + /** The serial uid. */ private static final long serialVersionUID = 1853381807991868844L; + NodeImplProxy node = null; + String key = null;; + Collection children = null;; public NodeCache(NodeImplProxy node) { - // System.out.println(this.getClass().getName() + "-" + "NodeCache (node)" + node.getFullPath()); + // System.out.println(this.getClass().getName() + "-" + "NodeCache + // (node)" + node.getFullPath()); this.node = node; this.key = node.getFullPath() + "-" + node.getNodeType(); } public NodeCache(String fullpath, int type) { - // System.out.println(this.getClass().getName() + "-" + "NodeCache - fullpath=" + fullpath); + // System.out.println(this.getClass().getName() + "-" + "NodeCache - + // fullpath=" + fullpath); this.key = fullpath + "-" + type; } public boolean isChildrenLoaded() { - // System.out.println(this.getClass().getName() + "-" + "isChildrenLoaded"); + // System.out.println(this.getClass().getName() + "-" + + // "isChildrenLoaded"); return children != null; } - - public NodeImplProxy getNode() { - // System.out.println(this.getClass().getName() + "-" + "getNode=" + node.getFullPath()); + // System.out.println(this.getClass().getName() + "-" + "getNode=" + + // node.getFullPath()); return node; } public void setNode(NodeImplProxy node) { - // System.out.println(this.getClass().getName() + "-" + "setFullpath=" + node.getFullPath()); + // System.out.println(this.getClass().getName() + "-" + + // "setFullpath=" + node.getFullPath()); this.node = node; } public Collection getChildren() { - // System.out.println(this.getClass().getName() + "-" + "getCHildren=" ); + // System.out.println(this.getClass().getName() + "-" + + // "getCHildren=" ); return children; } public void setChildren(Collection children) { - // System.out.println(this.getClass().getName() + "-" + "setChildren=" ); + // System.out.println(this.getClass().getName() + "-" + + // "setChildren=" ); this.children = children; } @@ -122,64 +131,63 @@ { return getKey().hashCode(); } - + public String getCacheKey() { return getKey(); } - public String getKey() - { - return key; - } + public String getKey() + { + return key; + } - - public void notifyChange(int action) - { + public void notifyChange(int action) + { - switch (action) - { - case CacheElement.ActionAdded: -// System.out.println("CacheObject Added =" + this.getKey()); - break; - case CacheElement.ActionChanged: -// System.out.println("CacheObject Changed =" + this.getKey()); - if (this.node != null) - this.node.invalidate(); - break; - case CacheElement.ActionRemoved: -// System.out.println("CacheObject Removed =" + this.getKey()); - if (this.node != null) - this.node.invalidate(); - break; - case CacheElement.ActionEvicted: -// System.out.println("CacheObject Evicted =" + this.getKey()); - if (this.node != null) - this.node.invalidate(); - break; - case CacheElement.ActionExpired: -// System.out.println("CacheObject Expired =" + this.getKey()); - if (this.node != null) - this.node.invalidate(); - break; - default: - System.out.println("CacheObject - UNKOWN OPRERATION =" + this.getKey()); - return; - } - return; - } + switch (action) + { + case CacheElement.ActionAdded: + // System.out.println("CacheObject Added =" + this.getKey()); + break; + case CacheElement.ActionChanged: + // System.out.println("CacheObject Changed =" + this.getKey()); + if (this.node != null) this.node.invalidate(); + break; + case CacheElement.ActionRemoved: + // System.out.println("CacheObject Removed =" + this.getKey()); + if (this.node != null) this.node.invalidate(); + break; + case CacheElement.ActionEvicted: + // System.out.println("CacheObject Evicted =" + this.getKey()); + if (this.node != null) this.node.invalidate(); + break; + case CacheElement.ActionExpired: + // System.out.println("CacheObject Expired =" + this.getKey()); + if (this.node != null) this.node.invalidate(); + break; + default: + System.out.println("CacheObject - UNKOWN OPRERATION =" + + this.getKey()); + return; + } + return; + } } private JetspeedCache preferenceCache; + private List preloadedApplications; + private boolean preloadEntities = false; - + /** * @param repositoryPath - * Location of repository mapping file. Must be available within the classpath. + * Location of repository mapping file. Must be available within + * the classpath. * @throws ClassNotFoundException - * if the <code>prefsFactoryImpl</code> argument does not reperesent a Class that exists in the - * current classPath. + * if the <code>prefsFactoryImpl</code> argument does not + * reperesent a Class that exists in the current classPath. */ public PersistenceBrokerPreferencesProvider(String repositoryPath) throws ClassNotFoundException @@ -189,120 +197,138 @@ this.preloadedApplications = new LinkedList(); } - /** * @param repository - * Location of repository mapping file. Must be available within the classpath. + * Location of repository mapping file. Must be available within + * the classpath. * @param prefsFactoryImpl - * <code>java.util.prefs.PreferencesFactory</code> implementation to use. + * <code>java.util.prefs.PreferencesFactory</code> + * implementation to use. * @param enablePropertyManager * Whether or not we chould be suing the property manager. * @throws ClassNotFoundException - * if the <code>prefsFactoryImpl</code> argument does not reperesent a Class that exists in the - * current classPath. + * if the <code>prefsFactoryImpl</code> argument does not + * reperesent a Class that exists in the current classPath. */ - public PersistenceBrokerPreferencesProvider(String repositoryPath, JetspeedCache preferenceCache) - throws ClassNotFoundException + public PersistenceBrokerPreferencesProvider(String repositoryPath, + JetspeedCache preferenceCache) throws ClassNotFoundException { this(repositoryPath); this.preferenceCache = preferenceCache; } - public PersistenceBrokerPreferencesProvider(String repositoryPath, JetspeedCache preferenceCache, List apps, boolean preloadEntities) - throws ClassNotFoundException + public PersistenceBrokerPreferencesProvider(String repositoryPath, + JetspeedCache preferenceCache, List apps, boolean preloadEntities) + throws ClassNotFoundException { this(repositoryPath); this.preferenceCache = preferenceCache; this.preloadedApplications = apps; this.preloadEntities = preloadEntities; } - + + public void destroy() + { + NodeImplProxy.setProvider(null); + preferenceCache = null; + preloadedApplications = null; + } + protected void addToCache(NodeCache content) { - CacheElement cachedElement = preferenceCache.createElement(content.getCacheKey(), content); - cachedElement.setTimeToIdleSeconds(preferenceCache.getTimeToIdleSeconds()); - cachedElement.setTimeToLiveSeconds(preferenceCache.getTimeToLiveSeconds()); - preferenceCache.put(cachedElement); - } - + CacheElement cachedElement = preferenceCache.createElement(content + .getCacheKey(), content); + cachedElement.setTimeToIdleSeconds(preferenceCache + .getTimeToIdleSeconds()); + cachedElement.setTimeToLiveSeconds(preferenceCache + .getTimeToLiveSeconds()); + preferenceCache.put(cachedElement); + } + private NodeCache getNode(String cacheKey) { - CacheElement cachedElement = preferenceCache.get(cacheKey); + CacheElement cachedElement = preferenceCache.get(cacheKey); if (cachedElement != null) - return (NodeCache)cachedElement.getContent(); + return (NodeCache) cachedElement.getContent(); return null; } - - public Node getNode(String fullPath, int nodeType) throws NodeDoesNotExistException + public Node getNode(String fullPath, int nodeType) + throws NodeDoesNotExistException { NodeCache key = new NodeCache(fullPath, nodeType); NodeCache hit = getNode(key.getCacheKey()); - if (hit != null) - { - return hit.getNode(); - } + if (hit != null) { return hit.getNode(); } Criteria c = new Criteria(); c.addEqualTo("fullPath", fullPath); c.addEqualTo("nodeType", new Integer(nodeType)); Query query = QueryFactory.newQuery(NodeImpl.class, c); - Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery(query); + Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery( + query); if (null != nodeObj) { - NodeImplProxy proxy = new NodeImplProxy(nodeObj); + NodeImplProxy proxy = new NodeImplProxy(nodeObj); addToCache(new NodeCache(proxy)); return proxy; - + } else { - throw new NodeDoesNotExistException("No node of type " + nodeType + "found at path: " + fullPath); + throw new NodeDoesNotExistException("No node of type " + nodeType + + "found at path: " + fullPath); } } + /** - * @see org.apache.jetspeed.prefs.PreferencesProvider#getNode(java.lang.String, int) + * @see org.apache.jetspeed.prefs.PreferencesProvider#getNode(java.lang.String, + * int) */ - public void redoNode(NodeImplProxy proxy, String fullPath, int nodeType) throws NodeDoesNotExistException + public void redoNode(NodeImplProxy proxy, String fullPath, int nodeType) + throws NodeDoesNotExistException { - + Criteria c = new Criteria(); c.addEqualTo("fullPath", fullPath); c.addEqualTo("nodeType", new Integer(nodeType)); Query query = QueryFactory.newQuery(NodeImpl.class, c); - Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery(query); + Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery( + query); if (null != nodeObj) { - proxy.setNode(nodeObj); - NodeCache cn = new NodeCache(nodeObj.getFullPath(), nodeObj.getNodeType()); - cn.setNode(proxy); + proxy.setNode(nodeObj); + NodeCache cn = new NodeCache(nodeObj.getFullPath(), nodeObj + .getNodeType()); + cn.setNode(proxy); addToCache(cn); } else { - throw new NodeDoesNotExistException("No node of type " + nodeType + "found at path: " + fullPath); + throw new NodeDoesNotExistException("No node of type " + nodeType + + "found at path: " + fullPath); } } /** - * @see org.apache.jetspeed.prefs.PreferencesProvider#nodeExists(java.lang.String, int) + * @see org.apache.jetspeed.prefs.PreferencesProvider#nodeExists(java.lang.String, + * int) */ public boolean nodeExists(String fullPath, int nodeType) { NodeCache key = new NodeCache(fullPath, nodeType); - if (preferenceCache.isKeyInCache(key)) - return true; + if (preferenceCache.isKeyInCache(key)) return true; Criteria c = new Criteria(); c.addEqualTo("fullPath", fullPath); c.addEqualTo("nodeType", new Integer(nodeType)); Query query = QueryFactory.newQuery(NodeImpl.class, c); - Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery(query); + Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery( + query); if (null != nodeObj) { - NodeImplProxy proxy = new NodeImplProxy(nodeObj); + NodeImplProxy proxy = new NodeImplProxy(nodeObj); addToCache(new NodeCache(proxy)); return true; } @@ -313,14 +339,17 @@ } /** - * @see org.apache.jetspeed.prefs.PreferencesProvider#createNode(org.apache.jetspeed.prefs.om.Node, java.lang.String, int, java.lang.String) + * @see org.apache.jetspeed.prefs.PreferencesProvider#createNode(org.apache.jetspeed.prefs.om.Node, + * java.lang.String, int, java.lang.String) */ - public Node createNode(Node parent, String nodeName, int nodeType, String fullPath) - throws FailedToCreateNodeException, NodeAlreadyExistsException + public Node createNode(Node parent, String nodeName, int nodeType, + String fullPath) throws FailedToCreateNodeException, + NodeAlreadyExistsException { if (nodeExists(fullPath, nodeType)) { - throw new NodeAlreadyExistsException("Node of type " + nodeType + " already exists at path " + fullPath); + throw new NodeAlreadyExistsException("Node of type " + nodeType + + " already exists at path " + fullPath); } else { @@ -330,68 +359,68 @@ parentNodeId = new Long(parent.getNodeId()); } - Node nodeObj = new NodeImpl(parentNodeId, nodeName, nodeType, fullPath); + Node nodeObj = new NodeImpl(parentNodeId, nodeName, nodeType, + fullPath); try { getPersistenceBrokerTemplate().store(nodeObj); - NodeImplProxy proxy = new NodeImplProxy(nodeObj); + NodeImplProxy proxy = new NodeImplProxy(nodeObj); addToCache(new NodeCache(proxy)); return proxy; } catch (Exception e) { - throw new FailedToCreateNodeException("Failed to create node of type " + nodeType + " for the path " - + fullPath + ". " + e.toString(), e); + throw new FailedToCreateNodeException( + "Failed to create node of type " + nodeType + + " for the path " + fullPath + ". " + + e.toString(), e); } } } - + /** * @see org.apache.jetspeed.prefs.PreferencesProvider#getChildren(org.apache.jetspeed.prefs.om.Node) */ public Collection getChildren(Node parentNode) { - NodeCache key = new NodeCache(parentNode.getFullPath(), parentNode.getNodeType()); + NodeCache key = new NodeCache(parentNode.getFullPath(), parentNode + .getNodeType()); NodeCache hit = getNode(key.getCacheKey()); if (hit == null) { - NodeImplProxy proxy = new NodeImplProxy(parentNode); + NodeImplProxy proxy = new NodeImplProxy(parentNode); hit = new NodeCache(proxy); addToCache(hit); } - if (hit.isChildrenLoaded()) - { - return resolveChildren(hit.getChildren()); - } + if (hit.isChildrenLoaded()) { return resolveChildren(hit.getChildren()); } Criteria c = new Criteria(); c.addEqualTo("parentNodeId", new Long(parentNode.getNodeId())); Query query = QueryFactory.newQuery(NodeImpl.class, c); - Collection children = getPersistenceBrokerTemplate().getCollectionByQuery(query); + Collection children = getPersistenceBrokerTemplate() + .getCollectionByQuery(query); hit.setChildren(cacheChildren(children)); // null or not return children; } - private Collection resolveChildren(Collection children) { - if (children == null) - return null; - try - { - Iterator it = children.iterator(); - Vector v = new Vector(); - while (it.hasNext()) - { - String s = (String) it.next(); - NodeCache hit = getNode(s); - if (hit != null) + if (children == null) return null; + try + { + Iterator it = children.iterator(); + Vector v = new Vector(); + while (it.hasNext()) + { + String s = (String) it.next(); + NodeCache hit = getNode(s); + if (hit != null) { - v.add(hit.getNode()); + v.add(hit.getNode()); } else { @@ -407,36 +436,36 @@ } } } - } - return v; - } - catch (Exception e) - { - e.printStackTrace(); - return null; - } + } + return v; + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } } - private Collection cacheChildren(Collection children) { - Iterator it = children.iterator(); - Vector v = new Vector(); - while (it.hasNext()) - { - Node key = (Node)it.next(); - NodeCache nodeKey = new NodeCache(key.getFullPath(),key.getNodeType()); - NodeCache hit = getNode(nodeKey.getCacheKey()); - if (hit == null) - { - NodeImplProxy proxy = new NodeImplProxy(key); - nodeKey.setNode(proxy); - addToCache(nodeKey); - hit= nodeKey; - } - v.add(hit.getCacheKey()); - } - return v; + Iterator it = children.iterator(); + Vector v = new Vector(); + while (it.hasNext()) + { + Node key = (Node) it.next(); + NodeCache nodeKey = new NodeCache(key.getFullPath(), key + .getNodeType()); + NodeCache hit = getNode(nodeKey.getCacheKey()); + if (hit == null) + { + NodeImplProxy proxy = new NodeImplProxy(key); + nodeKey.setNode(proxy); + addToCache(nodeKey); + hit = nodeKey; + } + v.add(hit.getCacheKey()); + } + return v; } /** @@ -444,74 +473,91 @@ */ public void storeNode(Node node) { - NodeImplProxy hit = null; - if (node instanceof NodeImplProxy) - { - hit = (NodeImplProxy)node; - } - else - { - //System.out.println("WARNING!!!!STORE NODE!!!!!!!!!!!! - Illegal Node element passed"); - hit = new NodeImplProxy(node); - } - + NodeImplProxy hit = null; + if (node instanceof NodeImplProxy) + { + hit = (NodeImplProxy) node; + } + else + { + // System.out.println("WARNING!!!!STORE NODE!!!!!!!!!!!! - Illegal + // Node element passed"); + hit = new NodeImplProxy(node); + } + NodeCache key = new NodeCache(hit); - getPersistenceBrokerTemplate().store(hit.getNode()); // avoid racing condition with the db and with cluster notification - // do the db first - preferenceCache.remove(key.getCacheKey()); // not sure we should actually do that, could also just update the node + getPersistenceBrokerTemplate().store(hit.getNode()); // avoid racing + // condition + // with the db + // and with + // cluster + // notification + // do the db first + preferenceCache.remove(key.getCacheKey()); // not sure we should + // actually do that, could + // also just update the node addToCache(key); } /** - * @see org.apache.jetspeed.prefs.PreferencesProvider#removeNode(org.apache.jetspeed.prefs.om.Node, org.apache.jetspeed.prefs.om.Node) + * @see org.apache.jetspeed.prefs.PreferencesProvider#removeNode(org.apache.jetspeed.prefs.om.Node, + * org.apache.jetspeed.prefs.om.Node) */ public void removeNode(Node parentNode, Node node) { - NodeImplProxy hit = null; - NodeImplProxy parentHit = null; + NodeImplProxy hit = null; + NodeImplProxy parentHit = null; - if (node instanceof NodeImplProxy) - { - getPersistenceBrokerTemplate().delete(((NodeImplProxy)node).getNode()); //avoid race conditions - do this first - } - else - getPersistenceBrokerTemplate().delete(node); //avoid race conditions - do this first - - if (node instanceof NodeImplProxy) - { - hit = (NodeImplProxy)node; - } - else - { - //System.out.println("WARNING!!!!REMOVE NODE!!!!!!!!!!!! - Illegal Node element passed"); - hit = new NodeImplProxy(node); - } + if (node instanceof NodeImplProxy) + { + getPersistenceBrokerTemplate().delete( + ((NodeImplProxy) node).getNode()); // avoid race conditions + // - do this first + } + else + getPersistenceBrokerTemplate().delete(node); // avoid race + // conditions - do + // this first + + if (node instanceof NodeImplProxy) + { + hit = (NodeImplProxy) node; + } + else + { + // System.out.println("WARNING!!!!REMOVE NODE!!!!!!!!!!!! - Illegal + // Node element passed"); + hit = new NodeImplProxy(node); + } NodeCache key = new NodeCache(hit); preferenceCache.remove(key.getCacheKey()); - if ( parentNode != null ) + if (parentNode != null) { - if (parentNode instanceof NodeImplProxy) - { - parentHit = (NodeImplProxy)parentNode; - } - else - { - //System.out.println("WARNING!!!!REMOVE NODE!!!!!!!!!!!! - Illegal Node element passed"); - parentHit = new NodeImplProxy(parentNode); - } - NodeCache parentKey = new NodeCache(parentHit); - parentKey = getNode(parentKey.getCacheKey()); - if ( parentKey != null && parentKey.isChildrenLoaded() ) + if (parentNode instanceof NodeImplProxy) { - parentKey.getChildren().remove(key.getCacheKey()); + parentHit = (NodeImplProxy) parentNode; } + else + { + // System.out.println("WARNING!!!!REMOVE NODE!!!!!!!!!!!! - + // Illegal Node element passed"); + parentHit = new NodeImplProxy(parentNode); + } + NodeCache parentKey = new NodeCache(parentHit); + parentKey = getNode(parentKey.getCacheKey()); + if (parentKey != null && parentKey.isChildrenLoaded()) + { + parentKey.getChildren().remove(key.getCacheKey()); + } } } - + /** - * @see org.apache.jetspeed.prefs.PreferencesProvider#lookupPreference(java.lang.String, java.lang.String, java.lang.String) + * @see org.apache.jetspeed.prefs.PreferencesProvider#lookupPreference(java.lang.String, + * java.lang.String, java.lang.String) */ - public Collection lookupPreference(String nodeName, String propertyName, String propertyValue) + public Collection lookupPreference(String nodeName, String propertyName, + String propertyValue) { Criteria c = new Criteria(); if (nodeName != null) @@ -527,28 +573,30 @@ c.addEqualTo("nodeProperties.propertyValue", propertyValue); } Query query = QueryFactory.newQuery(NodeImpl.class, c); - Collection children = getPersistenceBrokerTemplate().getCollectionByQuery(query); + Collection children = getPersistenceBrokerTemplate() + .getCollectionByQuery(query); Collection proxied = new ArrayList(); Iterator iter = children.iterator(); while (iter.hasNext()) { - NodeImpl node = (NodeImpl)iter.next(); - NodeCache key = new NodeCache(node.getFullPath(), node.getNodeType()); + NodeImpl node = (NodeImpl) iter.next(); + NodeCache key = new NodeCache(node.getFullPath(), node + .getNodeType()); NodeCache hit = getNode(key.getCacheKey()); if (hit == null) { NodeImplProxy proxy = new NodeImplProxy(node); addToCache(new NodeCache(proxy)); proxied.add(proxy); - } + } else { proxied.add(hit.getNode()); } } - return proxied; + return proxied; } - + public Property createProperty(Node node, String name, Object value) { return new PropertyImpl(node.getNodeId(), name, value); @@ -560,49 +608,51 @@ Iterator apps = this.preloadedApplications.iterator(); while (apps.hasNext()) { - String appName = (String)apps.next(); + String appName = (String) apps.next(); preloadApplicationPreferences(appName); } - if (preloadEntities) - preloadAllEntities(); + if (preloadEntities) preloadAllEntities(); } - - public void preloadApplicationPreferences(String portletApplicationName) throws NodeDoesNotExistException + + public void preloadApplicationPreferences(String portletApplicationName) + throws NodeDoesNotExistException { - String portletDefPrefPath = "/" + MutablePortletApplication.PREFS_ROOT + "/" + portletApplicationName + "/"; -// + PortletDefinitionComposite.PORTLETS_PREFS_ROOT + "/" + portlet.getName() + "/" -// + MutablePortletApplication.PORTLET_PREFERENCES_ROOT; -// NodeCache key = new NodeCache(portletDefPrefPath, 1); -// NodeCache hit = getNode(key.getCacheKey()); -// if (hit != null) -// { -// return 1; -// //return hit.getNode(); -// } - long start = System.currentTimeMillis(); + String portletDefPrefPath = "/" + MutablePortletApplication.PREFS_ROOT + + "/" + portletApplicationName + "/"; + // + PortletDefinitionComposite.PORTLETS_PREFS_ROOT + "/" + + // portlet.getName() + "/" + // + MutablePortletApplication.PORTLET_PREFERENCES_ROOT; + // NodeCache key = new NodeCache(portletDefPrefPath, 1); + // NodeCache hit = getNode(key.getCacheKey()); + // if (hit != null) + // { + // return 1; + // //return hit.getNode(); + // } + long start = System.currentTimeMillis(); int count = loadNodeAndAllChildren(portletDefPrefPath); long elapsed = System.currentTimeMillis() - start; - System.out.println("++++ PREFS:PA loaded " + count + " pref nodes for app " + portletDefPrefPath + " in " + elapsed + " milliseconds."); + System.out.println("++++ PREFS:PA loaded " + count + + " pref nodes for app " + portletDefPrefPath + " in " + + elapsed + " milliseconds."); } - + protected int loadNodeAndAllChildren(String path) { int count = 0; NodeCache root = null; Criteria c = new Criteria(); c.addLike("fullPath", path + "%"); - //c.addOrderBy("fullPath"); + // c.addOrderBy("fullPath"); Query query = QueryFactory.newQuery(NodeImpl.class, c); - Collection result = getPersistenceBrokerTemplate().getCollectionByQuery(query); + Collection result = getPersistenceBrokerTemplate() + .getCollectionByQuery(query); // TODO: ensure that we always get the first node back first - if (result == null || result.isEmpty()) - { - return count; - } + if (result == null || result.isEmpty()) { return count; } Iterator ri = result.iterator(); if (ri.hasNext()) { - Node n = (Node)ri.next(); + Node n = (Node) ri.next(); NodeImplProxy proxy = new NodeImplProxy(n); root = new NodeCache(proxy); addToCache(root); @@ -610,17 +660,18 @@ } else { - return count; + return count; } Map parents = new HashMap(); parents.put(new Long(root.getNode().getNodeId()), root); while (ri.hasNext()) { // build children and subchildren - Node subNode = (Node)ri.next(); - //System.out.println("*** Preloading: " + subNode.getFullPath()); + Node subNode = (Node) ri.next(); + // System.out.println("*** Preloading: " + subNode.getFullPath()); // add to current node - NodeCache nodeKey = new NodeCache(subNode.getFullPath(), subNode.getNodeType()); + NodeCache nodeKey = new NodeCache(subNode.getFullPath(), subNode + .getNodeType()); NodeCache lookup = getNode(nodeKey.getCacheKey()); if (lookup == null) { @@ -629,7 +680,8 @@ addToCache(nodeKey); lookup = nodeKey; } - NodeCache parent = (NodeCache)parents.get(subNode.getParentNodeId()); + NodeCache parent = (NodeCache) parents.get(subNode + .getParentNodeId()); if (parent != null) { if (parent.getChildren() == null) @@ -639,17 +691,19 @@ } parents.put(new Long(subNode.getNodeId()), lookup); count++; - } + } return count; } - + public void preloadAllEntities() throws NodeDoesNotExistException { - String entitiesRoot = "/" + MutablePortletEntity.PORTLET_ENTITY_ROOT + "/"; - long start = System.currentTimeMillis(); + String entitiesRoot = "/" + MutablePortletEntity.PORTLET_ENTITY_ROOT + + "/"; + long start = System.currentTimeMillis(); int count = loadNodeAndAllChildren(entitiesRoot); long elapsed = System.currentTimeMillis() - start; - System.out.println("++++ PREFS:ENTITIES loaded " + count + " total entity pref nodes in " + elapsed + " milliseconds."); + System.out.println("++++ PREFS:ENTITIES loaded " + count + + " total entity pref nodes in " + elapsed + " milliseconds."); } - + } \ No newline at end of file Modified: pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java =================================================================== --- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java 2008-05-15 13:51:07 UTC (rev 936) +++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java 2008-05-15 13:53:50 UTC (rev 937) @@ -16,35 +16,64 @@ */ package org.apache.jetspeed.prefs.impl; +import java.util.Observer; import java.util.prefs.Preferences; import java.util.prefs.PreferencesFactory; import org.apache.jetspeed.prefs.PreferencesException; import org.apache.jetspeed.prefs.PreferencesProvider; +import org.apache.jetspeed.util.PreferencesRootWrapper; /** - * <p>{@link java.util.prefs.PreferencesFactory} implementation to - * return {@link PreferencesImpl}.</p> - * + * <p> + * {@link java.util.prefs.PreferencesFactory} implementation to return + * {@link PreferencesImpl}. + * </p> + * * @author <a href="mailto:dlest****@apach*****">David Le Strat</a> + * @author <a href="mailto:ate****@douma*****">Ate Douma</a> + * @version $Id$ */ public class PreferencesFactoryImpl implements PreferencesFactory { - - protected static PreferencesProvider prefsProvider; + private Preferences userRootWrapper; + + private Preferences systemRootWrapper; + + private PreferencesImpl userRoot; + + private PreferencesImpl systemRoot; + + private PreferencesProvider preferencesProvider; + + /** + * Java Preferences invoked constructor + */ public PreferencesFactoryImpl() { - super(); - System.setProperty("java.util.prefs.PreferencesFactory", getClass().getName()); - } + userRootWrapper = new PreferencesRootWrapper(); + systemRootWrapper = new PreferencesRootWrapper(); + } /** + * Spring invoked constructor with a dummy parameter to distinguish it from + * the default constructor invoked by the Java Preferences + * + * @param dummy + */ + public PreferencesFactoryImpl(int dummy) + { + System.setProperty("java.util.prefs.PreferencesFactory", getClass() + .getName()); + } + + /** * @see java.util.prefs.PreferencesFactory#systemRoot() */ public Preferences systemRoot() { - return PreferencesImpl.systemRoot; + return systemRootWrapper; } /** @@ -52,9 +81,9 @@ */ public Preferences userRoot() { - return PreferencesImpl.userRoot; + return userRootWrapper; } - + /** * <p> * Initializes the factory. @@ -63,37 +92,52 @@ * @throws Exception */ public void init() throws Exception - { + { try - { - PreferencesImpl.setPreferencesProvider(prefsProvider); - PreferencesImpl.systemRoot = new PreferencesImpl(null, "", PreferencesImpl.SYSTEM_NODE_TYPE); - PreferencesImpl.userRoot = new PreferencesImpl(null, "", PreferencesImpl.USER_NODE_TYPE); + { + // Wrap the PreferencesProvider to provide a single instance to be + // stored in the Preferences nodes + // which can be disposed at once for all + PreferencesProviderWrapper ppw = new PreferencesProviderWrapper( + preferencesProvider); + preferencesProvider = null; + userRoot = new PreferencesImpl(null, ppw, "", + PreferencesImpl.USER_NODE_TYPE); + systemRoot = new PreferencesImpl(null, ppw, "", + PreferencesImpl.SYSTEM_NODE_TYPE); + // set/update the Java Preferences userRoot and systeRoot + // PreferencesRootWrapper instances + ((Observer) Preferences.userRoot()).update(null, userRoot); + ((Observer) Preferences.systemRoot()).update(null, systemRoot); } - catch(Throwable e) + catch (Throwable e) { - e.printStackTrace(); - throw new PreferencesException("Failed to initialize prefs api. "+e.toString()); + throw new PreferencesException("Failed to initialize prefs api. " + + e.getMessage(), e); } } - - /** - * @return The {@link PreferencesProvider} - */ - public PreferencesProvider getPrefsProvider() + + public void dispose() { - return prefsProvider; + ((Observer) Preferences.userRoot()).update(null, null); + ((Observer) Preferences.systemRoot()).update(null, null); + userRoot.disposeNode(); + systemRoot.disposeNode(); + userRoot.ppw.dispose(); + userRoot = null; + systemRoot = null; } - + /** * <p> * Set the preferences provider. * </p> * - * @param prefsProvider The {@link PreferencesProvider} + * @param preferencesProvider + * The {@link PreferencesProvider} */ - public void setPrefsProvider(PreferencesProvider prefsProvider) + public void setPrefsProvider(PreferencesProvider preferencesProvider) { - PreferencesFactoryImpl.prefsProvider = prefsProvider; + this.preferencesProvider = preferencesProvider; } } Modified: pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java =================================================================== --- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java 2008-05-15 13:51:07 UTC (rev 936) +++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java 2008-05-15 13:53:50 UTC (rev 937) @@ -29,7 +29,6 @@ import org.apache.jetspeed.prefs.FailedToCreateNodeException; import org.apache.jetspeed.prefs.NodeAlreadyExistsException; import org.apache.jetspeed.prefs.NodeDoesNotExistException; -import org.apache.jetspeed.prefs.PreferencesProvider; import org.apache.jetspeed.prefs.om.Node; import org.apache.jetspeed.prefs.om.Property; import org.apache.jetspeed.prefs.om.impl.PropertyImpl; @@ -41,6 +40,8 @@ * </p> * * @author <a href="mailto:dlest****@apach*****">David Le Strat </a> + * @author <a href="mailto:ate****@douma*****">Ate Douma</a> + * @version $Id$ */ public class PreferencesImpl extends AbstractPreferences { @@ -57,12 +58,13 @@ /** Logger. */ private static final Log log = LogFactory.getLog(PreferencesImpl.class); - protected static PreferencesProvider prefsProvider; + protected PreferencesProviderWrapper ppw; - static PreferencesImpl systemRoot; + void disposeNode() + { + node = null; + } - static PreferencesImpl userRoot; - /** * <p> * Constructs a root node in the underlying datastore if they have not yet @@ -72,31 +74,39 @@ * Logs a warning if the underlying datastore is unavailable. * </p> * - * @param parent The parent object. - * @param nodeName The node name. - * @param nodeType The node type. + * @param parent + * The parent object. + * @param nodeName + * The node name. + * @param nodeType + * The node type. */ - public PreferencesImpl(PreferencesImpl parent, String nodeName, int nodeType) throws IllegalStateException + PreferencesImpl(PreferencesImpl parent, PreferencesProviderWrapper ppw, + String nodeName, int nodeType) throws IllegalStateException { super(parent, nodeName); try { + this.ppw = ppw; if (parent != null) { - this.node = prefsProvider.createNode(parent.getNode(), nodeName, nodeType, this.absolutePath()); + this.node = ppw.provider().createNode(parent.getNode(), + nodeName, nodeType, this.absolutePath()); } else { - this.node = prefsProvider.createNode(null, nodeName, nodeType, this.absolutePath()); + this.node = ppw.provider().createNode(null, nodeName, nodeType, + this.absolutePath()); } newNode = true; } catch (FailedToCreateNodeException e) { - IllegalStateException ise = new IllegalStateException("Failed to create new Preferences of type " - + nodeType + " for path " + this.absolutePath()); + IllegalStateException ise = new IllegalStateException( + "Failed to create new Preferences of type " + nodeType + + " for path " + this.absolutePath()); ise.initCause(e); throw ise; } @@ -104,7 +114,7 @@ { try { - node = prefsProvider.getNode(this.absolutePath(), nodeType); + node = ppw.provider().getNode(this.absolutePath(), nodeType); newNode = false; } catch (NodeDoesNotExistException e1) @@ -128,7 +138,7 @@ */ public String[] childrenNamesSpi() throws BackingStoreException { - Collection nodes = prefsProvider.getChildren(getNode()); + Collection nodes = ppw.provider().getChildren(getNode()); if (null != nodes) { @@ -153,7 +163,7 @@ */ public AbstractPreferences childSpi(String name) { - return new PreferencesImpl(this, name, node.getNodeType()); + return new PreferencesImpl(this, ppw, name, node.getNodeType()); } /** @@ -161,7 +171,7 @@ */ public void flushSpi() throws BackingStoreException { - prefsProvider.storeNode(this.node); + ppw.provider().storeNode(this.node); } /** @@ -171,14 +181,19 @@ { String value = null; // Collection properties = node.getNodeProperties(); - // BEGIN + // TODO review below + // BEGIN Node targetNode = null; - try { - targetNode = prefsProvider.getNode(node.getFullPath(), node - .getNodeType()); - } catch (NodeDoesNotExistException e) { + try + { + targetNode = ppw.provider().getNode(node.getFullPath(), + node.getNodeType()); } - if (targetNode == null) { + catch (NodeDoesNotExistException e) + { + } + if (targetNode == null) + { targetNode = node; } Collection properties = targetNode.getNodeProperties(); @@ -187,7 +202,8 @@ for (Iterator i = properties.iterator(); i.hasNext();) { Property curProp = (Property) i.next(); - if ((null != curProp) && (null != curProp.getPropertyName()) && (curProp.getPropertyName().equals(key))) + if ((null != curProp) && (null != curProp.getPropertyName()) + && (curProp.getPropertyName().equals(key))) { value = curProp.getPropertyValue(); } @@ -216,7 +232,8 @@ } } - return (String[]) propertyNames.toArray(new String[propertyNames.size()]); + return (String[]) propertyNames + .toArray(new String[propertyNames.size()]); } /** @@ -228,7 +245,8 @@ Collection properties = node.getNodeProperties(); if (null == properties) { - log.error("Could not retrieve node property: [key: " + key + ", value:" + value + "]"); + log.error("Could not retrieve node property: [key: " + key + + ", value:" + value + "]"); return; } @@ -237,14 +255,18 @@ for (Iterator i = properties.iterator(); i.hasNext();) { Property curProp = (Property) i.next(); - if ((null != curProp) && (null != curProp.getPropertyName()) && curProp.getPropertyName().equals(key)) + if ((null != curProp) && (null != curProp.getPropertyName()) + && curProp.getPropertyName().equals(key)) { propFound = true; curProp.setPropertyValue(value); - curProp.setModifiedDate(new Timestamp(System.currentTimeMillis())); + curProp.setModifiedDate(new Timestamp(System + .currentTimeMillis())); if (log.isDebugEnabled()) { - log.debug("Update existing property: " + curProp.toString()); + log + .debug("Update existing property: " + + curProp.toString()); } // Property found, we break. break; @@ -255,7 +277,7 @@ properties.add(new PropertyImpl(node.getNodeId(), key, value)); } - prefsProvider.storeNode(node); + ppw.provider().storeNode(node); } /** @@ -269,7 +291,7 @@ { parentNode = ((PreferencesImpl) parent).getNode(); } - prefsProvider.removeNode(parentNode, node); + ppw.provider().removeNode(parentNode, node); } /** @@ -289,7 +311,7 @@ } } // Update node. - prefsProvider.storeNode(node); + ppw.provider().storeNode(node); } /** @@ -312,20 +334,4 @@ { return node; } - - /** - * - * <p> - * setPreferencesProvider - * </p> - * Sets the <code>org.apache.jetspeed.prefs.PreferencesProvider</code> - * that will support backing store operations for all - * <code>PreferencesImpls</code> - * - * @param prefsProvider - */ - public static void setPreferencesProvider(PreferencesProvider prefsProvider) - { - PreferencesImpl.prefsProvider = prefsProvider; - } } Added: pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesProviderWrapper.java =================================================================== --- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesProviderWrapper.java (rev 0) +++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesProviderWrapper.java 2008-05-15 13:53:50 UTC (rev 937) @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jetspeed.prefs.impl; + +import org.apache.jetspeed.prefs.PreferencesProvider; + +/** + * @author <a href="mailto:ate****@douma*****">Ate Douma</a> + * @version $Id$ + */ +public class PreferencesProviderWrapper +{ + + PreferencesProvider provider; + + PreferencesProviderWrapper(PreferencesProvider provider) + { + this.provider = provider; + } + + PreferencesProvider provider() + { + return provider; + } + + void dispose() + { + provider = null; + } +} Property changes on: pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesProviderWrapper.java ___________________________________________________________________ Name: svn:eol-style + native Modified: pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/src/webapp/WEB-INF/assembly/prefs.xml =================================================================== --- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/src/webapp/WEB-INF/assembly/prefs.xml 2008-05-15 13:51:07 UTC (rev 936) +++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/src/webapp/WEB-INF/assembly/prefs.xml 2008-05-15 13:53:50 UTC (rev 937) @@ -19,7 +19,7 @@ <beans> <!-- Preferences Implementation --> - <bean id="PreferencesProviderImpl" class="org.apache.jetspeed.prefs.impl.PersistenceBrokerPreferencesProvider" name="prefsPersistenceBroker" init-method="init"> + <bean id="PreferencesProviderImpl" class="org.apache.jetspeed.prefs.impl.PersistenceBrokerPreferencesProvider" name="prefsPersistenceBroker" init-method="init" destroy-method="destroy"> <constructor-arg index="0"> <value>JETSPEED-INF/ojb/prefs_repository.xml</value> </constructor-arg> @@ -36,7 +36,7 @@ <constructor-arg index='3'><value type="boolean">false</value></constructor-arg> </bean> - <bean id="org.apache.jetspeed.prefs.PreferencesProvider" parent="baseTransactionProxy" name="prefsProvider"> + <bean id="org.apache.jetspeed.prefs.PreferencesProvider" parent="baseTransactionProxy" name="prefsProvider" destroy-method="destroy"> <property name="proxyInterfaces"> <value>org.apache.jetspeed.prefs.PreferencesProvider</value> </property> @@ -55,7 +55,9 @@ </bean> <!-- PreferencesFactory implementation --> - <bean id="java.util.prefs.PreferencesFactory" class="org.apache.jetspeed.prefs.impl.PreferencesFactoryImpl" name="prefsFactory" init-method="init"> + <bean id="java.util.prefs.PreferencesFactory" class="org.apache.jetspeed.prefs.impl.PreferencesFactoryImpl" name="prefsFactory" init-method="init" destroy-method="destroy"> + <!-- dummy constructor argument to distinguish it from the default constructor invoked by the Java Preferences itself --> + <constructor-arg><value>1</value></constructor-arg> <property name="prefsProvider"> <ref bean="prefsProvider" /> </property>