1 /*
2  * This file is part of the LibreOffice project.
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * This file incorporates work covered by the following license notice:
9  *
10  *   Licensed to the Apache Software Foundation (ASF) under one or more
11  *   contributor license agreements. See the NOTICE file distributed
12  *   with this work for additional information regarding copyright
13  *   ownership. The ASF licenses this file to you under the Apache
14  *   License, Version 2.0 (the "License"); you may not use this file
15  *   except in compliance with the License. You may obtain a copy of
16  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
17  */
18 
19 package helper;
20 
21 import com.sun.star.uno.*;
22 import com.sun.star.lang.*;
23 import com.sun.star.container.*;
24 import com.sun.star.beans.*;
25 import com.sun.star.util.*;
26 
27 /**
28  * This <CODE>ConfigHelper</CODE> makes it possible to access the
29  * configuration and change their content.<P>
30  * <P>
31  * Example: <P>
32  * Listing of the <CODE>Configuration</CODE> Views.xcu:<P>
33  * &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>
34  *   &lt;node oor:name=&quot;Windows&quot;&gt;<P>
35  *       <&lt;node oor:name=&quot;SplitWindow0&quot; oor:op=&quot;replace&quot;&gt;<P>
36  *           &lt;prop oor:name=&quot;Visible&quot; oor:type=&quot;xs:boolean&quot;&gt;<P>
37  *                &lt;value&gt;false&lt;/value&gt;<P>
38  *           &lt;/prop&gt;<P>
39  *           &lt;prop oor:name=&quot;WindowState&quot; oor:type=&quot;xs:string&quot;&gt;<P>
40  *               &lt;value/&gt;<P>
41  *           &lt;/prop&gt;<P>
42  *            &lt;node oor:name=&quot;UserData&quot;&gt;<P>
43  *               &lt;prop oor:name=&quot;UserItem&quot; oor:op=&quot;replace&quot;
44  *                oor:type=&quot;xs:string&quot;&gt;<P>
45  *                   &lt;value&gt;V1,2,0&lt;/value&gt;<P>
46  *               &lt;/prop&gt;<P>
47  *           &lt;/node&gt;<P>
48  *        &lt;/node&gt;<P>
49  *  &lt;/node&gt;<P>
50  * <P>
51  * <CODE>Definition</CODE><P>
52  * <ul>
53  *    <li><CODE>&lt;node oor:name=&quot;Windows&quot;&gt;</CODE>
54  *        represents a <CODE>Set</CODE> and is a <CODE>XNameContainer</CODE></LI>
55  *    <li><CODE>&lt;node oor:name=&quot;SplitWindow0&quot;&gt;</CODE>
56  *        represents a <CODE>Group</CODE> and is a <CODE>XNameReplace</CODE></LI>
57  *    <li><CODE>&lt;prop oor:name=&quot;Visible&quot;&gt;</CODE>
58  *        represents a pr<CODE></CODE>operty of the group</li>
59  *    <li><CODE>&lt;node oor:name=&quot;UserData&quot;&gt;</CODE>
60  *        represents a <CODE>extensible group</CODE> and is a <CODE>XNameContainer</CODE></LI>
61  *    <li><CODE>&lt;prop oor:name=&quot;UserItem&quot;&gt;</CODE>
62  *        represents a <CODE>property</CODE> of the extensible group</LI>
63  * </UL>
64  * We assume in the following examples the existence of:<P>
65  * <CODE>ConfigHelper aConfig = new ConfigHelper(xMSF, "org.openoffice.Office.Views", false);</CODE>
66  * <ul>
67  *    <li>If you like to insert a new <CODE>Group</CODE> into the <CODE>Set</CODE> "Windows":<p>
68  *        <CODE>XNameReplace xMyGroup = aConfig.getOrInsertGroup("Windows", "myGroup");</CODE><P>
69  *        The method <CODE>getOrInsertGroup()</CODE> uses the
70  *        <CODE>XSingleServiceFactory</CODE> to create the skeleton of a new group.
71  *
72  *    </li>
73  *    <li>If you like to change the property "WindowState" of "myGroup"
74  *        of the Set "Windows"<p>
75  *        <CODE>aConfig.updateGroupProperty(
76  *          "Windows","myGroup", "WindowState", "952,180,244,349;1;0,0,0,0;");</CODE>
77  *    </li>
78  *    <li>If you like to change the property "myProp" of the extensible group
79  *        "myExtGroup" which is an extensible group of "my2ndGroup" of the
80  *        Set "Windows":<p>
81  *        <CODE>aConfig.insertOrUpdateExtensibleGroupProperty(
82  *              "Windows", "my2ndGroup", "myExtGroup", "myProp","TheValue");</CODE>
83  *    </li>
84  * </ul>
85  */
86 public class ConfigHelper
87 {
88     private final XHierarchicalNameAccess m_xConfig;
89 
90 
ConfigHelper(XMultiServiceFactory xSMGR , String sConfigPath , boolean bReadOnly )91     public ConfigHelper(XMultiServiceFactory xSMGR       ,
92                         String               sConfigPath ,
93                         boolean              bReadOnly   )
94         throws com.sun.star.uno.Exception
95     {
96         XMultiServiceFactory xConfigRoot = UnoRuntime.queryInterface(
97           XMultiServiceFactory.class,
98           xSMGR.createInstance("com.sun.star.configuration.ConfigurationProvider"));
99 
100         PropertyValue[] lParams = new PropertyValue[1];
101         lParams[0] = new PropertyValue();
102         lParams[0].Name  = "nodepath";
103         lParams[0].Value = sConfigPath;
104 
105         Object aConfig;
106         if (bReadOnly)
107             aConfig = xConfigRoot.createInstanceWithArguments(
108                             "com.sun.star.configuration.ConfigurationAccess",
109                             lParams);
110         else
111             aConfig = xConfigRoot.createInstanceWithArguments(
112                             "com.sun.star.configuration.ConfigurationUpdateAccess",
113                             lParams);
114 
115         m_xConfig = UnoRuntime.queryInterface(
116                             XHierarchicalNameAccess.class,
117                             aConfig);
118 
119         if (m_xConfig == null)
120             throw new com.sun.star.uno.Exception("Could not open configuration \""+sConfigPath+"\"");
121     }
122 
123 
124     /**
125      * Updates the configuration.<p>
126      * This must be called after you have changed the configuration
127      * else you changes will be lost.
128      */
flush()129     public void flush()
130     {
131         try
132         {
133             XChangesBatch xBatch = UnoRuntime.queryInterface(
134                                         XChangesBatch.class,
135                                         m_xConfig);
136             xBatch.commitChanges();
137         }
138         catch(com.sun.star.uno.Exception ex)
139         {}
140     }
141 
142 
143 
144 
145 
146 
147 
148 
149     /**
150      * Insert a structured node (group) in a name container (set)
151      * or else update it and return the <CODE>XNameReplace</CODE> of it.<P>
152      * The <CODE>XSingleServiceFacttory</CODE> of the <CODE>set</CODE> will be used
153      * to create a new group. This group is specific to its set and
154      * creates defined entries.
155      * @return The [inserted] group of the set
156      * @param groupName The name of the goup which should be returned
157      * @param setName The name of the set
158      * @throws com.sun.star.uno.Exception throws
159      *         <CODE>com.sun.star.uno.Exception</CODE> on any error.
160      */
getOrInsertGroup(String setName, String groupName)161     public XNameReplace getOrInsertGroup(String setName, String groupName)
162         throws  com.sun.star.uno.Exception
163 
164     {
165         XNameContainer xSetCont = this.getSet(setName);
166 
167         XNameReplace xChildAccess = null;
168 
169         try {
170             xSetCont.getByName(groupName);
171             xChildAccess = UnoRuntime.queryInterface(
172                             XNameReplace.class,xSetCont);
173         } catch(com.sun.star.container.NoSuchElementException e) {
174              // proceed with inserting
175         }
176 
177         if (xChildAccess == null)  {
178             XSingleServiceFactory xChildfactory = UnoRuntime.queryInterface(XSingleServiceFactory.class,xSetCont);
179 
180             Object xNewChild = xChildfactory.createInstance();
181 
182             xSetCont.insertByName(groupName, xNewChild);
183 
184             xChildAccess = UnoRuntime.queryInterface(XNameContainer.class,xNewChild);
185        }
186 
187         return xChildAccess;
188     }
189 
190      /**
191      * Update a property of a group container of a set container
192      * @param setName the name of the <CODE>set</CODE> which contains the <CODE>group</CODE>
193      * @param groupName the name of the <CODE>group</CODE> which property should be changed
194      * @param propName the name of the property which should be changed
195      * @param propValue the value the property should get
196      * @throws com.sun.star.uno.Exception throws <CODE>com.sun.star.uno.Exception</CODE> on any error.
197      */
updateGroupProperty(String setName, String groupName, String propName, Object propValue)198     public void updateGroupProperty(String setName,
199                                     String groupName,
200                                     String propName,
201                                     Object propValue)
202         throws  com.sun.star.uno.Exception
203     {
204         XNameContainer xSetCont = this.getSet(setName);
205 
206         XPropertySet xProp = null;
207         try {
208         xProp = UnoRuntime.queryInterface(
209                                     XPropertySet.class,
210                                     xSetCont.getByName(groupName));
211         } catch (com.sun.star.container.NoSuchElementException ex){
212             throw new com.sun.star.uno.Exception(ex,
213                 "could not get group '" + groupName +
214                "' from set '"+ setName +"'");
215         }
216         try{
217             xProp.setPropertyValue(propName, propValue);
218         } catch (com.sun.star.uno.Exception ex) {
219              throw new com.sun.star.uno.Exception(ex,
220                 "could not set property '" + propName +
221                 "' from group '"+ groupName +
222                 "' from set '"+ setName +"'");
223         }
224     }
225 
226 
227     /**
228      * Insert a property in an extensible group container or else update it
229      * @param setName the name of the <CODE>set</CODE> which contains the <CODE>group</CODE>
230      * @param group The name of the <CODE>group</CODE> which contains the <CODE>extensible group</CODE>.
231      * @param extGroup The name of the <CODE>extensible group</CODE> which
232      *                  [should] contain the property
233      * @param propName The name of the property.
234      * @param propValue The value of the property.
235      * @throws com.sun.star.uno.Exception throws <CODE>com.sun.star.uno.Exception</CODE> on any error.
236      */
insertOrUpdateExtensibleGroupProperty( String setName, String group, String extGroup, String propName, Object propValue)237     public void insertOrUpdateExtensibleGroupProperty(
238                     String setName,
239                     String group,
240                     String extGroup,
241                     String propName,
242                     Object propValue)
243         throws  com.sun.star.uno.Exception
244     {
245         XNameContainer xSetCont = this.getSet(setName);
246 
247         XNameReplace xGroupAccess = null;
248         XNameContainer xExtGroupCont = null;
249 
250         try {
251             Object xGroup=xSetCont.getByName(group);
252             xGroupAccess = UnoRuntime.queryInterface(
253                             XNameReplace.class,xGroup);
254         } catch(com.sun.star.container.NoSuchElementException ex) {
255              throw new com.sun.star.uno.Exception(ex,
256                 "could not get group '" + group +
257                 "' from set '"+ setName +"'");
258         }
259 
260         try {
261             Object xGroup=xGroupAccess.getByName(extGroup);
262             xExtGroupCont = UnoRuntime.queryInterface(
263                             XNameContainer.class,xGroup);
264         } catch(com.sun.star.container.NoSuchElementException ex) {
265              throw new com.sun.star.uno.Exception(ex,
266                 "could not get extensible group '"+extGroup+
267                 "' from group '"+ group +
268                 "' from set '"+ setName +"'");
269         }
270 
271         try {
272             xExtGroupCont.insertByName(propName, propValue);
273         }
274         catch(com.sun.star.container.ElementExistException e) {
275             xExtGroupCont.replaceByName(propName, propValue);
276         }
277 
278     }
279 
280 
281     /**
282      * Returns a <CODE>XNameContainer</CODE> of the <CODE>Set</CODE>
283      * of the <CODE>Configuration</CODE>
284      * @param setName the name of the Set which should be returned
285      * @throws com.sun.star.uno.Exception on any error
286      * @return A XNameContainer of the Set
287      */
getSet(String setName)288     private XNameContainer getSet(String setName)
289         throws com.sun.star.uno.Exception
290     {
291         XNameReplace xCont = UnoRuntime.queryInterface(XNameReplace.class, m_xConfig);
292 
293         Object oSet = xCont.getByName(setName);
294 
295         if (oSet == null)
296              throw new com.sun.star.uno.Exception(
297                 "could not get set '" + setName + ": null");
298 
299         return UnoRuntime.queryInterface(
300                                                 XNameContainer.class, oSet);
301 
302     }
303 }
304