001/* 002 * IzPack - Copyright 2001-2005 Julien Ponge, All Rights Reserved. 003 * 004 * http://www.izforge.com/izpack/ 005 * http://developer.berlios.de/projects/izpack/ 006 * 007 * Copyright 2005 Klaus Bartz 008 * 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 */ 021 022package com.coi.tools.os.win; 023 024import java.util.ArrayList; 025import java.util.HashMap; 026import java.util.Iterator; 027import java.util.MissingResourceException; 028import java.util.ResourceBundle; 029 030/** 031 * A exception class which will be used from the native part of system dependent classes to signal 032 * exceptions. The native methods writes only symbolic error messages, the language dependant 033 * mapping will be done in this class. 034 * 035 * @author Klaus Bartz 036 * 037 */ 038public class NativeLibException extends Exception 039{ 040 041 private static final long serialVersionUID = 3257002172494721080L; 042 043 /** Map of founded resource bundles which contains the localized error messages. */ 044 private final static HashMap messageResourceBundles = new HashMap(); 045 046 /** Internal error as number. */ 047 private int libErr; 048 049 /** OS error as number. */ 050 private int osErr; 051 052 /** Internal error message; contains most the symbolic error name. */ 053 private String libErrString; 054 055 /** OS error string; if possible localized. */ 056 private String osErrString; 057 058 /** Additional arguments. */ 059 private ArrayList args = new ArrayList(); 060 061 static 062 { 063 // add the first resource bundle 064 addResourceBundle("com.coi.tools.os.win.resources.NativeLibErr"); 065 } 066 067 /** 068 * Adds a resource bundle which contains localized error messages. The bundlePath should contain 069 * a string with which the bundle is loadable with ResourceBundle.getBundle, may be the full 070 * class path to a ListResourceBundle. The localize is done by getBundle, therefore the path 071 * should not contain the locale substring. At a call to getMessage the bundle is searched with 072 * the libErrString as key. If it exist, the value of it is used by getMessage, else the 073 * libErrString self. 074 * 075 * @param bundlePath path of bundle without locale 076 */ 077 public static void addResourceBundle(String bundlePath) 078 { 079 ResourceBundle bd = null; 080 if (messageResourceBundles.containsKey(bundlePath)) return; 081 try 082 { 083 bd = ResourceBundle.getBundle(bundlePath); 084 } 085 catch (MissingResourceException mre) 086 { 087 mre.printStackTrace(); 088 } 089 messageResourceBundles.put(bundlePath, bd); 090 return; 091 092 } 093 094 /** 095 * The constructor. 096 */ 097 public NativeLibException() 098 { 099 super(); 100 } 101 102 /** 103 * Creates a NativeLibException with the given message. 104 * 105 * @param message to be used 106 */ 107 public NativeLibException(String message) 108 { 109 super(message); 110 } 111 112 /** 113 * Creates a NativeLibException with the given cause. 114 * 115 * @param cause to be used 116 */ 117 public NativeLibException(Throwable cause) 118 { 119 super(cause); 120 } 121 122 /** 123 * Creates a NativeLibException with the given message and cause. 124 * 125 * @param message message to be used 126 * @param cause cause to be used 127 */ 128 public NativeLibException(String message, Throwable cause) 129 { 130 super(message, cause); 131 } 132 133 /** 134 * Creates a NativeLibException with the given values. 135 * 136 * @param libErr identifier of the internal handled error 137 * @param osErr system error number 138 * @param libString message for the internal handled error 139 * @param osString system error message 140 */ 141 public NativeLibException(int libErr, int osErr, String libString, String osString) 142 { 143 super(); 144 this.libErr = libErr; 145 this.osErr = osErr; 146 libErrString = libString; 147 osErrString = osString; 148 } 149 150 /* 151 * (non-Javadoc) 152 * 153 * @see java.lang.Throwable#getMessage() 154 */ 155 public String getMessage() 156 { 157 StringBuffer retval = new StringBuffer(); 158 boolean next = false; 159 if (libErrString != null) 160 { 161 retval.append(getLocalizedLibMessage()); 162 next = true; 163 } 164 else if (libErr != 0) 165 { 166 if (next) retval.append("\n"); 167 next = true; 168 retval.append(getMsg("libErrNumber." + Integer.toString(libErr))); 169 } 170 if (osErr != 0) 171 { 172 if (next) retval.append("\n"); 173 next = true; 174 retval.append(getMsg("libInternal.OsErrNumPraefix")).append(Integer.toString(osErr)); 175 } 176 if (osErrString != null) 177 { 178 if (next) retval.append("\n"); 179 next = true; 180 // Message self should be localized in the native part 181 retval.append(getMsg("libInternal.OsErrStringPraefix")).append(getOsMessage()); 182 } 183 if (retval.length() > 0) return (reviseMsgWithArgs(retval.toString())); 184 return null; 185 } 186 187 /** 188 * Returns the number of the internal handled error. 189 * 190 * @return the number of the internal handled error 191 */ 192 public int getLibErr() 193 { 194 return libErr; 195 } 196 197 /** 198 * Returns the message of the internal handled error. 199 * 200 * @return the messager of the internal handled error 201 */ 202 public String getLibMessage() 203 { 204 return libErrString; 205 } 206 207 /** 208 * Returns the localized message of the internal handled error. 209 * 210 * @return the localized message of the internal handled error 211 */ 212 public String getLocalizedLibMessage() 213 { 214 return (getMsg(libErrString)); 215 } 216 217 /** 218 * Returns the number of the system error. 219 * 220 * @return the number of the system error 221 */ 222 public int getOsErr() 223 { 224 return (osErr); 225 } 226 227 /** 228 * Returns the message of the system error. 229 * 230 * @return the messager of the system error 231 */ 232 public String getOsMessage() 233 { 234 return (osErrString); 235 } 236 237 /** 238 * Adds a string to the internal argument list. 239 * 240 * @param arg string to be added to the internal argument list 241 */ 242 public void addArgument(String arg) 243 { 244 args.add(arg); 245 } 246 247 /** 248 * Returns the internal argument list. 249 * 250 * @return the internal argument list 251 */ 252 public ArrayList getArguments() 253 { 254 return (args); 255 } 256 257 public String reviseMsgWithArgs(String msg) 258 { 259 for (int i = 0; i < args.size(); ++i) 260 { 261 String key = "{" + Integer.toString(i) + "}"; 262 msg = replaceString(msg, key, (String) args.get(i)); 263 } 264 return (msg); 265 } 266 267 /** 268 * Searches the resource bundles for a string which coresponds to the given string as key. 269 * 270 * @param s string which should be used as keys for the resource bundle 271 * @return the founded message as int value 272 */ 273 274 private String getMsg(String s) 275 { 276 Iterator it = messageResourceBundles.values().iterator(); 277 while (it.hasNext()) 278 { 279 try 280 { 281 return (((ResourceBundle) it.next()).getString(s)); 282 } 283 catch (MissingResourceException missingresourceexception) 284 { // do not throw, else look in next bundle. 285 ; 286 } 287 } 288 return (s); 289 } 290 291 /** 292 * Returns a string resulting from replacing all occurrences of what in this string with with. 293 * In opposite to the String.replaceAll method this method do not use regular expression or 294 * other methods which are only available in JRE 1.4 and later. 295 * 296 * @param destination string for which the replacing should be performed 297 * @param what what string should be replaced 298 * @param with with what string what should be replaced 299 * @return a new String object if what was found in the given string, else the given string self 300 */ 301 private static String replaceString(String destination, String what, String with) 302 { 303 if (destination.indexOf(what) >= 0) 304 { // what found, with (placeholder) not included in destination -> 305 // perform changing. 306 StringBuffer buf = new StringBuffer(); 307 int last = 0; 308 int current = destination.indexOf(what); 309 int whatLength = what.length(); 310 while (current >= 0) 311 { // Do not use Methods from JRE 1.4 and higher ... 312 if (current > 0) buf.append(destination.substring(last, current)); 313 buf.append(with); 314 last = current + whatLength; 315 current = destination.indexOf(what, last); 316 } 317 if (destination.length() > last) buf.append(destination.substring(last)); 318 return buf.toString(); 319 } 320 return destination; 321 } 322 323}