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.sql.Timestamp;
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Iterator;
23 import java.util.prefs.AbstractPreferences;
24 import java.util.prefs.BackingStoreException;
25 import java.util.prefs.Preferences;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.jetspeed.prefs.FailedToCreateNodeException;
30 import org.apache.jetspeed.prefs.NodeAlreadyExistsException;
31 import org.apache.jetspeed.prefs.NodeDoesNotExistException;
32 import org.apache.jetspeed.prefs.PreferencesProvider;
33 import org.apache.jetspeed.prefs.om.Node;
34 import org.apache.jetspeed.prefs.om.Property;
35 import org.apache.jetspeed.prefs.om.impl.PropertyImpl;
36
37 /***
38 * <p>
39 * S {@link Preferences}implementation relying on Jetspeed OJB based
40 * persistence plugin.
41 * </p>
42 *
43 * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
44 */
45 public class PreferencesImpl extends AbstractPreferences
46 {
47
48 /*** User <tt>Preferences<tt> node type. */
49 public static final int USER_NODE_TYPE = 0;
50
51 /*** System <tt>Preferences</tt> node type. */
52 public static final int SYSTEM_NODE_TYPE = 1;
53
54 /*** The current <code>Node</code> object. */
55 private Node node = null;
56
57 /*** Logger. */
58 private static final Log log = LogFactory.getLog(PreferencesImpl.class);
59
60 protected static PreferencesProvider prefsProvider;
61
62 static PreferencesImpl systemRoot;
63
64 static PreferencesImpl userRoot;
65
66 /***
67 * <p>
68 * Constructs a root node in the underlying datastore if they have not yet
69 * been created.
70 * </p>
71 * <p>
72 * Logs a warning if the underlying datastore is unavailable.
73 * </p>
74 *
75 * @param parent The parent object.
76 * @param nodeName The node name.
77 * @param nodeType The node type.
78 */
79 public PreferencesImpl(PreferencesImpl parent, String nodeName, int nodeType) throws IllegalStateException
80 {
81 super(parent, nodeName);
82
83 try
84 {
85 if (parent != null)
86 {
87 this.node = prefsProvider.createNode(parent.getNode(), nodeName, nodeType, this.absolutePath());
88 }
89 else
90 {
91 this.node = prefsProvider.createNode(null, nodeName, nodeType, this.absolutePath());
92 }
93
94 newNode = true;
95 }
96 catch (FailedToCreateNodeException e)
97 {
98 IllegalStateException ise = new IllegalStateException("Failed to create new Preferences of type "
99 + nodeType + " for path " + this.absolutePath());
100 ise.initCause(e);
101 throw ise;
102 }
103 catch (NodeAlreadyExistsException e)
104 {
105 try
106 {
107 node = prefsProvider.getNode(this.absolutePath(), nodeType);
108 newNode = false;
109 }
110 catch (NodeDoesNotExistException e1)
111 {
112
113 IllegalStateException ise = new IllegalStateException(
114 "Unable to create node for Preferences of type "
115 + nodeType
116 + " for path "
117 + this.absolutePath()
118 + ". If you see this exception at this, it more than likely means that the Preferences backing store is corrupt.");
119 ise.initCause(e1);
120 throw ise;
121 }
122 }
123
124 }
125
126 /***
127 * @see java.util.prefs.Preferences#childrenNamesSpi()
128 */
129 public String[] childrenNamesSpi() throws BackingStoreException
130 {
131 Collection nodes = prefsProvider.getChildren(getNode());
132
133 if (null != nodes)
134 {
135 ArrayList childrenNames = new ArrayList(nodes.size());
136 for (Iterator i = nodes.iterator(); i.hasNext();)
137 {
138 Node curnode = (Node) i.next();
139 childrenNames.add(curnode.getNodeName());
140 }
141 return (String[]) childrenNames.toArray(new String[0]);
142 }
143 else
144 {
145
146
147 return new String[0];
148 }
149 }
150
151 /***
152 * @see java.util.prefs.Preferences#childSpi(java.lang.String)
153 */
154 public AbstractPreferences childSpi(String name)
155 {
156 return new PreferencesImpl(this, name, node.getNodeType());
157 }
158
159 /***
160 * @see java.util.prefs.Preferences#flushSpi()
161 */
162 public void flushSpi() throws BackingStoreException
163 {
164 prefsProvider.storeNode(this.node);
165 }
166
167 /***
168 * @see java.util.prefs.Preferences#getSpi(java.lang.String)
169 */
170 public String getSpi(String key)
171 {
172 String value = null;
173 Collection properties = node.getNodeProperties();
174
175 for (Iterator i = properties.iterator(); i.hasNext();)
176 {
177 Property curProp = (Property) i.next();
178 if ((null != curProp) && (null != curProp.getPropertyName()) && (curProp.getPropertyName().equals(key)))
179 {
180 value = curProp.getPropertyValue();
181 }
182 }
183 return value;
184 }
185
186 /***
187 * @see java.util.prefs.Preferences#keysSpi()
188 */
189 public String[] keysSpi()
190 {
191 ArrayList propertyNames = new ArrayList();
192
193 Collection propCol = node.getNodeProperties();
194 if ((null != propCol) && propCol.size() > 0)
195 {
196 for (Iterator j = propCol.iterator(); j.hasNext();)
197 {
198 Property curprop = (Property) j.next();
199 if ((null != curprop) && (null != curprop.getPropertyName())
200 && !propertyNames.contains(curprop.getPropertyName()))
201 {
202 propertyNames.add(curprop.getPropertyName());
203 }
204 }
205 }
206
207 return (String[]) propertyNames.toArray(new String[propertyNames.size()]);
208 }
209
210 /***
211 * @see java.util.prefs.Preferences#putSpi(java.lang.String,
212 * java.lang.String)
213 */
214 public void putSpi(String key, String value)
215 {
216 Collection properties = node.getNodeProperties();
217 if (null == properties)
218 {
219 log.error("Could not retrieve node property: [key: " + key + ", value:" + value + "]");
220 return;
221 }
222
223
224 boolean propFound = false;
225 for (Iterator i = properties.iterator(); i.hasNext();)
226 {
227 Property curProp = (Property) i.next();
228 if ((null != curProp) && (null != curProp.getPropertyName()) && curProp.getPropertyName().equals(key))
229 {
230 propFound = true;
231 curProp.setPropertyValue(value);
232 curProp.setModifiedDate(new Timestamp(System.currentTimeMillis()));
233 if (log.isDebugEnabled())
234 {
235 log.debug("Update existing property: " + curProp.toString());
236 }
237
238 break;
239 }
240 }
241 if (!propFound)
242 {
243 properties.add(new PropertyImpl(node.getNodeId(), key, value));
244 }
245
246 prefsProvider.storeNode(node);
247 }
248
249 /***
250 * @see java.util.prefs.Preferences#removeNodeSpi()
251 */
252 public void removeNodeSpi() throws BackingStoreException
253 {
254 Node parentNode = null;
255 Preferences parent = parent();
256 if (parent != null && parent instanceof PreferencesImpl)
257 {
258 parentNode = ((PreferencesImpl) parent).getNode();
259 }
260 prefsProvider.removeNode(parentNode, node);
261 }
262
263 /***
264 * @see java.util.prefs.Preferences#removeSpi(java.lang.String)
265 */
266 public void removeSpi(String key)
267 {
268 Collection properties = node.getNodeProperties();
269
270 for (Iterator i = properties.iterator(); i.hasNext();)
271 {
272 Property curProp = (Property) i.next();
273
274 if ((curProp.getPropertyName().equals(key)))
275 {
276 i.remove();
277 }
278 }
279
280 prefsProvider.storeNode(node);
281 }
282
283 /***
284 * @see java.util.prefs.Preferences#syncSpi()
285 */
286 public void syncSpi() throws BackingStoreException
287 {
288 flushSpi();
289 }
290
291 /***
292 *
293 * <p>
294 * getNode
295 * </p>
296 *
297 * @return
298 */
299 public Node getNode()
300 {
301 return node;
302 }
303
304 /***
305 *
306 * <p>
307 * setPreferencesProvider
308 * </p>
309 * Sets the <code>org.apache.jetspeed.prefs.PreferencesProvider</code>
310 * that will support backing store operations for all
311 * <code>PreferencesImpls</code>
312 *
313 * @param prefsProvider
314 */
315 public static void setPreferencesProvider(PreferencesProvider prefsProvider)
316 {
317 PreferencesImpl.prefsProvider = prefsProvider;
318 }
319 }