1 package helper;
2 
3 import com.sun.star.uno.*;
4 import com.sun.star.lang.*;
5 import com.sun.star.container.*;
6 import com.sun.star.beans.*;
7 import com.sun.star.util.*;
8 
9 /**
10  * This <CODE>ConfigHelper</CODE> makes it possible to access the
11  * configuration and change their content.<P>
12  * <P>
13  * Example: <P>
14  * Listing of the <CODE>Configuration</CODE> Views.xcu:<P>
15  * &lt;oor:component-data xmlns:oor=&quot;http://openoffice.org/2001/registry&quot; xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot; oor:name=&quot;Views&quot; oor:package=&quot;org.openoffice.Office&quot;&gt;<p>
16  *   &lt;node oor:name=&quot;Windows&quot;&gt;<P>
17  *       <&lt;node oor:name=&quot;SplitWindow0&quot; oor:op=&quot;replace&quot;&gt;<P>
18  *           &lt;prop oor:name=&quot;Visible&quot; oor:type=&quot;xs:boolean&quot;&gt;<P>
19  *                &lt;value&gt;false&lt;/value&gt;<P>
20  *           &lt;/prop&gt;<P>
21  *           &lt;prop oor:name=&quot;WindowState&quot; oor:type=&quot;xs:string&quot;&gt;<P>
22  *               &lt;value/&gt;<P>
23  *           &lt;/prop&gt;<P>
24  *            &lt;node oor:name=&quot;UserData&quot;&gt;<P>
25  *               &lt;prop oor:name=&quot;UserItem&quot; oor:op=&quot;replace&quot;
26  *                oor:type=&quot;xs:string&quot;&gt;<P>
27  *                   &lt;value&gt;V1,2,0&lt;/value&gt;<P>
28  *               &lt;/prop&gt;<P>
29  *           &lt;/node&gt;<P>
30  *        &lt;/node&gt;<P>
31  *  &lt;/node&gt;<P>
32  * <P>
33  * <CODE>Definition</CODE><P>
34  * <ul>
35  *    <li><CODE>&lt;node oor:name=&quot;Windows&quot;&gt;</CODE>
36  *        represents a <CODE>Set</CODE> and is a <CODE>XNameContainer</CODE></LI>
37  *    <li><CODE>&lt;node oor:name=&quot;SplitWindow0&quot;&gt;</CODE>
38  *        represents a <CODE>Group</CODE> and is a <CODE>XNameReplace</CODE></LI>
39  *    <li><CODE>&lt;prop oor:name=&quot;Visible&quot;&gt;</CODE>
40  *        represents a pr<CODE></CODE>operty of the group</li>
41  *    <li><CODE>&lt;node oor:name=&quot;UserData&quot;&gt;</CODE>
42  *        represents a <CODE>extensible group</CODE> and is a <CODE>XNameContainer</CODE></LI>
43  *    <li><CODE>&lt;prop oor:name=&quot;UserItem&quot;&gt;</CODE>
44  *        represents a <CODE>property</CODE> of the extensible group</LI>
45  * </UL>
46  * We assume in the following examples the existance of:<P>
47  * <CODE>ConfigHelper aConfig = new ConfigHelper(xMSF, "org.openoffice.Office.Views", false);</CODE>
48  * <ul>
49  *    <li>If you like to insert a new <CODE>Group</CODE> into the <CODE>Set</CODE> "Windows":<p>
50  *        <CODE>XNameReplace xMyGroup = aConfig.getOrInsertGroup("Windows", "myGroup");</CODE><P>
51  *        The method <CODE>getOrInsertGroup()</CODE> uses the
52  *        <CODE>XSingleServiceFactory</CODE> to create the skeleton of a new group.
53  *
54  *    </li>
55  *    <li>If you like to change the property "WindowState" of "myGroup"
56  *        of the Set "Windows"<p>
57  *        <CODE>aConfig.updateGroupProperty(
58  *          "Windows","myGroup", "WindowState", "952,180,244,349;1;0,0,0,0;");</CODE>
59  *    </li>
60  *    <li>If you like to change the property "myProp" of the extensible group
61  *        "myExtGroup" which is an extensible group of "my2ndGroup" of the
62  *        Set "Windows":<p>
63  *        <CODE>aConfig.insertOrUpdateExtensibleGroupProperty(
64  *              "Windows", "my2ndGroup", "myExtGroup", "myProp","TheValue");</CODE>
65  *    </li>
66  * </ul>
67  */
68 public class ConfigHelper
69 {
70     private XMultiServiceFactory m_xSMGR = null;
71     private XHierarchicalNameAccess m_xConfig = null;
72 
73     //-----------------------------------------------
74     public ConfigHelper(XMultiServiceFactory xSMGR       ,
75                         String               sConfigPath ,
76                         boolean              bReadOnly   )
77         throws com.sun.star.uno.Exception
78     {
79         m_xSMGR = xSMGR;
80 
81         XMultiServiceFactory xConfigRoot = (XMultiServiceFactory)
82                         UnoRuntime.queryInterface(
83                         XMultiServiceFactory.class,
84                         m_xSMGR.createInstance(
85                         "com.sun.star.configuration.ConfigurationProvider"));
86 
87         PropertyValue[] lParams = new PropertyValue[1];
88         lParams[0] = new PropertyValue();
89         lParams[0].Name  = "nodepath";
90         lParams[0].Value = sConfigPath;
91 
92         Object aConfig;
93         if (bReadOnly)
94             aConfig = xConfigRoot.createInstanceWithArguments(
95                             "com.sun.star.configuration.ConfigurationAccess",
96                             lParams);
97         else
98             aConfig = xConfigRoot.createInstanceWithArguments(
99                             "com.sun.star.configuration.ConfigurationUpdateAccess",
100                             lParams);
101 
102         m_xConfig = (XHierarchicalNameAccess)UnoRuntime.queryInterface(
103                             XHierarchicalNameAccess.class,
104                             aConfig);
105 
106         if (m_xConfig == null)
107             throw new com.sun.star.uno.Exception("Could not open configuration \""+sConfigPath+"\"");
108     }
109 
110     //-----------------------------------------------
111     public Object readRelativeKey(String sRelPath,
112                                   String sKey    )
113         throws com.sun.star.container.NoSuchElementException
114     {
115         try
116         {
117             XPropertySet xPath = (XPropertySet)UnoRuntime.queryInterface(
118                                     XPropertySet.class,
119                                     m_xConfig.getByHierarchicalName(sRelPath));
120             return xPath.getPropertyValue(sKey);
121         }
122         catch(com.sun.star.uno.Exception ex)
123         {
124             throw new com.sun.star.container.NoSuchElementException(ex.getMessage());
125         }
126     }
127 
128     //-----------------------------------------------
129     public void writeRelativeKey(String sRelPath,
130                                  String sKey    ,
131                                  Object aValue  )
132         throws com.sun.star.container.NoSuchElementException
133     {
134         try
135         {
136             XPropertySet xPath = (XPropertySet)UnoRuntime.queryInterface(
137                                     XPropertySet.class,
138                                     m_xConfig.getByHierarchicalName(sRelPath));
139             xPath.setPropertyValue(sKey, aValue);
140         }
141         catch(com.sun.star.uno.Exception ex)
142         {
143             throw new com.sun.star.container.NoSuchElementException(ex.getMessage());
144         }
145     }
146 
147     //-----------------------------------------------
148     /**
149      * Updates the configuration.<p>
150      * This must be called after you have changed the configuration
151      * else you changes will be lost.
152      */
153     public void flush()
154     {
155         try
156         {
157             XChangesBatch xBatch = (XChangesBatch)UnoRuntime.queryInterface(
158                                         XChangesBatch.class,
159                                         m_xConfig);
160             xBatch.commitChanges();
161         }
162         catch(com.sun.star.uno.Exception ex)
163         {}
164     }
165 
166     //-----------------------------------------------
167     public static Object readDirectKey(XMultiServiceFactory xSMGR      ,
168                                        String               sConfigFile,
169                                        String               sRelPath   ,
170                                        String               sKey       )
171         throws com.sun.star.uno.Exception
172     {
173         ConfigHelper aConfig = new ConfigHelper(xSMGR, sConfigFile, true);
174         return aConfig.readRelativeKey(sRelPath, sKey);
175     }
176 
177     //-----------------------------------------------
178     public static void writeDirectKey(XMultiServiceFactory xSMGR      ,
179                                       String               sConfigFile,
180                                       String               sRelPath   ,
181                                       String               sKey       ,
182                                       Object               aValue     )
183         throws com.sun.star.uno.Exception
184     {
185         ConfigHelper aConfig = new ConfigHelper(xSMGR, sConfigFile, false);
186         aConfig.writeRelativeKey(sRelPath, sKey, aValue);
187         aConfig.flush();
188     }
189 
190 
191     /**
192      * Insert a structured node (group) in a name container (set)
193      * or else update it and retrun the <CODE>XNameReplace</CODE> of it.<P>
194      * The <CODE>XSingleServiceFacttory</CODE> of the <CODE>set</CODE> will be used
195      * to create a new group. This group is specific to its set and
196      * creates defined entries.
197      * @return The [inserted] group of the set
198      * @param groupName The name of the goup which should be returned
199      * @param setName The name of the set
200      * @throws com.sun.star.uno.Exception throws
201      *         <CODE>com.sun.star.uno.Exeception</CODE> on any error.
202      */
203     public XNameReplace getOrInsertGroup(String setName, String groupName)
204         throws  com.sun.star.uno.Exception
205 
206     {
207         XNameContainer xSetCont = this.getSet(setName);
208 
209         XNameReplace xChildAccess = null;
210 
211         try {
212             Object xChild=xSetCont.getByName(groupName);
213             xChildAccess = (XNameReplace) UnoRuntime.queryInterface(
214                             XNameReplace.class,xSetCont);
215         } catch(com.sun.star.container.NoSuchElementException e) {
216              // proceed with inserting
217         }
218 
219         if (xChildAccess == null)  {
220             XSingleServiceFactory xChildfactory = (XSingleServiceFactory)
221                 UnoRuntime.queryInterface(XSingleServiceFactory.class,xSetCont);
222 
223             Object xNewChild = xChildfactory.createInstance();
224 
225             xSetCont.insertByName(groupName, xNewChild);
226 
227             xChildAccess = (XNameReplace)
228                 UnoRuntime.queryInterface(XNameContainer.class,xNewChild);
229        }
230 
231         return xChildAccess;
232     }
233 
234      /**
235      * Update a property of a group container of a set container
236      * @param setName the name of the <CODE>set</CODE> which containes the <CODE>group</CODE>
237      * @param groupName the name of the <CODE>group</CODE> which property should be changed
238      * @param propName the name of the property which should be changed
239      * @param propValue the value the property should get
240      * @throws com.sun.star.uno.Exception throws <CODE>com.sun.star.uno.Exeception</CODE> on any error.
241      */
242     public void updateGroupProperty(String setName,
243                                     String groupName,
244                                     String propName,
245                                     Object propValue)
246         throws  com.sun.star.uno.Exception
247     {
248         XNameContainer xSetCont = this.getSet(setName);
249 
250         XPropertySet xProp = null;
251         try {
252         xProp = (XPropertySet)UnoRuntime.queryInterface(
253                                     XPropertySet.class,
254                                     xSetCont.getByName(groupName));
255         } catch (com.sun.star.container.NoSuchElementException e){
256             throw new com.sun.star.uno.Exception(
257                 "could not get group '" + groupName +
258                "' from set '"+ setName +"':\n" + e.toString());
259         }
260         try{
261             xProp.setPropertyValue(propName, propValue);
262         } catch (com.sun.star.uno.Exception e) {
263              throw new com.sun.star.uno.Exception(
264                 "could not set property '" + propName +
265                 "' from group '"+ groupName +
266                 "' from set '"+ setName +"':\n" + e.toString());
267         }
268     }
269 
270 
271     /**
272      * Insert a property in an extensible group container or else update it
273      * @param setName the name of the <CODE>set</CODE> which containes the <CODE>group</CODE>
274      * @param group The name of the <CODE>group</CODE> which conatins the <CODE>extensible group</CODE>.
275      * @param extGroup The name of the <CODE>extensible group</CODE> which
276      *                  [should] contain the property
277      * @param propName The name of the property.
278      * @param propValue The value of the property.
279      * @throws com.sun.star.uno.Exception throws <CODE>com.sun.star.uno.Exeception</CODE> on any error.
280      */
281     public void insertOrUpdateExtensibleGroupProperty(
282                     String setName,
283                     String group,
284                     String extGroup,
285                     String propName,
286                     Object propValue)
287         throws  com.sun.star.uno.Exception
288     {
289         XNameContainer xSetCont = this.getSet(setName);
290 
291         XNameReplace xGroupAccess = null;
292         XNameContainer xExtGroupCont = null;
293 
294         try {
295             Object xGroup=xSetCont.getByName(group);
296             xGroupAccess = (XNameReplace) UnoRuntime.queryInterface(
297                             XNameReplace.class,xGroup);
298         } catch(com.sun.star.container.NoSuchElementException e) {
299              throw new com.sun.star.uno.Exception(
300                 "could not get group '" + group +
301                 "' from set '"+ setName +"':\n" + e.toString());
302         }
303 
304         try {
305             Object xGroup=xGroupAccess.getByName(extGroup);
306             xExtGroupCont = (XNameContainer) UnoRuntime.queryInterface(
307                             XNameContainer.class,xGroup);
308         } catch(com.sun.star.container.NoSuchElementException e) {
309              throw new com.sun.star.uno.Exception(
310                 "could not get extensilbe group '"+extGroup+
311                 "' from group '"+ group +
312                 "' from set '"+ setName +"':\n" + e.toString());
313         }
314 
315         try {
316             xExtGroupCont.insertByName(propName, propValue);
317         }
318         catch(com.sun.star.container.ElementExistException e) {
319             xExtGroupCont .replaceByName(propName, propValue);
320         }
321 
322     }
323 
324 
325     /**
326      * Returns a <CODE>XNameContainer</CODE> of the <CODE>Set</CODE>
327      * of the <CODE>Configuration</CODE>
328      * @param setName the name of the Set which sould be returned
329      * @throws com.sun.star.uno.Exception on any error
330      * @return A XNameContainer of the Set
331      */
332     public XNameContainer getSet(String setName)
333         throws com.sun.star.uno.Exception
334     {
335         XNameReplace xCont = (XNameReplace)
336                     UnoRuntime.queryInterface(XNameReplace.class, m_xConfig);
337 
338         Object oSet = xCont.getByName(setName);
339 
340         if (oSet == null)
341              throw new com.sun.star.uno.Exception(
342                 "could not get set '" + setName + ": null");
343 
344         return (XNameContainer) UnoRuntime.queryInterface(
345                                                 XNameContainer.class, oSet);
346 
347     }
348 }
349