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