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 util;
25 
26 // access the implementations via names
27 import com.sun.star.uno.UnoRuntime;
28 import java.io.PrintWriter ;
29 
30 import com.sun.star.registry.XRegistryKey ;
31 import com.sun.star.registry.XSimpleRegistry ;
32 import com.sun.star.registry.RegistryKeyType ;
33 import com.sun.star.registry.RegistryValueType ;
34 import com.sun.star.registry.InvalidRegistryException ;
35 import com.sun.star.lang.XMultiServiceFactory ;
36 import com.sun.star.uno.Exception;
37 
38 public class RegistryTools {
39 
40 	/**
41 	* Creates 'com.sun.star.registry.SimpleRegistry'
42 	* service.
43 	* @param xMSF Multiservice factory.
44 	* @return Service created.
45 	*/
createRegistryService(XMultiServiceFactory xMSF)46 	public static XSimpleRegistry createRegistryService
47 		(XMultiServiceFactory xMSF) throws com.sun.star.uno.Exception {
48 
49         Object oInterface = xMSF.createInstance
50         	("com.sun.star.registry.SimpleRegistry");
51         return (XSimpleRegistry) UnoRuntime.queryInterface (
52         	XSimpleRegistry.class, oInterface) ;
53     }
54 
55 	/**
56 	* Opens registry file for reading/writing. If file doesn't
57 	* exist a new one created.
58 	* @param file Registry file name.
59 	* @param xMSF Multiservice factory.
60 	* @return Opened registry.
61 	*/
openRegistry(String file, XMultiServiceFactory xMSF)62     public static XSimpleRegistry openRegistry
63     	(String file, XMultiServiceFactory xMSF)
64     	throws com.sun.star.uno.Exception {
65 
66     	XSimpleRegistry reg = createRegistryService(xMSF) ;
67 
68     	reg.open(file, false, true) ;
69 
70     	return reg ;
71     }
72 
73 	/**
74 	* Compares two registry keys, their names, value
75 	* types and values.
76 	* return <code>true</code> if key names, value types
77 	* and values are equal, else returns <code>false</code>.
78 	*/
compareKeys(XRegistryKey key1, XRegistryKey key2)79 	public static boolean compareKeys
80 		(XRegistryKey key1, XRegistryKey key2) {
81 
82 		if (key1 == null || key2 == null ||
83 			!key1.isValid() || !key2.isValid())
84 
85 			return false ;
86 
87 		String keyName1 = getShortKeyName(key1.getKeyName()) ;
88 		String keyName2 = getShortKeyName(key2.getKeyName()) ;
89 
90 		if (!keyName1.equals(keyName2)) return false ;
91 
92 		try {
93 			if (key1.getValueType() != key2.getValueType()) return false ;
94 		} catch (InvalidRegistryException e) {
95 			return false ;
96 		}
97 
98 		RegistryValueType type ;
99 		try {
100 			type = key1.getValueType() ;
101 
102 			if (type.equals(RegistryValueType.ASCII)) {
103 				if (!key1.getAsciiValue().equals(key2.getAsciiValue()))
104 					return false ;
105 			} else
106 			if (type.equals(RegistryValueType.STRING)) {
107 				if (!key1.getStringValue().equals(key2.getStringValue()))
108 					return false ;
109 			} else
110 			if (type.equals(RegistryValueType.LONG)) {
111 				if (key1.getLongValue() != key2.getLongValue())
112 					return false ;
113 			} else
114 			if (type.equals(RegistryValueType.BINARY)) {
115 				byte[] bin1 = key1.getBinaryValue() ;
116 				byte[] bin2 = key2.getBinaryValue() ;
117 				if (bin1.length != bin2.length)
118 					return false ;
119 				for (int i = 0; i < bin1.length; i++)
120 					if (bin1[i] != bin2[i]) return false ;
121 			} else
122 			if (type.equals(RegistryValueType.ASCIILIST)) {
123 				String[] list1 = key1.getAsciiListValue() ;
124 				String[] list2 = key2.getAsciiListValue() ;
125 				if (list1.length != list2.length)
126 					return false ;
127 				for (int i = 0; i < list1.length; i++)
128 					if (!list1[i].equals(list2[i])) return false ;
129 			} else
130 			if (type.equals(RegistryValueType.STRINGLIST)) {
131 				String[] list1 = key1.getStringListValue() ;
132 				String[] list2 = key2.getStringListValue() ;
133 				if (list1.length != list2.length)
134 					return false ;
135 				for (int i = 0; i < list1.length; i++)
136 					if (!list1[i].equals(list2[i])) return false ;
137 			} else
138 			if (type.equals(RegistryValueType.LONGLIST)) {
139 				int[] list1 = key1.getLongListValue() ;
140 				int[] list2 = key2.getLongListValue() ;
141 				if (list1.length != list2.length)
142 					return false ;
143 				for (int i = 0; i < list1.length; i++)
144 					if (list1[i] != list2[i]) return false ;
145 			}
146 		} catch (Exception e) {
147 			return false ;
148 		}
149 
150 		return true ;
151 	}
152 
153 	/**
154 	* Gets name of the key relative to its parent.
155 	* For example if full name of key is '/key1/subkey'
156 	* short key name is 'subkey'
157 	* @param keyName Full key name.
158 	* @return Short key name.
159 	*/
getShortKeyName(String keyName)160 	public static String getShortKeyName(String keyName) {
161 		if (keyName == null) return null ;
162 		int idx = keyName.lastIndexOf("/") ;
163 		if (idx < 0) return keyName ;
164 		else return keyName.substring(idx + 1) ;
165 	}
166 
167 	/**
168 	* Compare all child keys.
169 	* @param compareRoot If <code>true</code> method also
170 	* compare root keys, if <code>false</code> it begins recursive
171 	* comparing from children of root keys.
172 	* @return <code>true</code> if keys and their sub keys are equal.
173 	*/
compareKeyTrees(XRegistryKey tree1, XRegistryKey tree2, boolean compareRoot)174 	protected static boolean compareKeyTrees
175 		(XRegistryKey tree1, XRegistryKey tree2, boolean compareRoot) {
176 
177 		if (compareRoot && !compareKeys(tree1, tree2)) return false ;
178 
179 		try {
180 			String[] keyNames1 = tree1.getKeyNames() ;
181 			String[] keyNames2 = tree2.getKeyNames() ;
182 
183 			if (keyNames1 == null && keyNames2 == null) return true ;
184 
185 			if (keyNames1 == null || keyNames2 == null ||
186 				keyNames2.length != keyNames1.length)
187 				return false ;
188 
189 			for (int i = 0; i < keyNames1.length; i++) {
190 
191 				String keyName = getShortKeyName(keyNames1[i]) ;
192 				XRegistryKey key2 = tree2.openKey(keyName) ;
193 
194 				if (key2 == null)
195 				// key with the same name doesn't exist in the second tree
196 					return false ;
197 
198 				if (!tree1.getKeyType(keyName).equals(
199 					 tree2.getKeyType(keyName)))
200 					return false ;
201 
202 				if (tree1.getKeyType(keyName).equals(
203 					RegistryKeyType.LINK)) {
204 
205 					if (!getShortKeyName(tree1.getLinkTarget(keyName)).equals(
206 						getShortKeyName(tree2.getLinkTarget(keyName))))
207 
208 						return false ;
209 				} else {
210 
211 					if (compareKeyTrees(tree1.openKey(keyName),
212 						  tree2.openKey(keyName), true) == false) return false ;
213 				}
214 			}
215 		} catch (InvalidRegistryException e) {
216 			return false ;
217 		}
218 
219 		return true ;
220 	}
221 
222 	/**
223 	* Compare keys specified and all their child keys.
224 	* @return <code>true</code> if keys and their sub keys are equal.
225 	*/
compareKeyTrees(XRegistryKey tree1, XRegistryKey tree2)226 	public static boolean compareKeyTrees
227 		(XRegistryKey tree1, XRegistryKey tree2) {
228 
229 		return compareKeyTrees(tree1, tree2, false) ;
230 	}
231 
232 	/**
233 	* Prints to a specified output about all keys and subkeys information
234 	* (key name, type, value, link target, attributes) recursively.
235 	* @param reg Registry for which information is needed.
236 	* @param out Output stream.
237 	*/
printRegistryInfo(XSimpleRegistry reg, PrintWriter out)238 	public static void printRegistryInfo(XSimpleRegistry reg, PrintWriter out) {
239 		try {
240 			printRegistryInfo(reg.getRootKey(), out) ;
241 		} catch (com.sun.star.registry.InvalidRegistryException e) {
242 			out.println("!!! Can't open root registry key for info printing") ;
243 		}
244 	}
245 
246 	/**
247 	* Prints to a specified output about all keys and subkeys information
248 	* (key name, type, value, link target, attributes) recursively.
249 	* @param root Key for which subkeys (and further) information is required.
250 	* @param out Output stream.
251 	*/
printRegistryInfo(XRegistryKey root, PrintWriter out)252 	public static void printRegistryInfo(XRegistryKey root, PrintWriter out) {
253 		if (root == null) {
254 			out.println("/(null)") ;
255 			return ;
256 		}
257 
258 		out.println("/") ;
259 		try {
260 			printTreeInfo(root, out, "  ") ;
261 		} catch (com.sun.star.registry.InvalidRegistryException e) {
262 			out.println("Exception accessing registry :") ;
263 			e.printStackTrace(out) ;
264 		}
265 	}
266 
printTreeInfo(XRegistryKey key, PrintWriter out, String margin)267 	private static void printTreeInfo(XRegistryKey key,
268 		PrintWriter out, String margin)
269 		throws com.sun.star.registry.InvalidRegistryException {
270 
271 		String[] subKeys = key.getKeyNames() ;
272 
273 		if (subKeys == null || subKeys.length == 0) return ;
274 
275 		for (int i = 0; i < subKeys.length; i++) {
276 			printKeyInfo(key, subKeys[i], out, margin) ;
277 			XRegistryKey subKey = key.openKey
278 				(getShortKeyName(subKeys[i])) ;
279 			printTreeInfo(subKey, out, margin + "  ") ;
280 			subKey.closeKey() ;
281 		}
282 	}
283 
printKeyInfo(XRegistryKey parentKey, String keyName, PrintWriter out, String margin)284 	private static void printKeyInfo(XRegistryKey parentKey,
285 		String keyName, PrintWriter out, String margin)
286 		throws com.sun.star.registry.InvalidRegistryException {
287 
288 		out.print(margin) ;
289 		keyName = getShortKeyName(keyName) ;
290 		XRegistryKey key = parentKey.openKey(keyName) ;
291 		if (key != null)
292 			out.print("/" + getShortKeyName(key.getKeyName()) + " ") ;
293 		else {
294 			out.println("(null)") ;
295 			return ;
296 		}
297 
298 		if (!key.isValid()) {
299 			out.println("(not valid)") ;
300 			return ;
301 		}
302 
303 		if (key.isReadOnly()) {
304 			out.print("(read only) ") ;
305 		}
306 
307 		if (parentKey.getKeyType(keyName) == RegistryKeyType.LINK) {
308 			out.println("(link to " + parentKey.getLinkTarget(keyName) + ")") ;
309 			return ;
310 		}
311 
312 		RegistryValueType type ;
313 		try {
314 			type = key.getValueType() ;
315 
316 			if (type.equals(RegistryValueType.ASCII)) {
317 				out.println("[ASCII] = '" + key.getAsciiValue() + "'") ;
318 			} else
319 			if (type.equals(RegistryValueType.STRING)) {
320 				out.println("[STRING] = '" + key.getStringValue() + "'") ;
321 			} else
322 			if (type.equals(RegistryValueType.LONG)) {
323 				out.println("[LONG] = " + key.getLongValue()) ;
324 			} else
325 			if (type.equals(RegistryValueType.BINARY)) {
326 				out.print("[BINARY] = {") ;
327 				byte[] bin = key.getBinaryValue() ;
328 				for (int i = 0; i < bin.length; i++)
329 					out.print("" + bin[i] + ",") ;
330 				out.println("}") ;
331 			} else
332 			if (type.equals(RegistryValueType.ASCIILIST)) {
333 				out.print("[ASCIILIST] = {") ;
334 				String[] list = key.getAsciiListValue() ;
335 				for (int i = 0; i < list.length; i++)
336 					out.print("'" + list[i] + "',") ;
337 				out.println("}") ;
338 			} else
339 			if (type.equals(RegistryValueType.STRINGLIST)) {
340 				out.print("[STRINGLIST] = {") ;
341 				String[] list = key.getStringListValue() ;
342 				for (int i = 0; i < list.length; i++)
343 					out.print("'" + list[i] + "',") ;
344 				out.println("}") ;
345 			} else
346 			if (type.equals(RegistryValueType.LONGLIST)) {
347 				out.print("[LONGLIST] = {") ;
348 				int[] list = key.getLongListValue() ;
349 				for (int i = 0; i < list.length; i++)
350 					out.print("" + list[i] + ",") ;
351 				out.println("}") ;
352 			} else {
353 				out.println("") ;
354 			}
355 		} catch (com.sun.star.uno.Exception e) {
356 			out.println("Exception occurred : ") ;
357 			e.printStackTrace(out) ;
358 		} finally {
359 			key.closeKey() ;
360 		}
361 	}
362 
363 
364 //	public static void compareKeyTrees
365 
366 }
367