1 21 22 package com.izforge.izpack.event; 23 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.StringTokenizer ; 27 import java.util.Vector ; 28 29 import net.n3.nanoxml.XMLElement; 30 31 import com.coi.tools.os.win.NativeLibException; 32 import com.izforge.izpack.Pack; 33 import com.izforge.izpack.installer.AutomatedInstallData; 34 import com.izforge.izpack.installer.UninstallData; 35 import com.izforge.izpack.installer.Unpacker; 36 import com.izforge.izpack.util.AbstractUIProgressHandler; 37 import com.izforge.izpack.util.SpecHelper; 38 import com.izforge.izpack.util.VariableSubstitutor; 39 import com.izforge.izpack.util.os.RegistryDefaultHandler; 40 import com.izforge.izpack.util.os.RegistryHandler; 41 import com.izforge.izpack.util.os.WrappedNativeLibException; 42 43 53 public class RegistryInstallerListener extends NativeInstallerListener 54 { 55 56 57 private static final String SPEC_FILE_NAME = "RegistrySpec.xml"; 58 59 private static final String REG_KEY = "key"; 60 61 private static final String REG_VALUE = "value"; 62 63 private static final String REG_ROOT = "root"; 64 65 private static final String REG_BASENAME = "name"; 66 67 private static final String REG_KEYPATH = "keypath"; 68 69 private static final String REG_DWORD = "dword"; 70 71 private static final String REG_STRING = "string"; 72 73 private static final String REG_MULTI = "multi"; 74 75 private static final String REG_BIN = "bin"; 76 77 private static final String REG_DATA = "data"; 78 79 private static final String REG_OVERRIDE = "override"; 80 81 84 public RegistryInstallerListener() 85 { 86 super(true); 87 } 88 89 95 public void beforePacks(AutomatedInstallData idata, Integer npacks, 96 AbstractUIProgressHandler handler) throws Exception 97 { 98 super.beforePacks(idata, npacks, handler); 99 initializeRegistryHandler(idata); 100 } 101 102 108 public void afterPacks(AutomatedInstallData idata, AbstractUIProgressHandler handler) 109 throws Exception 110 { 111 try 112 { 113 RegistryHandler rh = RegistryDefaultHandler.getInstance(); 115 if (rh == null) return; 116 XMLElement uninstallerPack = null; 117 Unpacker.setDiscardInterrupt(true); 119 rh.activateLogging(); 120 if (getSpecHelper().getSpec() != null) 121 { 122 VariableSubstitutor substitutor = new VariableSubstitutor(idata.getVariables()); 123 Iterator iter = idata.selectedPacks.iterator(); 124 uninstallerPack = getSpecHelper().getPackForName("UninstallStuff"); 127 performPack(uninstallerPack, substitutor); 128 129 while (iter != null && iter.hasNext()) 131 { 132 XMLElement pack = getSpecHelper().getPackForName(((Pack) iter.next()).name); 134 performPack(pack, substitutor); 135 136 } 137 } 138 String uninstallSuffix = idata.getVariable("UninstallKeySuffix"); 139 if (uninstallSuffix != null) 140 { 141 rh.setUninstallName(rh.getUninstallName() + " " + uninstallSuffix); 142 } 143 if (uninstallerPack == null) rh.registerUninstallKey(); 145 List info = rh.getLoggingInfo(); 152 if (info != null) 153 UninstallData.getInstance().addAdditionalData("registryEntries", info); 154 155 } 156 catch (Exception e) 157 { 158 if (e instanceof NativeLibException) 159 throw new WrappedNativeLibException(e); 160 else 161 throw e; 162 } 163 } 164 165 171 private void performPack(XMLElement pack, VariableSubstitutor substitutor) throws Exception 172 { 173 if (pack == null) return; 174 Vector regEntries = pack.getChildren(); 176 if (regEntries == null) return; 177 Iterator entriesIter = regEntries.iterator(); 178 while (entriesIter != null && entriesIter.hasNext()) 179 { 180 XMLElement regEntry = (XMLElement) entriesIter.next(); 181 String type = regEntry.getName(); 183 if (type.equalsIgnoreCase(REG_KEY)) 184 { 185 performKeySetting(regEntry, substitutor); 186 } 187 else if (type.equalsIgnoreCase(REG_VALUE)) 188 { 189 performValueSetting(regEntry, substitutor); 190 } 191 else 192 getSpecHelper().parseError(regEntry, 194 "Non-valid type of entry; only 'key' and 'value' are allowed."); 195 196 } 197 198 } 199 200 206 private void performValueSetting(XMLElement regEntry, VariableSubstitutor substitutor) 207 throws Exception 208 { 209 SpecHelper specHelper = getSpecHelper(); 210 String name = specHelper.getRequiredAttribute(regEntry, REG_BASENAME); 211 name = substitutor.substitute(name, null); 212 String keypath = specHelper.getRequiredAttribute(regEntry, REG_KEYPATH); 213 keypath = substitutor.substitute(keypath, null); 214 String root = specHelper.getRequiredAttribute(regEntry, REG_ROOT); 215 int rootId = resolveRoot(regEntry, root, substitutor); 216 217 RegistryHandler rh = RegistryDefaultHandler.getInstance(); 218 if (rh == null) return; 219 220 rh.setRoot(rootId); 221 222 String override = regEntry.getAttribute(REG_OVERRIDE, "true"); 223 if (!"true".equalsIgnoreCase(override)) 224 { 226 if (rh.getValue(keypath, name, null) != null) return; 227 } 228 229 String value = regEntry.getAttribute(REG_DWORD); 230 if (value != null) 231 { value = substitutor.substitute(value, null); 233 rh.setValue(keypath, name, Long.parseLong(value)); 234 return; 235 } 236 value = regEntry.getAttribute(REG_STRING); 237 if (value != null) 238 { value = substitutor.substitute(value, null); 240 rh.setValue(keypath, name, value); 241 return; 242 } 243 Vector values = regEntry.getChildrenNamed(REG_MULTI); 244 if (values != null && !values.isEmpty()) 245 { Iterator multiIter = values.iterator(); 247 String [] multiString = new String [values.size()]; 248 for (int i = 0; multiIter.hasNext(); ++i) 249 { 250 XMLElement element = (XMLElement) multiIter.next(); 251 multiString[i] = specHelper.getRequiredAttribute(element, REG_DATA); 252 multiString[i] = substitutor.substitute(multiString[i], null); 253 } 254 rh.setValue(keypath, name, multiString); 255 return; 256 } 257 values = regEntry.getChildrenNamed(REG_BIN); 258 if (values != null && !values.isEmpty()) 259 { Iterator multiIter = values.iterator(); 262 263 StringBuffer buf = new StringBuffer (); 264 for (int i = 0; multiIter.hasNext(); ++i) 265 { 266 XMLElement element = (XMLElement) multiIter.next(); 267 String tmp = specHelper.getRequiredAttribute(element, REG_DATA); 268 buf.append(tmp); 269 if (!tmp.endsWith(",") && multiIter.hasNext()) buf.append(","); 270 } 271 byte[] bytes = extractBytes(regEntry, substitutor.substitute(buf.toString(), null)); 272 rh.setValue(keypath, name, bytes); 273 return; 274 } 275 specHelper.parseError(regEntry, "No data found."); 276 277 } 278 279 private byte[] extractBytes(XMLElement element, String byteString) throws Exception 280 { 281 StringTokenizer st = new StringTokenizer (byteString, ","); 282 byte[] retval = new byte[st.countTokens()]; 283 int i = 0; 284 while (st.hasMoreTokens()) 285 { 286 byte value = 0; 287 String token = st.nextToken().trim(); 288 try 289 { int tval = Integer.parseInt(token, 16); 291 if (tval < 0 || tval > 0xff) 292 throw new NumberFormatException ("Value out of range."); 293 if (tval > 0x7f) tval -= 0x100; 294 value = (byte) tval; 295 } 296 catch (NumberFormatException nfe) 297 { 298 getSpecHelper() 299 .parseError(element, 300 "Bad entry for REG_BINARY; a byte should be written as 2 digit hexvalue followed by a ','."); 301 } 302 retval[i++] = value; 303 } 304 return (retval); 305 306 } 307 308 314 private void performKeySetting(XMLElement regEntry, VariableSubstitutor substitutor) 315 throws Exception 316 { 317 String keypath = getSpecHelper().getRequiredAttribute(regEntry, REG_KEYPATH); 318 keypath = substitutor.substitute(keypath, null); 319 String root = getSpecHelper().getRequiredAttribute(regEntry, REG_ROOT); 320 int rootId = resolveRoot(regEntry, root, substitutor); 321 RegistryHandler rh = RegistryDefaultHandler.getInstance(); 322 if (rh == null) return; 323 rh.setRoot(rootId); 324 if (!rh.keyExist(keypath)) rh.createKey(keypath); 325 } 326 327 private int resolveRoot(XMLElement regEntry, String root, VariableSubstitutor substitutor) 328 throws Exception 329 { 330 String root1 = substitutor.substitute(root, null); 331 Integer tmp = (Integer ) RegistryHandler.ROOT_KEY_MAP.get(root1); 332 if (tmp != null) return (tmp.intValue()); 333 getSpecHelper().parseError(regEntry, "Unknown value (" + root1 + ")for registry root."); 334 return 0; 335 } 336 337 private void initializeRegistryHandler(AutomatedInstallData idata) throws Exception 338 { 339 RegistryHandler rh = RegistryDefaultHandler.getInstance(); 340 if (rh == null) return; 341 rh.verify(idata); 342 getSpecHelper().readSpec(SPEC_FILE_NAME); 343 } 344 345 } 346 | Popular Tags |