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