View Javadoc

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.om.preference.impl;
18  
19  import java.util.Arrays;
20  import java.util.ConcurrentModificationException;
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Set;
25  import java.util.Vector;
26  import java.util.prefs.BackingStoreException;
27  import java.util.prefs.Preferences;
28  
29  import javax.portlet.PreferencesValidator;
30  
31  import org.apache.jetspeed.om.common.preference.PreferenceSetComposite;
32  import org.apache.jetspeed.om.common.preference.PreferencesValidatorFactory;
33  import org.apache.pluto.om.common.Preference;
34  
35  /***
36   * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
37   * 
38   *  
39   */
40  public class PrefsPreferenceSetImpl implements PreferenceSetComposite
41  {
42      protected Preferences prefsRootNode;
43      protected PreferenceSetComposite defaults;
44      protected PreferencesValidatorFactory validatorFactory;
45  
46      /***
47       * @param portletEntity
48       *                  PortletEntity for which to build the PreferenceSet for.
49       * @throws BackingStoreException
50       *                   if an error is encountered while accessing the Preferences
51       *                   backing store.
52       */
53      public PrefsPreferenceSetImpl( Preferences prefsRootNode ) throws BackingStoreException
54      {
55          super();
56          this.prefsRootNode = prefsRootNode;
57  
58      }
59      
60      /***
61       * @param portletEntity
62       *                  PortletEntity for which to build the PreferenceSet for.
63       * @param validatorFactory
64       *                  Factory for providing access to a PreferencesValidator instance                
65       * @throws BackingStoreException
66       *                   if an error is encountered while accessing the Preferences
67       *                   backing store.
68       */
69      public PrefsPreferenceSetImpl( Preferences prefsRootNode, PreferencesValidatorFactory validatorFactory ) throws BackingStoreException
70      {
71          this(prefsRootNode);
72          this.validatorFactory = validatorFactory;
73      }
74  
75      public PrefsPreferenceSetImpl( Preferences prefsRootNode,  PreferenceSetComposite defaults) throws BackingStoreException
76      {
77          this(prefsRootNode);        
78          this.defaults = defaults;
79      }
80  
81      /***
82       * <p>
83       * getNames
84       * </p>
85       * 
86       * @see org.apache.jetspeed.om.common.preference.PreferenceSetComposite#getNames()
87       * @return
88       */
89      public Set getNames()
90      {
91          try
92          {
93              if(defaults != null)
94              {
95                  Set names = defaults.getNames();                    
96                  names.addAll(new HashSet(Arrays.asList(prefsRootNode.childrenNames())));
97                  return names;                
98              }
99              else
100             {
101               return new HashSet(Arrays.asList(prefsRootNode.childrenNames()));
102             }
103         }
104         catch (BackingStoreException e)
105         {
106             String msg = "Preference backing store failed: " + e.toString();
107             IllegalStateException ise = new IllegalStateException(msg);
108             ise.initCause(e);
109             throw ise;
110         }
111     }
112 
113     /***
114      * <p>
115      * get
116      * </p>
117      * 
118      * @see org.apache.pluto.om.common.PreferenceSet#get(java.lang.String)
119      * @param arg0
120      * @return
121      */
122     public Preference get( String key )
123     {
124         try
125         {
126             Preference pref = null;
127             if (prefsRootNode.nodeExists(key))
128             {
129                 pref = new PrefsPreference(prefsRootNode.node(key), key);
130             }
131             else if(defaults != null)
132             {
133                 pref = defaults.get(key);
134             }
135             
136             return pref;
137         }
138         catch (IllegalStateException ise)
139         {
140             // node has been removed
141             return null;
142         }        
143         catch (BackingStoreException e)
144         {
145             String msg = "Preference backing store failed: " + e.toString();
146             IllegalStateException ise = new IllegalStateException(msg);
147             ise.initCause(e);
148             throw ise;
149         }
150     }
151 
152     /***
153      * <p>
154      * getPreferencesValidator
155      * </p>
156      * 
157      * @see org.apache.pluto.om.common.PreferenceSet#getPreferencesValidator()
158      * @return
159      */
160     public PreferencesValidator getPreferencesValidator()
161     {
162         if ( validatorFactory != null )
163         {
164             return validatorFactory.getPreferencesValidator();
165         }
166         return null;
167     }
168 
169     /***
170      * <p>
171      * add
172      * </p>
173      * 
174      * @see org.apache.pluto.om.common.PreferenceSetCtrl#add(java.lang.String,
175      *          java.util.List)
176      * @param name
177      * @param values
178      * @return
179      */
180     public Preference add( String name, List values )
181     {
182         Iterator valuesItr = values.iterator();
183 
184         PrefsPreference pref = new PrefsPreference(prefsRootNode.node(name), name);
185         while (valuesItr.hasNext())
186         {
187             pref.addValue((String) valuesItr.next());
188         }
189 
190         return pref;
191     }
192 
193     /***
194      * <p>
195      * remove
196      * </p>
197      * 
198      * @see org.apache.pluto.om.common.PreferenceSetCtrl#remove(org.apache.pluto.om.common.Preference)
199      * @param arg0
200      */
201     public void remove( Preference pref )
202     {
203         remove(pref.getName());
204     }
205 
206     /***
207      * <p>
208      * remove
209      * </p>
210      * 
211      * @see org.apache.pluto.om.common.PreferenceSetCtrl#remove(java.lang.String)
212      * @param arg0
213      * @return
214      */
215     public Preference remove( String key )
216     {
217         try
218         {
219         	Preferences nodeToRemove = prefsRootNode.node(key);
220         	
221             if (nodeToRemove == null)
222             	return null;
223             PrefsPreference pref = new PrefsPreference(nodeToRemove, key);
224             nodeToRemove.removeNode();
225             return pref;
226         }
227         catch (BackingStoreException e)
228         {
229             String msg = "Preference backing store failed: " + e.toString();
230             IllegalStateException ise = new IllegalStateException(msg);
231             ise.initCause(e);
232             throw ise;
233         }
234     }
235 
236     /***
237      *  
238      */
239     public void flush() throws BackingStoreException
240     {
241         prefsRootNode.flush();
242     }
243     
244     /***
245      * 
246      * <p>
247      * clear
248      * </p>
249      *
250      * @throws BackingStoreException
251      */
252     public void clear() throws BackingStoreException
253     {
254         prefsRootNode.removeNode();
255     }
256 
257     /***
258      * <p>
259      * size
260      * </p>
261      * 
262      * @see org.apache.jetspeed.om.common.preference.PreferenceSetComposite#size()
263      * @return
264      */
265     public int size()
266     {
267         try
268         {
269             int length = prefsRootNode.childrenNames().length;
270             
271             if(defaults != null)
272             {
273                 length += defaults.size();
274             }
275                   
276             return length;
277         }
278         catch (IllegalStateException ise)
279         {
280             // node has been removed
281             return 0;
282         }
283         catch (BackingStoreException e)
284         {
285             IllegalStateException ise = new IllegalStateException(e.toString());
286             ise.initCause(e);
287             throw ise;
288         }
289     }
290 
291     /***
292      * <p>
293      * iterator
294      * </p>
295      * 
296      * @see org.apache.pluto.om.common.PreferenceSet#iterator()
297      * @return
298      */
299     public Iterator iterator()
300     {
301         return new PortletPrefsIterator();
302     }
303 
304     protected class PortletPrefsIterator implements Iterator
305     {
306         int beginSize = 0;
307         int pointer;
308         String[] childrenNames;
309         protected PrefsPreference currentPref;
310 
311         protected PortletPrefsIterator()
312         {
313             super();
314             try
315             {
316                 childrenNames = prefsRootNode.childrenNames();
317                 if (childrenNames != null)
318                 	beginSize =  childrenNames.length;
319                 
320                 if(defaults != null)
321                 {
322                     Vector v = new Vector();
323 
324                     Iterator itr = defaults.getNames().iterator();
325                     while( itr.hasNext())
326                     {
327                         String name = (String) itr.next();
328                         if(!arrayContains(childrenNames, name))
329                         {
330                         	v.add(name);
331                         }
332                     }
333                     int j = v.size();
334                     if (j>0)
335                     {
336                     	int i = childrenNames.length;
337                         String[] tempArray = new String[j+i];
338                         System.arraycopy(childrenNames, 0, tempArray, 0, i);
339                         for (int x = 0; x < j; x++)
340                             tempArray[i+x] = (String)v.get(x);
341                         childrenNames = tempArray;
342                         beginSize = i+j;
343                     }
344                 }
345                 pointer = 0;
346             }
347             catch (IllegalStateException ise)
348             {
349                 // node has been removed
350                 childrenNames = new String[0];
351             }                    
352             catch (BackingStoreException e)
353             {
354                 String msg = "Preference backing store failed: " + e.toString();
355                 IllegalStateException ise = new IllegalStateException(msg);
356                 ise.initCause(e);
357                 throw ise;
358             }
359 
360         }
361 
362         /***
363          * <p>
364          * hasNext
365          * </p>
366          * 
367          * @see java.util.Iterator#hasNext()
368          * @return
369          */
370         public boolean hasNext()
371         {
372         	try
373         	{
374         		return pointer < beginSize;
375         	}
376         	catch (Exception e)
377         	{
378             	throw new ConcurrentModificationException("Underlying PreferenceSet has changed.");
379         	}
380         }
381 
382         /***
383          * <p>
384          * next
385          * </p>
386          * 
387          * @see java.util.Iterator#next()
388          * @return
389          */
390         public Object next()
391         {
392 			try
393 			{
394 	            currentPref = (PrefsPreference) get(childrenNames[pointer]);
395 	            pointer++;
396 	            return currentPref;
397 	    	}
398 	    	catch (Exception e)
399 	    	{
400 	        	throw new ConcurrentModificationException("Underlying PreferenceSet has changed.");
401 	    	}
402         }
403 
404         /***
405          * <p>
406          * remove
407          * </p>
408          * 
409          * @see java.util.Iterator#remove()
410          *  
411          */
412         public void remove()
413         {
414             if (currentPref == null)
415             {
416                 throw new IllegalStateException(" next() must be called at least once before invoking remove().");
417             }
418 
419             PrefsPreferenceSetImpl.this.remove(currentPref);
420             beginSize--;
421 
422         }
423     }
424     
425     protected boolean arrayContains(String[] array, String value)
426     {
427         for(int i=0; i<array.length; i++)
428         {
429             if(array[i].equals(value))
430             {
431                 return true;
432             }
433         }
434         
435         return false;
436     }
437    
438 }