KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > coi > tools > os > win > RegistryImpl


1 /*
2  * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
3  *
4  * http://www.izforge.com/izpack/
5  * http://developer.berlios.de/projects/izpack/
6  *
7  * Copyright 2005 Klaus Bartz
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */

21
22 package com.coi.tools.os.win;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27
28 /**
29  * System dependent helper for MS Windows registry handling. This class is only vaild on Windows. It
30  * declares naitve methods which are implemented in COIOSHelper.dll. The native methods uses the
31  * classes RegDataContainer and AccessControlList as in and output. Do not change the getter and
32  * setter methods of them. Do not try to implement a get or setValueACL because it will be nonsense.
33  * In the registry only keys have a ACL. not values.
34  *
35  * @author Klaus Bartz
36  */

37 public class RegistryImpl implements MSWinConstants
38 {
39
40     private static final String JavaDoc DEFAULT_PLACEHOLDER = "__#$&DEFAULT_PLACEHODER_VALUE#$?";
41
42     private int currentRoot = HKEY_CURRENT_USER;
43
44     private List JavaDoc logging = new ArrayList JavaDoc();
45
46     private boolean doLogging = false;
47
48     /**
49      * Creates a new empty RegistryImpl object.
50      */

51     public RegistryImpl()
52     {
53         super();
54     }
55
56     /**
57      * Returns current root.
58      *
59      * @return current root
60      */

61     public int getRoot()
62     {
63         return currentRoot;
64     }
65
66     /**
67      * Sets the root id to the given value.
68      *
69      * @param i root id to be set
70      */

71     public void setRoot(int i)
72     {
73         currentRoot = i;
74     }
75
76     /**
77      * Returns the value of the given value name as RegDataContainer.
78      *
79      * @param key key of the registry entry
80      * @param value value name of the registry entry
81      * @return the value of the given value name as RegDataContainer
82      * @throws NativeLibException
83      */

84     public RegDataContainer getValue(String JavaDoc key, String JavaDoc value) throws NativeLibException
85     {
86         if( key == null)
87             key = "";
88         return (getValue(currentRoot, key, value));
89     }
90
91     /**
92      * Returns the value of the given value name as Object. The real type depends to the type of the
93      * value.
94      *
95      * @param key key of the registry entry
96      * @param value value name of the registry entry
97      * @return the value of the given value name as RegDataContainer
98      * @throws NativeLibException
99      */

100     public Object JavaDoc getValueAsObject(String JavaDoc key, String JavaDoc value) throws NativeLibException
101     {
102         if( key == null)
103             key = "";
104         return (getValue(currentRoot, key, value).getDataAsObject());
105     }
106
107     /**
108      * Returns all sub keys under the given key which is under the current root.
109      *
110      * @param key key for which the sub keys should be detected
111      * @return all sub keys under the given key which is under the current root
112      * @throws NativeLibException
113      */

114     public String JavaDoc[] getSubkeys(String JavaDoc key) throws NativeLibException
115     {
116         if( key == null)
117             key = "";
118         return (getSubkeyNames(currentRoot, key));
119     }
120
121     /**
122      * Returns all value names under the given key which is under the current root.
123      *
124      * @param key key for which the values should be detected
125      * @return all value names under the given key which is under the current root
126      * @throws NativeLibException
127      */

128     public String JavaDoc[] getValueNames(String JavaDoc key) throws NativeLibException
129     {
130         if( key == null)
131             key = "";
132         return (getValueNames(currentRoot, key));
133     }
134
135     /**
136      * Creates the given key under the current root.
137      *
138      * @param key key to be created
139      * @throws NativeLibException
140      */

141     public void createKey(String JavaDoc key) throws NativeLibException
142     {
143         createKey(currentRoot, key);
144     }
145
146     /**
147      * Creates the given key under the given root.
148      * It is possible to declare keys without a sub path.
149      * This is only possible on roots which are no real roots
150      * (e.g. HKEY_CURRENT_USER which is a link to
151      * HKEY_USERS\GUID of current user). Therefore this method
152      * will be raise an exception if root is a real root and
153      * key contains no sub path.
154      *
155      * @param root to be used
156      * @param key key to be created
157      * @throws NativeLibException
158      */

159     public void createKey(int root, String JavaDoc key) throws NativeLibException
160     {
161         int pathEnd = key.lastIndexOf('\\');
162         if( pathEnd > 0 )
163         {
164             String JavaDoc subkey = key.substring(0, pathEnd);
165             if (!exist(root, subkey))
166             { // Create missing sub keys
167
createKey(root, subkey);
168             }
169         }
170         // Create key
171
createKeyN(root, key);
172         RegistryLogItem rli = new RegistryLogItem(RegistryLogItem.CREATED_KEY, root, key, null,
173                 null, null);
174         log(rli);
175
176     }
177
178     /**
179      * Returns whether the given key under the current root exist or not.
180      *
181      * @param key key to be tested
182      * @return true if thekey exist, else false
183      * @throws NativeLibException
184      */

185     public boolean keyExist(String JavaDoc key) throws NativeLibException
186     {
187         return (keyExist(currentRoot, key));
188     }
189
190     /**
191      * Returns whether the given key under the given root exist or not.
192      *
193      * @param root to be used
194      * @param key key to be tested
195      * @return true if thekey exist, else false
196      * @throws NativeLibException
197      */

198     public boolean keyExist(int root, String JavaDoc key) throws NativeLibException
199     {
200         try
201         {
202             return (exist(root, key));
203         }
204         catch (NativeLibException ne)
205         {
206             String JavaDoc em = ne.getLibMessage();
207             if ("functionFailed.RegOpenKeyEx".equals(em)) { return (false); }
208             throw (ne);
209         }
210     }
211
212     /**
213      * Returns whether the given value exist under the current root or not.
214      *
215      * @param key key of the value for which should be tested
216      * @param value value to be tested
217      * @return true if the value exist, else false
218      * @throws NativeLibException
219      */

220     public boolean valueExist(String JavaDoc key, String JavaDoc value) throws NativeLibException
221     {
222         if( key == null)
223             key = "";
224         try
225         {
226             this.getValue(currentRoot, key, value);
227         }
228         catch (NativeLibException ne)
229         {
230             String JavaDoc em = ne.getLibMessage();
231             if ("functionFailed.RegOpenKeyEx".equals(em)
232                     || "functionFailed.RegQueryValueEx".equals(em)) { return (false); }
233             throw (ne);
234         }
235         return (true);
236     }
237
238     /**
239      * Sets the given contents to the given registry value. If a sub key or the registry value does
240      * not exist, it will be created. REG_SZ is used as registry value type.
241      *
242      * @param key the registry key which should be used or created
243      * @param value the registry value into which the contents should be set
244      * @param contents the contents for the value
245      * @throws NativeLibException
246      */

247     public void setValue(String JavaDoc key, String JavaDoc value, String JavaDoc contents) throws NativeLibException
248     {
249
250         setValue(currentRoot, key, value, new RegDataContainer(contents));
251     }
252
253     /**
254      * Sets the given contents to the given registry value. If a sub key or the registry value does
255      * not exist, it will be created. REG_MULTI_SZ is used as registry value type.
256      *
257      * @param key the registry key which should be used or created
258      * @param value the registry value into which the contents should be set
259      * @param contents the contents for the value
260      * @throws NativeLibException
261      */

262     public void setValue(String JavaDoc key, String JavaDoc value, String JavaDoc[] contents) throws NativeLibException
263     {
264
265         setValue(currentRoot, key, value, new RegDataContainer(contents));
266     }
267
268     /**
269      * Sets the given contents to the given registry value. If a sub key or the registry value does
270      * not exist, it will be created. REG_BINARY is used as registry value type.
271      *
272      * @param key the registry key which should be used or created
273      * @param value the registry value into which the contents should be set
274      * @param contents the contents for the value
275      * @throws NativeLibException
276      */

277     public void setValue(String JavaDoc key, String JavaDoc value, byte[] contents) throws NativeLibException
278     {
279
280         setValue(currentRoot, key, value, new RegDataContainer(contents));
281     }
282
283     /**
284      * Sets the given contents to the given registry value. If a sub key or the registry value does
285      * not exist, it will be created. REG_DWORD is used as registry value type.
286      *
287      * @param key the registry key which should be used or created
288      * @param value the registry value into which the contents should be set
289      * @param contents the contents for the value
290      * @throws NativeLibException
291      */

292     public void setValue(String JavaDoc key, String JavaDoc value, long contents) throws NativeLibException
293     {
294         setValue(currentRoot, key, value, new RegDataContainer(contents));
295     }
296
297     /**
298      * Sets the given contents to the given registry value under current root. If a sub key or the
299      * registry value does not exist, it will be created. The used registry value type will be
300      * determined by the type of the RegDataContainer.
301      *
302      * @param key the registry key which should be used or created
303      * @param value the registry value into which the contents should be set
304      * @param contents the contents for the value
305      * @throws NativeLibException
306      */

307     public void setValue(String JavaDoc key, String JavaDoc value, RegDataContainer contents)
308             throws NativeLibException
309     {
310         setValue(currentRoot, key, value, contents);
311     }
312
313     /**
314      * Sets the given contents to the given registry value. If a sub key or the registry value does
315      * not exist, it will be created. The used registry value type will be determined by the type of
316      * the RegDataContainer.
317      *
318      * @param root id for the root of the key
319      * @param key the registry key which should be used or created
320      * @param value the registry value into which the contents should be set
321      * @param contents the contents for the value
322      * @throws NativeLibException
323      */

324     public void setValue(int root, String JavaDoc key, String JavaDoc value, RegDataContainer contents)
325             throws NativeLibException
326     {
327         RegDataContainer oldContents = null;
328         String JavaDoc localValue = value;
329         if( key == null)
330             key = "";
331         if(value == null) // We allow it for the default value...
332
value = "";
333         // May be someone do not like backslashes ...
334
key = key.replace('/', '\\');
335
336         synchronized (logging)
337         {
338             try
339             {
340                 oldContents = getValue(currentRoot, key, value);
341             }
342             catch (NativeLibException ne)
343             {
344                 String JavaDoc em = ne.getLibMessage();
345                 if ("functionFailed.RegOpenKeyEx".equals(em)
346                         || "functionFailed.RegQueryValueEx".equals(em))
347                 {
348                     setValueR(root, key, value, contents);
349                     return;
350                 }
351                 throw (ne);
352             }
353             setValueN(root, key, value, contents);
354             // Add value changing to log list
355
if (value.length() == 0) // The default value ...
356
localValue = DEFAULT_PLACEHOLDER; // Rewind will fail if last
357
// token is
358
// empty.
359

360             RegistryLogItem rli = new RegistryLogItem(RegistryLogItem.CHANGED_VALUE, root, key,
361                     localValue, contents, oldContents);
362             log(rli);
363         }
364     }
365
366     /**
367      * Deletes a key under the current root if exist and it is empty, else throw an exception.
368      *
369      * @param key key to be deleted
370      * @throws NativeLibException
371      */

372     public void deleteKey(String JavaDoc key) throws NativeLibException
373     {
374         deleteKeyL(currentRoot, key);
375     }
376
377     /**
378      * Deletes a key under the current root if it is empty, else do nothing.
379      *
380      * @param key key to be deleted
381      * @throws NativeLibException
382      */

383     public void deleteKeyIfEmpty(String JavaDoc key) throws NativeLibException
384     {
385         deleteKeyIfEmpty(currentRoot, key);
386     }
387
388     /**
389      * Deletes a key if it is empty, else do nothing.
390      *
391      * @param root id for the root of the key
392      * @param key key to be deleted
393      * @throws NativeLibException
394      */

395     public void deleteKeyIfEmpty(int root, String JavaDoc key) throws NativeLibException
396     {
397         if (keyExist(root, key) && isKeyEmpty(root, key)) deleteKeyL(root, key);
398
399     }
400
401     /**
402      * Deletes a value.
403      *
404      * @param key key of the value which should be deleted
405      * @param value value name to be deleted
406      * @throws NativeLibException
407      */

408     public void deleteValue(String JavaDoc key, String JavaDoc value) throws NativeLibException
409     {
410         deleteValueL(currentRoot, key, value);
411     }
412
413     /**
414      * Deletes a key with logging.
415      *
416      * @param root id for the root of the key
417      * @param key key to be deleted
418      * @throws NativeLibException
419      */

420     private void deleteKeyL(int root, String JavaDoc key) throws NativeLibException
421     {
422         RegistryLogItem rli = new RegistryLogItem(RegistryLogItem.REMOVED_KEY, root, key, null,
423                 null, null);
424         log(rli);
425         deleteKeyN(root, key);
426     }
427
428     /**
429      * Deletes a value with logging.
430      *
431      * @param root id for the root of the key
432      * @param key key of the value which should be deleted
433      * @param value value name to be deleted
434      * @throws NativeLibException
435      */

436     private void deleteValueL(int root, String JavaDoc key, String JavaDoc value) throws NativeLibException
437     {
438         if( key == null)
439             key = "";
440         RegDataContainer oldContents = getValue(currentRoot, key, value);
441         RegistryLogItem rli = new RegistryLogItem(RegistryLogItem.REMOVED_VALUE, root, key, value,
442                 null, oldContents);
443         log(rli);
444         deleteValueN(currentRoot, key, value);
445     }
446
447     /**
448      * Rewinds all logged actions.
449      *
450      * @throws IllegalArgumentException
451      * @throws NativeLibException
452      */

453     public void rewind() throws IllegalArgumentException JavaDoc, NativeLibException
454     {
455         synchronized (logging)
456         {
457             Iterator JavaDoc iter = logging.iterator();
458             suspendLogging();
459
460             while (iter.hasNext())
461             {
462                 RegistryLogItem rli = (RegistryLogItem) iter.next();
463                 String JavaDoc rliValueName = (DEFAULT_PLACEHOLDER.equals(rli.getValueName())) ? "" : rli
464                         .getValueName();
465                 switch (rli.getType())
466                 {
467                 case RegistryLogItem.CREATED_KEY:
468                     deleteKeyIfEmpty(rli.getRoot(), rli.getKey());
469                     break;
470                 case RegistryLogItem.REMOVED_KEY:
471                     createKeyN(rli.getRoot(), rli.getKey());
472                     break;
473                 case RegistryLogItem.CREATED_VALUE:
474                     RegDataContainer currentContents = null;
475                     // Delete value only if reg entry exists and is equal to the stored value.
476
try
477                     {
478                         currentContents = getValue(rli.getRoot(), rli.getKey(), rliValueName);
479                     }
480                     catch (NativeLibException nle)
481                     {
482                         break;
483                     }
484                     if (currentContents.equals(rli.getNewValue()))
485                     {
486                         deleteValueN(rli.getRoot(), rli.getKey(), rliValueName);
487                     }
488                     // TODO: what todo if value has changed?
489
break;
490                 case RegistryLogItem.REMOVED_VALUE:
491                     // Set old value only if reg entry not exists.
492
try
493                     {
494                         getValue(rli.getRoot(), rli.getKey(), rliValueName);
495                     }
496                     catch (NativeLibException nle)
497                     {
498                         setValueN(rli.getRoot(), rli.getKey(), rliValueName, rli
499                                 .getOldValue());
500                     }
501                     break;
502                 case RegistryLogItem.CHANGED_VALUE:
503                     // Change to old value only if reg entry exists and equal to
504
// the
505
// stored value.
506
try
507                     {
508                         currentContents = getValue(rli.getRoot(), rli.getKey(), rliValueName);
509                     }
510                     catch (NativeLibException nle)
511                     {
512                         break;
513                     }
514                     if (currentContents.equals(rli.getNewValue()))
515                     {
516                         setValueN(rli.getRoot(), rli.getKey(), rliValueName, rli
517                                 .getOldValue());
518                     }
519                     break;
520                 }
521             }
522         }
523
524     }
525
526     /**
527      * Sets the given contents to the given registry value. If a sub key or the registry value does
528      * not exist, it will be created. The used registry value type will be determined by the type of
529      * the RegDataContainer.
530      *
531      * @param root id for the root of the key
532      * @param key the registry key which should be used or created
533      * @param value the registry value into which the contents should be set
534      * @param contents the contents for the value
535      * @throws NativeLibException
536      */

537     private void setValueR(int root, String JavaDoc key, String JavaDoc value, RegDataContainer contents)
538             throws NativeLibException
539     {
540         String JavaDoc localValue = value;
541         if (!exist(root, key))
542         { // Create missing sub keys
543
createKey(root, key);
544         }
545         // Create value
546
setValueN(root, key, value, contents);
547         // Add value creation to log list
548
if (value.length() == 0) // The default value ...
549
localValue = DEFAULT_PLACEHOLDER; // Rewind will fail if last token
550
// is
551
// empty.
552
StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
553         sb.append("SetValue;").append(Integer.toString(root)).append(";").append(key).append(";")
554                 .append(localValue);
555         RegistryLogItem rli = new RegistryLogItem(RegistryLogItem.CREATED_VALUE, root, key,
556                 localValue, contents, null);
557         log(rli);
558     }
559
560     private native boolean exist(int root, String JavaDoc key) throws NativeLibException;
561
562     private native void createKeyN(int root, String JavaDoc key) throws NativeLibException;
563
564     private native void setValueN(int root, String JavaDoc key, String JavaDoc value, RegDataContainer contents)
565             throws NativeLibException;
566
567     private native RegDataContainer getValue(int root, String JavaDoc key, String JavaDoc value)
568             throws NativeLibException;
569
570     private native void deleteValueN(int root, String JavaDoc key, String JavaDoc value) throws NativeLibException;
571
572     private native void deleteKeyN(int root, String JavaDoc key) throws NativeLibException;
573
574     private native boolean isKeyEmpty(int root, String JavaDoc key) throws NativeLibException;
575
576     private native String JavaDoc[] getSubkeyNames(int root, String JavaDoc key) throws NativeLibException;
577
578     private native String JavaDoc[] getValueNames(int root, String JavaDoc key) throws NativeLibException;
579
580     // Methods which are implemented in the native part but not used yet. To suppress warnings
581
// in Eclipse this methods are commented out. Comment in if needed.
582
// private native int getValueType(int root, String key, String value) throws
583
// NativeLibException;
584
//
585
// private native int getSubkeyCount(int root, String key) throws NativeLibException;
586
//
587
// private native int getValueCount(int root, String key) throws NativeLibException;
588
//
589
// private native String getSubkeyName(int root, String key, int index) throws
590
// NativeLibException;
591
//
592
// private native String getValueName(int root, String key, int index) throws
593
// NativeLibException;
594
//
595
// private native void modifyKeyACL(int root, String key, AccessControlList acl)
596
// throws NativeLibException;
597
//
598
// private native AccessControlList getKeyACL(int root, String key) throws NativeLibException;
599

600     /**
601      * Creates a new (empty) logging list and activates logging.
602      */

603     public void resetLogging()
604     {
605         logging = new ArrayList JavaDoc();
606         activateLogging();
607     }
608
609     /**
610      * Suspends logging.
611      */

612     public void suspendLogging()
613     {
614         doLogging = false;
615     }
616
617     /**
618      * Activates logging.
619      */

620     public void activateLogging()
621     {
622         doLogging = true;
623     }
624
625     /**
626      * Returns a copy of the colected logging informations.
627      *
628      * @return a copy of the colected logging informations
629      */

630     public List JavaDoc getLoggingInfo()
631     {
632         ArrayList JavaDoc retval = new ArrayList JavaDoc(logging.size());
633         Iterator JavaDoc iter = logging.iterator();
634         while (iter.hasNext())
635             try
636             {
637                 retval.add(((RegistryLogItem) iter.next()).clone());
638             }
639             catch (CloneNotSupportedException JavaDoc e)
640             { // Should never be...
641
e.printStackTrace();
642             }
643         return (retval);
644     }
645
646     /**
647      * Copies the contents of the given list of RegistryLogItems to a newly created internal logging
648      * list.
649      *
650      * @param info list containing RegistryLogItems to be used for logging
651      */

652     public void setLoggingInfo(List JavaDoc info)
653     {
654         resetLogging();
655         addLoggingInfo(info);
656     }
657
658     /**
659      * Adds copies of the contents of the given list of RegistryLogItems to the existent internal
660      *
661      * @param info list containing RegistryLogItems to be used for logging logging list.
662      */

663     public void addLoggingInfo(List JavaDoc info)
664     {
665         Iterator JavaDoc iter = info.iterator();
666         while (iter.hasNext())
667             try
668             {
669                 logging.add(((RegistryLogItem) iter.next()).clone());
670             }
671             catch (CloneNotSupportedException JavaDoc e)
672             { // Should never be
673
e.printStackTrace();
674             }
675
676     }
677
678     /**
679      * Adds the given item to the beginning of the logging list if logging is enabled, else do
680      * nothing.
681      *
682      * @param item
683      */

684     private void log(RegistryLogItem item)
685     {
686         if (doLogging && logging != null) logging.add(0, item);
687     }
688
689 }
690
Popular Tags