• R/O
  • SSH
  • HTTPS

pal: Commit


Commit MetaInfo

Revision1788 (tree)
Zeit2009-03-04 14:38:03
Autorsone

Log Message

applied patch 'r740489: Backport of preferences fix'

Ändern Zusammenfassung

Diff

--- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java (revision 1787)
+++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java (revision 1788)
@@ -30,7 +30,6 @@
3030 import org.apache.jetspeed.prefs.FailedToCreateNodeException;
3131 import org.apache.jetspeed.prefs.NodeAlreadyExistsException;
3232 import org.apache.jetspeed.prefs.NodeDoesNotExistException;
33-import org.apache.jetspeed.prefs.PreferencesProvider;
3433 import org.apache.jetspeed.prefs.om.Node;
3534 import org.apache.jetspeed.prefs.om.Property;
3635 import org.apache.jetspeed.prefs.om.impl.PropertyImpl;
@@ -42,6 +41,7 @@
4241 * </p>
4342 *
4443 * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
44+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
4545 */
4646 public class PreferencesImpl extends AbstractPreferences
4747 {
@@ -58,13 +58,13 @@
5858 /** Logger. */
5959 private static final Log log = LogFactory.getLog(PreferencesImpl.class);
6060
61- // TODO Findbugs
62- protected static PreferencesProvider prefsProvider;
61+ PreferencesProviderWrapper ppw;
6362
64- static PreferencesImpl systemRoot;
63+ void disposeNode()
64+ {
65+ node = null;
66+ }
6567
66- static PreferencesImpl userRoot;
67-
6868 /**
6969 * <p>
7070 * Constructs a root node in the underlying datastore if they have not yet
@@ -81,13 +81,14 @@
8181 * @param nodeType
8282 * The node type.
8383 */
84- public PreferencesImpl(PreferencesImpl parent, String nodeName, int nodeType)
85- throws IllegalStateException
84+ PreferencesImpl(PreferencesImpl parent, PreferencesProviderWrapper ppw,
85+ String nodeName, int nodeType) throws IllegalStateException
8686 {
8787 super(parent, nodeName);
88+ this.ppw = ppw;
8889 try
8990 {
90- node = prefsProvider.getNode(this.absolutePath(), nodeType);
91+ node = ppw.provider().getNode(this.absolutePath(), nodeType);
9192 newNode = false;
9293 }
9394 catch (NodeDoesNotExistException e1)
@@ -96,12 +97,12 @@
9697 {
9798 if (parent != null)
9899 {
99- this.node = prefsProvider.createNode(parent.getNode(),
100+ this.node = ppw.provider().createNode(parent.getNode(),
100101 nodeName, nodeType, this.absolutePath());
101102 }
102103 else
103104 {
104- this.node = prefsProvider.createNode(null, nodeName,
105+ this.node = ppw.provider().createNode(null, nodeName,
105106 nodeType, this.absolutePath());
106107 }
107108
@@ -119,7 +120,8 @@
119120 {
120121 try
121122 {
122- node = prefsProvider.getNode(this.absolutePath(), nodeType);
123+ node = ppw.provider()
124+ .getNode(this.absolutePath(), nodeType);
123125 newNode = false;
124126 }
125127 catch (NodeDoesNotExistException e2)
@@ -143,7 +145,7 @@
143145 */
144146 public String[] childrenNamesSpi() throws BackingStoreException
145147 {
146- Collection nodes = prefsProvider.getChildren(getNode());
148+ Collection nodes = ppw.provider().getChildren(getNode());
147149
148150 if (null != nodes)
149151 {
@@ -168,7 +170,7 @@
168170 */
169171 public AbstractPreferences childSpi(String name)
170172 {
171- return new PreferencesImpl(this, name, node.getNodeType());
173+ return new PreferencesImpl(this, ppw, name, node.getNodeType());
172174 }
173175
174176 /**
@@ -176,7 +178,7 @@
176178 */
177179 public void flushSpi() throws BackingStoreException
178180 {
179- prefsProvider.storeNode(this.node);
181+ ppw.provider().storeNode(this.node);
180182 }
181183
182184 /**
@@ -190,8 +192,8 @@
190192 Node targetNode = null;
191193 try
192194 {
193- targetNode = prefsProvider.getNode(node.getFullPath(), node
194- .getNodeType());
195+ targetNode = ppw.provider().getNode(node.getFullPath(),
196+ node.getNodeType());
195197 }
196198 catch (NodeDoesNotExistException e)
197199 {
@@ -287,7 +289,7 @@
287289 properties.add(new PropertyImpl(node.getNodeId(), key, value));
288290 }
289291
290- prefsProvider.storeNode(node);
292+ ppw.provider().storeNode(node);
291293 }
292294
293295 /**
@@ -301,7 +303,7 @@
301303 {
302304 parentNode = ((PreferencesImpl) parent).getNode();
303305 }
304- prefsProvider.removeNode(parentNode, node);
306+ ppw.provider().removeNode(parentNode, node);
305307 }
306308
307309 /**
@@ -321,7 +323,7 @@
321323 }
322324 }
323325 // Update node.
324- prefsProvider.storeNode(node);
326+ ppw.provider().storeNode(node);
325327 }
326328
327329 /**
@@ -344,20 +346,4 @@
344346 {
345347 return node;
346348 }
347-
348- /**
349- *
350- * <p>
351- * setPreferencesProvider
352- * </p>
353- * Sets the <code>org.apache.jetspeed.prefs.PreferencesProvider</code>
354- * that will support backing store operations for all
355- * <code>PreferencesImpls</code>
356- *
357- * @param prefsProvider
358- */
359- public static void setPreferencesProvider(PreferencesProvider prefsProvider)
360- {
361- PreferencesImpl.prefsProvider = prefsProvider;
362- }
363349 }
--- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PersistenceBrokerPreferencesProvider.java (revision 1787)
+++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PersistenceBrokerPreferencesProvider.java (revision 1788)
@@ -714,4 +714,9 @@
714714 + " total entity pref nodes in " + elapsed + " milliseconds.");
715715 }
716716
717+ public void destroy()
718+ {
719+ NodeImplProxy.setProvider(null);
720+ preferenceCache = null;
721+ }
717722 }
\ No newline at end of file
--- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java (revision 1787)
+++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java (revision 1788)
@@ -16,6 +16,7 @@
1616 */
1717 package org.apache.jetspeed.prefs.impl;
1818
19+import java.util.Observer;
1920 import java.util.prefs.Preferences;
2021 import java.util.prefs.PreferencesFactory;
2122
@@ -24,6 +25,7 @@
2425
2526 import org.apache.jetspeed.prefs.PreferencesException;
2627 import org.apache.jetspeed.prefs.PreferencesProvider;
28+import org.apache.jetspeed.util.PreferencesRootWrapper;
2729
2830 /**
2931 * <p>
@@ -36,15 +38,35 @@
3638 public class PreferencesFactoryImpl implements PreferencesFactory
3739 {
3840
39- // TODO Findbugs
4041 protected static PreferencesProvider prefsProvider;
4142
43+ private Preferences userRootWrapper;
44+
45+ private Preferences systemRootWrapper;
46+
47+ private PreferencesImpl userRoot;
48+
49+ private PreferencesImpl systemRoot;
50+
51+ private PreferencesProvider preferencesProvider;
52+
4253 protected static final Log log = LogFactory
4354 .getLog(PreferencesFactoryImpl.class);
4455
4556 public PreferencesFactoryImpl()
4657 {
47- super();
58+ userRootWrapper = new PreferencesRootWrapper();
59+ systemRootWrapper = new PreferencesRootWrapper();
60+ }
61+
62+ /**
63+ * Spring invoked constructor with a dummy parameter to distinguish it from
64+ * the default constructor invoked by the Java Preferences
65+ *
66+ * @param dummy
67+ */
68+ public PreferencesFactoryImpl(int dummy)
69+ {
4870 System.setProperty("java.util.prefs.PreferencesFactory", getClass()
4971 .getName());
5072 }
@@ -54,7 +76,7 @@
5476 */
5577 public Preferences systemRoot()
5678 {
57- return PreferencesImpl.systemRoot;
79+ return systemRootWrapper;
5880 }
5981
6082 /**
@@ -62,7 +84,7 @@
6284 */
6385 public Preferences userRoot()
6486 {
65- return PreferencesImpl.userRoot;
87+ return userRootWrapper;
6688 }
6789
6890 /**
@@ -76,13 +98,18 @@
7698 {
7799 try
78100 {
79- PreferencesImpl.setPreferencesProvider(prefsProvider);
80- // TODO Findbugs
81- PreferencesImpl.systemRoot = new PreferencesImpl(null, "",
101+ // Wrap the PreferencesProvider to provide a single instance to be stored in the Preferences nodes
102+ // which can be disposed at once for all
103+ PreferencesProviderWrapper ppw = new PreferencesProviderWrapper(
104+ preferencesProvider);
105+ preferencesProvider = null;
106+ userRoot = new PreferencesImpl(null, ppw, "",
107+ PreferencesImpl.USER_NODE_TYPE);
108+ systemRoot = new PreferencesImpl(null, ppw, "",
82109 PreferencesImpl.SYSTEM_NODE_TYPE);
83- // TODO Findbugs
84- PreferencesImpl.userRoot = new PreferencesImpl(null, "",
85- PreferencesImpl.USER_NODE_TYPE);
110+ // set/update the Java Preferences userRoot and systeRoot PreferencesRootWrapper instances
111+ ((Observer) Preferences.userRoot()).update(null, userRoot);
112+ ((Observer) Preferences.systemRoot()).update(null, systemRoot);
86113 }
87114 catch (Throwable e)
88115 {
@@ -89,16 +116,19 @@
89116 //e.printStackTrace();
90117 log.log("1500002", e); // REPLACED
91118 throw new PreferencesException("Failed to initialize prefs api. "
92- + e.toString());
119+ + e.getMessage(), e);
93120 }
94121 }
95122
96- /**
97- * @return The {@link PreferencesProvider}
98- */
99- public PreferencesProvider getPrefsProvider()
123+ public void destroy()
100124 {
101- return prefsProvider;
125+ ((Observer) Preferences.userRoot()).update(null, null);
126+ ((Observer) Preferences.systemRoot()).update(null, null);
127+ userRoot.disposeNode();
128+ systemRoot.disposeNode();
129+ userRoot.ppw.dispose();
130+ userRoot = null;
131+ systemRoot = null;
102132 }
103133
104134 /**
@@ -106,12 +136,11 @@
106136 * Set the preferences provider.
107137 * </p>
108138 *
109- * @param prefsProvider
139+ * @param preferencesProvider
110140 * The {@link PreferencesProvider}
111141 */
112- public void setPrefsProvider(PreferencesProvider prefsProvider)
142+ public void setPrefsProvider(PreferencesProvider preferencesProvider)
113143 {
114- // TODO Findbugs
115- PreferencesFactoryImpl.prefsProvider = prefsProvider;
144+ this.preferencesProvider = preferencesProvider;
116145 }
117146 }
--- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesProviderWrapper.java (nonexistent)
+++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesProviderWrapper.java (revision 1788)
@@ -0,0 +1,44 @@
1+/*
2+ * Licensed to the Apache Software Foundation (ASF) under one or more
3+ * contributor license agreements. See the NOTICE file distributed with
4+ * this work for additional information regarding copyright ownership.
5+ * The ASF licenses this file to You under the Apache License, Version 2.0
6+ * (the "License"); you may not use this file except in compliance with
7+ * the License. You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ */
17+package org.apache.jetspeed.prefs.impl;
18+
19+import org.apache.jetspeed.prefs.PreferencesProvider;
20+
21+/**
22+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
23+ * @version $Id$
24+ */
25+public class PreferencesProviderWrapper
26+{
27+
28+ PreferencesProvider provider;
29+
30+ PreferencesProviderWrapper(PreferencesProvider provider)
31+ {
32+ this.provider = provider;
33+ }
34+
35+ PreferencesProvider provider()
36+ {
37+ return provider;
38+ }
39+
40+ void dispose()
41+ {
42+ provider = null;
43+ }
44+}
--- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/page-manager/project.xml (revision 1787)
+++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/components/page-manager/project.xml (revision 1788)
@@ -96,6 +96,7 @@
9696 <exclude>**/PageManagerTestShared.java</exclude>
9797 <exclude>**/DirectoryXMLTransform.java</exclude>
9898 <exclude>**/DatabasePageManagerServer.java</exclude>
99+ <exclude>**/TestTransactions.java</exclude>
99100 </excludes>
100101 <resources>
101102 <resource>
--- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/src/webapp/WEB-INF/assembly/prefs.xml (revision 1787)
+++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/src/webapp/WEB-INF/assembly/prefs.xml (revision 1788)
@@ -19,7 +19,7 @@
1919 <beans>
2020
2121 <!-- Preferences Implementation -->
22- <bean id="PreferencesProviderImpl" class="org.apache.jetspeed.prefs.impl.PersistenceBrokerPreferencesProvider" name="prefsPersistenceBroker" init-method="init">
22+ <bean id="PreferencesProviderImpl" class="org.apache.jetspeed.prefs.impl.PersistenceBrokerPreferencesProvider" name="prefsPersistenceBroker" init-method="init" destroy-method="destroy">
2323 <constructor-arg index="0">
2424 <value>JETSPEED-INF/ojb/prefs_repository.xml</value>
2525 </constructor-arg>
@@ -36,7 +36,7 @@
3636 <constructor-arg index='3'><value type="boolean">false</value></constructor-arg>
3737 </bean>
3838
39- <bean id="org.apache.jetspeed.prefs.PreferencesProvider" parent="baseTransactionProxy" name="prefsProvider">
39+ <bean id="org.apache.jetspeed.prefs.PreferencesProvider" parent="baseTransactionProxy" name="prefsProvider">
4040 <property name="proxyInterfaces">
4141 <value>org.apache.jetspeed.prefs.PreferencesProvider</value>
4242 </property>
@@ -55,7 +55,10 @@
5555 </bean>
5656
5757 <!-- PreferencesFactory implementation -->
58- <bean id="java.util.prefs.PreferencesFactory" class="org.apache.jetspeed.prefs.impl.PreferencesFactoryImpl" name="prefsFactory" init-method="init">
58+ <bean id="java.util.prefs.PreferencesFactory" class="org.apache.jetspeed.prefs.impl.PreferencesFactoryImpl"
59+ name="prefsFactory" init-method="init" destroy-method="destroy">
60+ <!-- dummy constructor argument to distinguish it from the default constructor invoked by the Java Preferences itself -->
61+ <constructor-arg><value>1</value></constructor-arg>
5962 <property name="prefsProvider">
6063 <ref bean="prefsProvider" />
6164 </property>
--- pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/commons/src/java/org/apache/jetspeed/util/PreferencesRootWrapper.java (nonexistent)
+++ pal-portal/branches/pal-portal-1.x/portal/jetspeed-2/commons/src/java/org/apache/jetspeed/util/PreferencesRootWrapper.java (revision 1788)
@@ -0,0 +1,237 @@
1+/*
2+ * Licensed to the Apache Software Foundation (ASF) under one or more
3+ * contributor license agreements. See the NOTICE file distributed with
4+ * this work for additional information regarding copyright ownership.
5+ * The ASF licenses this file to You under the Apache License, Version 2.0
6+ * (the "License"); you may not use this file except in compliance with
7+ * the License. You may obtain a copy of the License at
8+ *
9+ * http://www.apache.org/licenses/LICENSE-2.0
10+ *
11+ * Unless required by applicable law or agreed to in writing, software
12+ * distributed under the License is distributed on an "AS IS" BASIS,
13+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+ * See the License for the specific language governing permissions and
15+ * limitations under the License.
16+ */
17+package org.apache.jetspeed.util;
18+
19+import java.io.IOException;
20+import java.io.OutputStream;
21+import java.util.Observable;
22+import java.util.Observer;
23+import java.util.prefs.BackingStoreException;
24+import java.util.prefs.NodeChangeListener;
25+import java.util.prefs.PreferenceChangeListener;
26+import java.util.prefs.Preferences;
27+
28+/**
29+ * PreferencesRootWrapper is a lightweight wrapper around the Jetspeed persistent PreferencesImpl to allow
30+ * restarting the Jetspeed Portal.
31+ * <p>
32+ * As the (Sun) Java Preferences implementation only creates a PreferencesFactory instance *once* per JVM
33+ * (as static final), reloading the Jetspeed Portal (using a new classloader) requires a wrapper solution
34+ * to prevent ClassCastExceptions and/or out-of-sync kept proxies and caches.
35+ * </p>
36+ * <p>
37+ * As a newly created Jetspeed Portal classloader can no longer cast a previous Preferences root to its
38+ * own PreferencesImpl, a "trick" is used by also implementing the Observer interface (which is provided by
39+ * the Java system classloader). The Observer interface is used because it is very lightweight and allows
40+ * passing an Object instance through its update method. That update method is used to "inject" the newly
41+ * created Preferences root instance.
42+ * </p>
43+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
44+ * @version $Id$
45+ */
46+public class PreferencesRootWrapper extends Preferences implements Observer
47+{
48+
49+ private Preferences root;
50+
51+ public String absolutePath()
52+ {
53+ return root.absolutePath();
54+ }
55+
56+ public void addNodeChangeListener(NodeChangeListener ncl)
57+ {
58+ root.addNodeChangeListener(ncl);
59+ }
60+
61+ public void addPreferenceChangeListener(PreferenceChangeListener pcl)
62+ {
63+ root.addPreferenceChangeListener(pcl);
64+ }
65+
66+ public String[] childrenNames() throws BackingStoreException
67+ {
68+ return root.childrenNames();
69+ }
70+
71+ public void clear() throws BackingStoreException
72+ {
73+ root.clear();
74+ }
75+
76+ public boolean equals(Object obj)
77+ {
78+ return root.equals(obj);
79+ }
80+
81+ public void exportNode(OutputStream os) throws IOException,
82+ BackingStoreException
83+ {
84+ root.exportNode(os);
85+ }
86+
87+ public void exportSubtree(OutputStream os) throws IOException,
88+ BackingStoreException
89+ {
90+ root.exportSubtree(os);
91+ }
92+
93+ public void flush() throws BackingStoreException
94+ {
95+ root.flush();
96+ }
97+
98+ public String get(String key, String def)
99+ {
100+ return root.get(key, def);
101+ }
102+
103+ public boolean getBoolean(String key, boolean def)
104+ {
105+ return root.getBoolean(key, def);
106+ }
107+
108+ public byte[] getByteArray(String key, byte[] def)
109+ {
110+ return root.getByteArray(key, def);
111+ }
112+
113+ public double getDouble(String key, double def)
114+ {
115+ return root.getDouble(key, def);
116+ }
117+
118+ public float getFloat(String key, float def)
119+ {
120+ return root.getFloat(key, def);
121+ }
122+
123+ public int getInt(String key, int def)
124+ {
125+ return root.getInt(key, def);
126+ }
127+
128+ public long getLong(String key, long def)
129+ {
130+ return root.getLong(key, def);
131+ }
132+
133+ public int hashCode()
134+ {
135+ return root.hashCode();
136+ }
137+
138+ public boolean isUserNode()
139+ {
140+ return root.isUserNode();
141+ }
142+
143+ public String[] keys() throws BackingStoreException
144+ {
145+ return root.keys();
146+ }
147+
148+ public String name()
149+ {
150+ return root.name();
151+ }
152+
153+ public Preferences node(String pathName)
154+ {
155+ return root.node(pathName);
156+ }
157+
158+ public boolean nodeExists(String pathName) throws BackingStoreException
159+ {
160+ return root.nodeExists(pathName);
161+ }
162+
163+ public Preferences parent()
164+ {
165+ return root.parent();
166+ }
167+
168+ public void put(String key, String value)
169+ {
170+ root.put(key, value);
171+ }
172+
173+ public void putBoolean(String key, boolean value)
174+ {
175+ root.putBoolean(key, value);
176+ }
177+
178+ public void putByteArray(String key, byte[] value)
179+ {
180+ root.putByteArray(key, value);
181+ }
182+
183+ public void putDouble(String key, double value)
184+ {
185+ root.putDouble(key, value);
186+ }
187+
188+ public void putFloat(String key, float value)
189+ {
190+ root.putFloat(key, value);
191+ }
192+
193+ public void putInt(String key, int value)
194+ {
195+ root.putInt(key, value);
196+ }
197+
198+ public void putLong(String key, long value)
199+ {
200+ root.putLong(key, value);
201+ }
202+
203+ public void remove(String key)
204+ {
205+ root.remove(key);
206+ }
207+
208+ public void removeNode() throws BackingStoreException
209+ {
210+ root.removeNode();
211+ }
212+
213+ public void removeNodeChangeListener(NodeChangeListener ncl)
214+ {
215+ root.removeNodeChangeListener(ncl);
216+ }
217+
218+ public void removePreferenceChangeListener(PreferenceChangeListener pcl)
219+ {
220+ root.removePreferenceChangeListener(pcl);
221+ }
222+
223+ public void sync() throws BackingStoreException
224+ {
225+ root.sync();
226+ }
227+
228+ public String toString()
229+ {
230+ return root.toString();
231+ }
232+
233+ public void update(Observable o, Object arg)
234+ {
235+ root = (Preferences) arg;
236+ }
237+}
Show on old repository browser