1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 package com.sun.star.wizards.common;
24 
25 import java.util.*;
26 
27 import javax.swing.ListModel;
28 import javax.swing.event.ListDataEvent;
29 
30 
31 import org.w3c.dom.*;
32 
33 /**
34  *
35  * @author  rpiterman
36  */
37 public class ConfigSet implements ConfigNode, XMLProvider, ListModel
38 {
39 
40     private Class childClass;
41     private Map childrenMap = new HashMap();
42     private List childrenList = new Vector();
43     public Object root;
44     /**
45      * After reading the configuration set items,
46      * the ConfigSet checks this field.
47      * If it is true, it will remove any nulls from
48      * the vector.
49      * subclasses can change this field in the constructor
50      * to avoid this "deletion" of nulls.
51      */
52     protected boolean noNulls = true;
53     /** Utility field used by event firing mechanism. */
54     private javax.swing.event.EventListenerList listenerList = null;
55 
ConfigSet(Class childType)56     public ConfigSet(Class childType)
57     {
58         childClass = childType;
59     }
60 
add(String name, Object child)61     public void add(String name, Object child)
62     {
63         childrenMap.put(name, child);
64         try
65         {
66             int i = ((Indexable) child).getIndex();
67             int oldSize = getSize();
68             while (getSize() <= i)
69             {
70                 childrenList.add(null);
71             }
72             childrenList.set(i, child);
73             if (oldSize > i)
74             {
75                 oldSize = i;
76             }
77             fireListDataListenerIntervalAdded(oldSize, i);
78         }
79         catch (ClassCastException cce)
80         {
81             childrenList.add(child);
82             fireListDataListenerIntervalAdded(getSize() - 1, getSize() - 1);
83         }
84     }
85 
add(int i, Object o)86     public void add(int i, Object o)
87     {
88         int name = i;
89         while (getElement(PropertyNames.EMPTY_STRING + name) != null)
90         {
91             name++;
92         }
93         childrenMap.put(PropertyNames.EMPTY_STRING + name, o);
94         childrenList.add(i, o);
95 
96         fireListDataListenerIntervalAdded(i, i);
97     }
98 
createChild()99     protected Object createChild() throws InstantiationException, IllegalAccessException
100     {
101         return childClass.newInstance();
102     }
103 
writeConfiguration(Object configView, Object param)104     public void writeConfiguration(Object configView, Object param)
105     {
106         Object[] names = childrenMap.keySet().toArray();
107 
108         if (ConfigNode.class.isAssignableFrom(childClass))
109         {
110             //first I remove all the children from the configuration.
111             String children[] = Configuration.getChildrenNames(configView);
112             for (int i = 0; i < children.length; i++)
113             {
114                 try
115                 {
116                     Configuration.removeNode(configView, children[i]);
117                 }
118                 catch (Exception ex)
119                 {
120                     ex.printStackTrace();
121                 }            // and add them new.
122             }
123             for (int i = 0; i < names.length; i++)
124             {
125                 try
126                 {
127                     ConfigNode child = (ConfigNode) getElement(names[i]);
128                     Object childView = Configuration.addConfigNode(configView, (String) names[i]);
129                     child.writeConfiguration(childView, param);
130                 }
131                 catch (Exception ex)
132                 {
133                     ex.printStackTrace();
134                 }
135             }
136         }
137         //for a set of primitive / String type.
138         else
139         {
140             throw new IllegalArgumentException("Unable to write primitive sets to configuration (not implemented)");
141         }
142     }
143 
readConfiguration(Object configurationView, Object param)144     public void readConfiguration(Object configurationView, Object param)
145     {
146         String[] names = Configuration.getChildrenNames(configurationView);
147 
148         if (ConfigNode.class.isAssignableFrom(childClass))
149         {
150 
151             for (int i = 0; i < names.length; i++)
152             {
153                 try
154                 {
155                     ConfigNode child = (ConfigNode) createChild();
156                     child.setRoot(root);
157                     child.readConfiguration(Configuration.getNode(names[i], configurationView), param);
158                     add(names[i], child);
159                 }
160                 catch (Exception ex)
161                 {
162                     ex.printStackTrace();
163                 }
164             }
165             //remove any nulls from the list
166             if (noNulls)
167             {
168                 for (int i = 0; i < childrenList.size(); i++)
169                 {
170                     if (childrenList.get(i) == null)
171                     {
172                         childrenList.remove(i--);
173                     }
174                 }
175             }
176         }
177         //for a set of primitive / String type.
178         else
179         {
180             for (int i = 0; i < names.length; i++)
181             {
182                 try
183                 {
184                     Object child = Configuration.getNode(names[i], configurationView);
185                     add(names[i], child);
186                 }
187                 catch (Exception ex)
188                 {
189                     ex.printStackTrace();
190                 }
191             }
192         }
193     }
194 
remove(Object obj)195     public void remove(Object obj)
196     {
197         Object key = getKey(obj);
198         childrenMap.remove(key);
199         int i = childrenList.indexOf(obj);
200         childrenList.remove(obj);
201         fireListDataListenerIntervalRemoved(i, i);
202     }
203 
remove(int i)204     public void remove(int i)
205     {
206         Object o = getElementAt(i);
207         remove(o);
208     }
209 
clear()210     public void clear()
211     {
212         childrenMap.clear();
213         childrenList.clear();
214     }
215 
update(int i)216     public void update(int i)
217     {
218         fireListDataListenerContentsChanged(i, i);
219     }
220 
createDOM(Node parent)221     public Node createDOM(Node parent)
222     {
223 
224         Object[] items = items();
225 
226         for (int i = 0; i < items.length; i++)
227         {
228             Object item = items[i];
229             if (item instanceof XMLProvider)
230             {
231                 ((XMLProvider) item).createDOM(parent);
232             }
233         }
234         return parent;
235     }
236 
items()237     public Object[] items()
238     {
239         return childrenList.toArray();
240     }
241 
getKey(Object object)242     public Object getKey(Object object)
243     {
244         for (Iterator i = childrenMap.entrySet().iterator(); i.hasNext();)
245         {
246 
247             Map.Entry me = (Map.Entry) i.next();
248             if (me.getValue() == object)
249             {
250                 return me.getKey();
251             }
252         }
253         return null;
254     }
255 
getKey(int i)256     public Object getKey(int i)
257     {
258         int c = 0;
259         while (i > -1)
260         {
261             if (getElementAt(c) != null)
262             {
263                 i--;
264             }
265             c++;
266         }
267         if (c == 0)
268         {
269             return null;
270         }
271         else
272         {
273             return getKey(getElementAt(c - 1));
274         }
275     }
276 
setRoot(Object newRoot)277     public void setRoot(Object newRoot)
278     {
279         root = newRoot;
280     }
281 
282     /** Registers ListDataListener to receive events.
283      * @param listener The listener to register.
284      *
285      */
addListDataListener(javax.swing.event.ListDataListener listener)286     public synchronized void addListDataListener(javax.swing.event.ListDataListener listener)
287     {
288         if (listenerList == null)
289         {
290             listenerList = new javax.swing.event.EventListenerList();
291         }
292         listenerList.add(javax.swing.event.ListDataListener.class, listener);
293     }
294 
295     /** Removes ListDataListener from the list of listeners.
296      * @param listener The listener to remove.
297      *
298      */
removeListDataListener(javax.swing.event.ListDataListener listener)299     public synchronized void removeListDataListener(javax.swing.event.ListDataListener listener)
300     {
301         listenerList.remove(javax.swing.event.ListDataListener.class, listener);
302     }
303 
304     /** Notifies all registered listeners about the event.
305      *
306      * @param event The event to be fired
307      *
308      */
fireListDataListenerIntervalAdded(int i0, int i1)309     private void fireListDataListenerIntervalAdded(int i0, int i1)
310     {
311         ListDataEvent event = new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, i0, i1);
312         if (listenerList == null)
313         {
314             return;
315         }
316         Object[] listeners = listenerList.getListenerList();
317         for (int i = listeners.length - 2; i >= 0; i -= 2)
318         {
319             if (listeners[i] == javax.swing.event.ListDataListener.class)
320             {
321                 ((javax.swing.event.ListDataListener) listeners[i + 1]).intervalAdded(event);
322             }
323         }
324     }
325 
326     /** Notifies all registered listeners about the event.
327      *
328      * @param event The event to be fired
329      *
330      */
fireListDataListenerIntervalRemoved(int i0, int i1)331     private void fireListDataListenerIntervalRemoved(int i0, int i1)
332     {
333         ListDataEvent event = new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, i0, i1);
334         if (listenerList == null)
335         {
336             return;
337         }
338         Object[] listeners = listenerList.getListenerList();
339         for (int i = listeners.length - 2; i >= 0; i -= 2)
340         {
341             if (listeners[i] == javax.swing.event.ListDataListener.class)
342             {
343                 ((javax.swing.event.ListDataListener) listeners[i + 1]).intervalRemoved(event);
344             }
345         }
346     }
347 
348     /** Notifies all registered listeners about the event.
349      *
350      * @param event The event to be fired
351      *
352      */
fireListDataListenerContentsChanged(int i0, int i1)353     private void fireListDataListenerContentsChanged(int i0, int i1)
354     {
355         ListDataEvent event = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, i0, i1);
356         if (listenerList == null)
357         {
358             return;
359         }
360         Object[] listeners = listenerList.getListenerList();
361         for (int i = listeners.length - 2; i >= 0; i -= 2)
362         {
363             if (listeners[i] == javax.swing.event.ListDataListener.class)
364             {
365                 ((javax.swing.event.ListDataListener) listeners[i + 1]).contentsChanged(event);
366             }
367         }
368     }
369 
getElementAt(int i)370     public Object getElementAt(int i)
371     {
372         return childrenList.get(i);
373     }
374 
getElement(Object o)375     public Object getElement(Object o)
376     {
377         return childrenMap.get(o);
378     }
379 
getSize()380     public int getSize()
381     {
382         return childrenList.size();
383     }
384 
keys()385     public Set keys()
386     {
387         return childrenMap.keySet();
388     }
389 
getIndexOf(Object item)390     public int getIndexOf(Object item)
391     {
392         return childrenList.indexOf(item);
393     }
394 
395     /**
396      * Set members might include a property
397      * which orders them.
398      * This method reindexes the given member to be
399      * the index number 0
400      * Do not forget to call commit() after calling this method.
401      * @param confView
402      * @param memebrName
403      */
reindexSet(Object confView, String memberName, String indexPropertyName)404     public void reindexSet(Object confView, String memberName, String indexPropertyName) throws Exception
405     {
406         /*
407          * First I read all memebrs of the set,
408          * except the one that should be number 0
409          * to a vector, ordered by there index property
410          */
411         String[] names = Configuration.getChildrenNames(confView);
412         Vector v = new Vector(names.length);
413         Object member = null;
414         int index = 0;
415         for (int i = 0; i < names.length; i++)
416         {
417             if (!names[i].equals(memberName))
418             {
419                 member = Configuration.getConfigurationNode(names[i], confView);
420                 index = Configuration.getInt(indexPropertyName, member);
421                 while (index >= v.size())
422                 {
423                     v.add(null);
424                 }
425                 v.setElementAt(member, index);
426 
427             }
428         /**
429          * Now I reindex them
430          */
431         }
432         index = 1;
433         for (int i = 0; i < v.size(); i++)
434         {
435             member = v.get(i);
436             if (member != null)
437             {
438                 Configuration.set(index++, indexPropertyName, member);
439             }
440         }
441 
442     }
443 
sort(Comparator comparator)444     public void sort(Comparator comparator)
445     {
446         Collections.sort(this.childrenList, comparator);
447     }
448 }
449