1 /* |
1 /* |
2 * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
25 |
25 |
26 package javax.xml.transform; |
26 package javax.xml.transform; |
27 |
27 |
28 import java.lang.reflect.Method; |
28 import java.lang.reflect.Method; |
29 import java.lang.reflect.InvocationTargetException; |
29 import java.lang.reflect.InvocationTargetException; |
|
30 import java.security.AccessControlContext; |
|
31 import java.security.AccessController; |
|
32 import java.security.CodeSigner; |
|
33 import java.security.CodeSource; |
|
34 import java.security.PermissionCollection; |
|
35 import java.security.Permissions; |
|
36 import java.security.PrivilegedAction; |
|
37 import java.security.ProtectionDomain; |
|
38 import java.util.Objects; |
30 |
39 |
31 /** |
40 /** |
32 * This class specifies an exceptional condition that occured |
41 * This class specifies an exceptional condition that occurred |
33 * during the transformation process. |
42 * during the transformation process. |
34 * |
43 * |
35 * @since 1.4 |
44 * @since 1.4 |
36 */ |
45 */ |
37 public class TransformerException extends Exception { |
46 public class TransformerException extends Exception { |
38 |
47 |
39 /** Field locator specifies where the error occured */ |
48 /** Field locator specifies where the error occurred */ |
40 SourceLocator locator; |
49 SourceLocator locator; |
41 |
50 |
42 /** |
51 /** |
43 * Method getLocator retrieves an instance of a SourceLocator |
52 * Method getLocator retrieves an instance of a SourceLocator |
44 * object that specifies where an error occured. |
53 * object that specifies where an error occurred. |
45 * |
54 * |
46 * @return A SourceLocator object, or null if none was specified. |
55 * @return A SourceLocator object, or null if none was specified. |
47 */ |
56 */ |
48 public SourceLocator getLocator() { |
57 public SourceLocator getLocator() { |
49 return locator; |
58 return this.locator; |
50 } |
59 } |
51 |
60 |
52 /** |
61 /** |
53 * Method setLocator sets an instance of a SourceLocator |
62 * Method setLocator sets an instance of a SourceLocator |
54 * object that specifies where an error occured. |
63 * object that specifies where an error occurred. |
55 * |
64 * |
56 * @param location A SourceLocator object, or null to clear the location. |
65 * @param location A SourceLocator object, or null to clear the location. |
57 */ |
66 */ |
58 public void setLocator(SourceLocator location) { |
67 public void setLocator(SourceLocator location) { |
59 locator = location; |
68 this.locator = location; |
60 } |
69 } |
61 |
70 |
62 /** Field containedException specifies a wrapped exception. May be null. */ |
71 /** Field containedException specifies a wrapped exception. May be null. */ |
63 Throwable containedException; |
72 Throwable containedException; |
64 |
73 |
74 |
83 |
75 /** |
84 /** |
76 * Returns the cause of this throwable or <code>null</code> if the |
85 * Returns the cause of this throwable or <code>null</code> if the |
77 * cause is nonexistent or unknown. (The cause is the throwable that |
86 * cause is nonexistent or unknown. (The cause is the throwable that |
78 * caused this throwable to get thrown.) |
87 * caused this throwable to get thrown.) |
79 */ |
88 * @return the cause, or null if unknown |
|
89 */ |
|
90 @Override |
80 public Throwable getCause() { |
91 public Throwable getCause() { |
81 |
92 |
82 return ((containedException == this) |
93 return ((containedException == this) |
83 ? null |
94 ? null |
84 : containedException); |
95 : containedException); |
106 * @throws IllegalStateException if this throwable was |
117 * @throws IllegalStateException if this throwable was |
107 * created with {@link #TransformerException(Throwable)} or |
118 * created with {@link #TransformerException(Throwable)} or |
108 * {@link #TransformerException(String,Throwable)}, or this method has already |
119 * {@link #TransformerException(String,Throwable)}, or this method has already |
109 * been called on this throwable. |
120 * been called on this throwable. |
110 */ |
121 */ |
|
122 @Override |
111 public synchronized Throwable initCause(Throwable cause) { |
123 public synchronized Throwable initCause(Throwable cause) { |
112 |
124 |
113 // TransformerException doesn't set its cause (probably |
125 // TransformerException doesn't set its cause (probably |
114 // because it predates initCause()) - and we may not want |
126 // because it predates initCause()) - and we may not want |
115 // to change this since Exceptions are serializable... |
127 // to change this since Exceptions are serializable... |
134 * Create a new TransformerException. |
146 * Create a new TransformerException. |
135 * |
147 * |
136 * @param message The error or warning message. |
148 * @param message The error or warning message. |
137 */ |
149 */ |
138 public TransformerException(String message) { |
150 public TransformerException(String message) { |
139 |
151 this(message, null, null); |
140 super(message); |
|
141 |
|
142 this.containedException = null; |
|
143 this.locator = null; |
|
144 } |
152 } |
145 |
153 |
146 /** |
154 /** |
147 * Create a new TransformerException wrapping an existing exception. |
155 * Create a new TransformerException wrapping an existing exception. |
148 * |
156 * |
149 * @param e The exception to be wrapped. |
157 * @param e The exception to be wrapped. |
150 */ |
158 */ |
151 public TransformerException(Throwable e) { |
159 public TransformerException(Throwable e) { |
152 |
160 this(null, null, e); |
153 super(e.toString()); |
|
154 |
|
155 this.containedException = e; |
|
156 this.locator = null; |
|
157 } |
161 } |
158 |
162 |
159 /** |
163 /** |
160 * Wrap an existing exception in a TransformerException. |
164 * Wrap an existing exception in a TransformerException. |
161 * |
165 * |
165 * @param message The error or warning message, or null to |
169 * @param message The error or warning message, or null to |
166 * use the message from the embedded exception. |
170 * use the message from the embedded exception. |
167 * @param e Any exception |
171 * @param e Any exception |
168 */ |
172 */ |
169 public TransformerException(String message, Throwable e) { |
173 public TransformerException(String message, Throwable e) { |
170 |
174 this(message, null, e); |
171 super(((message == null) || (message.length() == 0)) |
|
172 ? e.toString() |
|
173 : message); |
|
174 |
|
175 this.containedException = e; |
|
176 this.locator = null; |
|
177 } |
175 } |
178 |
176 |
179 /** |
177 /** |
180 * Create a new TransformerException from a message and a Locator. |
178 * Create a new TransformerException from a message and a Locator. |
181 * |
179 * |
185 * |
183 * |
186 * @param message The error or warning message. |
184 * @param message The error or warning message. |
187 * @param locator The locator object for the error or warning. |
185 * @param locator The locator object for the error or warning. |
188 */ |
186 */ |
189 public TransformerException(String message, SourceLocator locator) { |
187 public TransformerException(String message, SourceLocator locator) { |
190 |
188 this(message, locator, null); |
191 super(message); |
|
192 |
|
193 this.containedException = null; |
|
194 this.locator = locator; |
|
195 } |
189 } |
196 |
190 |
197 /** |
191 /** |
198 * Wrap an existing exception in a TransformerException. |
192 * Wrap an existing exception in a TransformerException. |
199 * |
193 * |
202 * @param locator The locator object for the error or warning. |
196 * @param locator The locator object for the error or warning. |
203 * @param e Any exception |
197 * @param e Any exception |
204 */ |
198 */ |
205 public TransformerException(String message, SourceLocator locator, |
199 public TransformerException(String message, SourceLocator locator, |
206 Throwable e) { |
200 Throwable e) { |
207 |
201 super(((message == null) || (message.length() == 0)) |
208 super(message); |
202 ? ((e == null) ? "" : e.toString()) |
|
203 : message); |
209 |
204 |
210 this.containedException = e; |
205 this.containedException = e; |
211 this.locator = locator; |
206 this.locator = locator; |
212 } |
207 } |
213 |
208 |
217 * |
212 * |
218 * @return A <code>String</code> representing the error message with |
213 * @return A <code>String</code> representing the error message with |
219 * location information appended. |
214 * location information appended. |
220 */ |
215 */ |
221 public String getMessageAndLocation() { |
216 public String getMessageAndLocation() { |
222 |
217 StringBuilder sbuffer = new StringBuilder(); |
223 StringBuffer sbuffer = new StringBuffer(); |
218 sbuffer.append(Objects.toString(super.getMessage(), "")); |
224 String message = super.getMessage(); |
219 sbuffer.append(Objects.toString(getLocationAsString(), "")); |
225 |
220 |
226 if (null != message) { |
221 return sbuffer.toString(); |
227 sbuffer.append(message); |
222 } |
228 } |
223 |
229 |
224 /** |
230 if (null != locator) { |
225 * Get the location information as a string. |
231 String systemID = locator.getSystemId(); |
226 * |
232 int line = locator.getLineNumber(); |
227 * @return A string with location info, or null |
233 int column = locator.getColumnNumber(); |
228 * if there is no location information. |
|
229 */ |
|
230 public String getLocationAsString() { |
|
231 if (locator == null) { |
|
232 return null; |
|
233 } |
|
234 |
|
235 if (System.getSecurityManager() == null) { |
|
236 return getLocationString(); |
|
237 } else { |
|
238 return AccessController.doPrivileged((PrivilegedAction<String>) () -> |
|
239 getLocationString(), |
|
240 new AccessControlContext(new ProtectionDomain[] {getNonPrivDomain()})); |
|
241 } |
|
242 } |
|
243 |
|
244 /** |
|
245 * Constructs the location string. |
|
246 * @return the location string |
|
247 */ |
|
248 private String getLocationString() { |
|
249 if (locator == null) { |
|
250 return null; |
|
251 } |
|
252 |
|
253 StringBuilder sbuffer = new StringBuilder(); |
|
254 String systemID = locator.getSystemId(); |
|
255 int line = locator.getLineNumber(); |
|
256 int column = locator.getColumnNumber(); |
234 |
257 |
235 if (null != systemID) { |
258 if (null != systemID) { |
236 sbuffer.append("; SystemID: "); |
259 sbuffer.append("; SystemID: "); |
237 sbuffer.append(systemID); |
260 sbuffer.append(systemID); |
238 } |
261 } |
244 |
267 |
245 if (0 != column) { |
268 if (0 != column) { |
246 sbuffer.append("; Column#: "); |
269 sbuffer.append("; Column#: "); |
247 sbuffer.append(column); |
270 sbuffer.append(column); |
248 } |
271 } |
249 } |
|
250 |
|
251 return sbuffer.toString(); |
|
252 } |
|
253 |
|
254 /** |
|
255 * Get the location information as a string. |
|
256 * |
|
257 * @return A string with location info, or null |
|
258 * if there is no location information. |
|
259 */ |
|
260 public String getLocationAsString() { |
|
261 |
|
262 if (null != locator) { |
|
263 StringBuffer sbuffer = new StringBuffer(); |
|
264 String systemID = locator.getSystemId(); |
|
265 int line = locator.getLineNumber(); |
|
266 int column = locator.getColumnNumber(); |
|
267 |
|
268 if (null != systemID) { |
|
269 sbuffer.append("; SystemID: "); |
|
270 sbuffer.append(systemID); |
|
271 } |
|
272 |
|
273 if (0 != line) { |
|
274 sbuffer.append("; Line#: "); |
|
275 sbuffer.append(line); |
|
276 } |
|
277 |
|
278 if (0 != column) { |
|
279 sbuffer.append("; Column#: "); |
|
280 sbuffer.append(column); |
|
281 } |
|
282 |
272 |
283 return sbuffer.toString(); |
273 return sbuffer.toString(); |
284 } else { |
|
285 return null; |
|
286 } |
|
287 } |
274 } |
288 |
275 |
289 /** |
276 /** |
290 * Print the the trace of methods from where the error |
277 * Print the the trace of methods from where the error |
291 * originated. This will trace all nested exception |
278 * originated. This will trace all nested exception |
292 * objects, as well as this object. |
279 * objects, as well as this object. |
293 */ |
280 */ |
|
281 @Override |
294 public void printStackTrace() { |
282 public void printStackTrace() { |
295 printStackTrace(new java.io.PrintWriter(System.err, true)); |
283 printStackTrace(new java.io.PrintWriter(System.err, true)); |
296 } |
284 } |
297 |
285 |
298 /** |
286 /** |
299 * Print the the trace of methods from where the error |
287 * Print the the trace of methods from where the error |
300 * originated. This will trace all nested exception |
288 * originated. This will trace all nested exception |
301 * objects, as well as this object. |
289 * objects, as well as this object. |
302 * @param s The stream where the dump will be sent to. |
290 * @param s The stream where the dump will be sent to. |
303 */ |
291 */ |
|
292 @Override |
304 public void printStackTrace(java.io.PrintStream s) { |
293 public void printStackTrace(java.io.PrintStream s) { |
305 printStackTrace(new java.io.PrintWriter(s)); |
294 printStackTrace(new java.io.PrintWriter(s)); |
306 } |
295 } |
307 |
296 |
308 /** |
297 /** |
309 * Print the the trace of methods from where the error |
298 * Print the the trace of methods from where the error |
310 * originated. This will trace all nested exception |
299 * originated. This will trace all nested exception |
311 * objects, as well as this object. |
300 * objects, as well as this object. |
312 * @param s The writer where the dump will be sent to. |
301 * @param s The writer where the dump will be sent to. |
313 */ |
302 */ |
|
303 @Override |
314 public void printStackTrace(java.io.PrintWriter s) { |
304 public void printStackTrace(java.io.PrintWriter s) { |
315 |
305 |
316 if (s == null) { |
306 if (s == null) { |
317 s = new java.io.PrintWriter(System.err, true); |
307 s = new java.io.PrintWriter(System.err, true); |
318 } |
308 } |
356 break; |
346 break; |
357 } |
347 } |
358 } else { |
348 } else { |
359 exception = null; |
349 exception = null; |
360 } |
350 } |
361 } catch (InvocationTargetException ite) { |
351 } catch (InvocationTargetException | IllegalAccessException |
362 exception = null; |
352 | NoSuchMethodException e) { |
363 } catch (IllegalAccessException iae) { |
|
364 exception = null; |
|
365 } catch (NoSuchMethodException nsme) { |
|
366 exception = null; |
353 exception = null; |
367 } |
354 } |
368 } |
355 } |
369 } finally { |
356 } finally { |
370 // ensure output is written |
357 // ensure output is written |
371 s.flush(); |
358 s.flush(); |
372 } |
359 } |
373 } |
360 } |
|
361 |
|
362 /** |
|
363 * Creates a ProtectionDomain that has no permission. |
|
364 * @return a ProtectionDomain |
|
365 */ |
|
366 private ProtectionDomain getNonPrivDomain() { |
|
367 CodeSource nullSource = new CodeSource(null, (CodeSigner[]) null); |
|
368 PermissionCollection noPermission = new Permissions(); |
|
369 return new ProtectionDomain(nullSource, noPermission); |
374 } |
370 } |
|
371 } |