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