KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > bridge > ExternalResourcesTest


1 /*
2
3    Copyright 2002-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.bridge;
19
20 import java.io.File JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.net.MalformedURLException JavaDoc;
23 import java.net.URL JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25 import java.util.Vector JavaDoc;
26
27 import org.w3c.dom.Document JavaDoc;
28 import org.w3c.dom.Element JavaDoc;
29 import org.w3c.dom.Node JavaDoc;
30
31 import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
32 import org.apache.batik.gvt.GraphicsNode;
33 import org.apache.batik.test.AbstractTest;
34 import org.apache.batik.test.DefaultTestReport;
35 import org.apache.batik.test.TestReport;
36 import org.apache.batik.util.ParsedURL;
37 import org.apache.batik.util.XMLResourceDescriptor;
38
39 /**
40  * This test validates that SecurityExceptions are generated when
41  * the user is trying the access external resources and the UserAgent
42  * disallows that.
43  *
44  * In the following, 'unsecure' means an external resource coming from
45  * a different location than the file referencing it.
46  *
47  * This test works with an SVG file containing an unsecure stylesheet
48  * and a set of unsecure elements of all kinds, such as <image>
49  * <use> or <feImage>. All these elements are defined
50  * in a defs section. The test tries to load the document and validates
51  * that a SecurityException is thrown (because of the unsecure
52  * stylesheet). Then, the test iterates over the various unsecure
53  * elements, inserting them into the document outside the defs
54  * section, which should result in a SecurityException in each case.
55  *
56  * There is a property (secure) to have the test work the opposite
57  * way and check that no SecurityException is thrown if access
58  * to external resources is allowed.
59  *
60  * @author <a HREF="mailto:vhardy@apache.org">Vincent Hardy</a>
61  * @version $Id: ExternalResourcesTest.java,v 1.6 2004/08/18 07:16:38 vhardy Exp $
62  */

63
64 public class ExternalResourcesTest extends AbstractTest
65     implements ErrorConstants {
66     /**
67      * Error when the input file cannot be loaded into a
68      * Document object
69      * {0} = IOException message
70      */

71     public static final String JavaDoc ERROR_CANNOT_LOAD_SVG_DOCUMENT
72         = "ExternalResourcesTest.error.cannot.load.svg.document";
73
74     /**
75      * Error while processing the document
76      * {0} = BridgeException message
77      */

78     public static final String JavaDoc ERROR_WHILE_PROCESSING_SVG_DOCUMENT
79         = "ExternalResourcesTest.error.while.processing.svg.document";
80
81     /**
82      * Error: an expected exception was not thrown
83      * {0} = List of ids for which the exception was not thrown
84      */

85     public static final String JavaDoc ERROR_UNTHROWN_SECURITY_EXCEPTIONS
86         = "ExternalResourcesTest.error.unthrown.security.exceptions";
87
88     /**
89      * Error: an unexpected exception was thrown
90      * {0} = List of ids for which an exception was thrown
91      */

92     public static final String JavaDoc ERROR_THROWN_SECURITY_EXCEPTIONS
93         = "ExternalResourcesTest.error.thrown.security.exceptions";
94
95     /**
96      * Error when the insertion point cannot be found in the
97      * test document
98      * {0} = insertion point id
99      */

100     public static final String JavaDoc ERROR_NO_INSERTION_POINT_IN_DOCUMENT
101         = "ExternalResourceTest.error.no.insertion.point.in.document";
102
103     /**
104      * Error when the test could not find a list of ids for testing
105      */

106     public static final String JavaDoc ERROR_NO_ID_LIST
107         = "ExternalResourceTest.error.no.id.list";
108
109     /**
110      * Error when one of the target id cannot be found
111      * {0} = id which was not found
112      */

113     public static final String JavaDoc ERROR_TARGET_ID_NOT_FOUND
114         = "ExternalResourcesTest.error.target.id.not.found";
115
116     /**
117      * Entry describing the error
118      */

119     public static final String JavaDoc ENTRY_KEY_ERROR_DESCRIPTION
120         = "ExternalResourcesTest.entry.key.error.description";
121
122     public static final String JavaDoc ENTRY_KEY_INSERTION_POINT_ID
123         = "ExternalResourcesTest.entry.key.insertion.point.id";
124
125     public static final String JavaDoc ENTRY_KEY_TARGET_ID
126         = "ExternalResourcesTest.entry.target.id";
127
128     public static final String JavaDoc ENTRY_KEY_EXPECTED_EXCEPTION_ON
129         = "ExternalResourcesTest.entry.key.expected.exception.on";
130
131     public static final String JavaDoc ENTRY_KEY_UNEXPECTED_EXCEPTION_ON
132         = "ExternalResourcesTest.entry.key.unexpected.exception.on";
133
134     /**
135      * Pseudo id for the external stylesheet test
136      */

137     public static final String JavaDoc EXTERNAL_STYLESHEET_ID
138         = "external-stylesheet";
139
140     /**
141      * Test Namespace
142      */

143     public static final String JavaDoc testNS = "http://xml.apache.org/batik/test";
144
145     /**
146      * Id of the element where unsecure content is inserted
147      */

148     public static final String JavaDoc INSERTION_POINT_ID = "insertionPoint";
149
150     /**
151      * Location of test files in filesystem.
152      */

153     public static final String JavaDoc FILE_DIR =
154         "test-resources/org/apache/batik/bridge/";
155     /**
156      * Controls whether the test works in secure mode or not
157      */

158     protected boolean secure = true;
159
160     String JavaDoc svgURL;
161
162     public void setId(String JavaDoc id){
163         super.setId(id);
164         String JavaDoc file = id;
165         int idx = file.indexOf('.');
166         if (idx != -1) {
167             file = file.substring(0,idx);
168         }
169         svgURL = resolveURL(FILE_DIR + file + ".svg");
170     }
171
172     public Boolean JavaDoc getSecure(){
173         return new Boolean JavaDoc(secure);
174     }
175
176     public void setSecure(Boolean JavaDoc secure) {
177         this.secure = secure.booleanValue();
178     }
179
180     /**
181      * Resolves the input string as follows.
182      * + First, the string is interpreted as a file description.
183      * If the file exists, then the file name is turned into
184      * a URL.
185      * + Otherwise, the string is supposed to be a URL. If it
186      * is an invalid URL, an IllegalArgumentException is thrown.
187      */

188     protected String JavaDoc resolveURL(String JavaDoc url){
189         // Is url a file?
190
File JavaDoc f = (new File JavaDoc(url)).getAbsoluteFile();
191         if(f.getParentFile().exists()){
192             try{
193                 return f.toURL().toString();
194             }catch(MalformedURLException JavaDoc e){
195                 throw new IllegalArgumentException JavaDoc();
196             }
197         }
198         
199         // url is not a file. It must be a regular URL...
200
try{
201             return (new URL JavaDoc(url)).toString();
202         }catch(MalformedURLException JavaDoc e){
203             throw new IllegalArgumentException JavaDoc(url);
204         }
205     }
206
207     /**
208      * This test uses a list of ids found in the test document. These ids reference
209      * elements found in a defs section. For each such element, the test will
210      * attempt to insert the target id at a given insertion point. That insertion
211      * should cause a SecurityException. If so, the test passes. Otherwise, the test
212      * will fail
213      */

214     public TestReport runImpl() throws Exception JavaDoc{
215         DefaultTestReport report
216             = new DefaultTestReport(this);
217
218         //
219
// First step:
220
//
221
// Load the input SVG into a Document object
222
//
223
String JavaDoc parserClassName = XMLResourceDescriptor.getXMLParserClassName();
224         SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parserClassName);
225         Document JavaDoc doc = null;
226
227         try {
228             doc = f.createDocument(svgURL);
229         } catch(IOException JavaDoc e){
230             report.setErrorCode(ERROR_CANNOT_LOAD_SVG_DOCUMENT);
231             report.addDescriptionEntry(ENTRY_KEY_ERROR_DESCRIPTION,
232                                        e.getMessage());
233             report.setPassed(false);
234             return report;
235         } catch(Exception JavaDoc e){
236             report.setErrorCode(ERROR_CANNOT_LOAD_SVG_DOCUMENT);
237             report.addDescriptionEntry(ENTRY_KEY_ERROR_DESCRIPTION,
238                                        e.getMessage());
239             report.setPassed(false);
240             return report;
241         }
242
243         Vector JavaDoc failures = new Vector JavaDoc();
244
245         //
246
// Do an initial processing to validate that the external
247
// stylesheet causes a SecurityException
248
//
249
MyUserAgent userAgent = buildUserAgent();
250         GVTBuilder builder = new GVTBuilder();
251         BridgeContext ctx = new BridgeContext(userAgent);
252         ctx.setDynamic(true);
253
254         // We expect either a SecurityException or a BridgeException
255
// with ERR_URI_UNSECURE.
256
Throwable JavaDoc th = null;
257         try {
258             GraphicsNode gn = builder.build(ctx, doc);
259             gn.getBounds();
260             th = userAgent.getDisplayError();
261         } catch (BridgeException e){
262             th = e;
263         } catch (SecurityException JavaDoc e) {
264             th = e;
265         } catch (Throwable JavaDoc t) {
266             th = t;
267         }
268         if (th == null) {
269             if (secure)
270                 failures.addElement(EXTERNAL_STYLESHEET_ID);
271         } else if (th instanceof SecurityException JavaDoc) {
272             if (!secure)
273                 failures.addElement(EXTERNAL_STYLESHEET_ID);
274         } else if (th instanceof BridgeException) {
275             BridgeException be = (BridgeException)th;
276             if (!secure ||
277                 (secure && !ERR_URI_UNSECURE.equals(be.getCode()))) {
278                 report.setErrorCode(ERROR_WHILE_PROCESSING_SVG_DOCUMENT);
279                 report.addDescriptionEntry(ENTRY_KEY_ERROR_DESCRIPTION,
280                                            be.getMessage());
281                 report.setPassed(false);
282                 return report;
283             }
284         }
285         
286         //
287
// Remove the stylesheet from the document
288
//
289
Node JavaDoc child = doc.getFirstChild();
290         Node JavaDoc next = null;
291         while (child != null) {
292             next = child.getNextSibling();
293             if (child.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
294                 doc.removeChild(child);
295             }
296             child = next;
297         }
298
299         //
300
// Now, get the list of ids to be checked
301
//
302
Element JavaDoc root = doc.getDocumentElement();
303         String JavaDoc idList = root.getAttributeNS(testNS, "targetids");
304         if (idList == null || "".equals(idList)) {
305             report.setErrorCode(ERROR_NO_ID_LIST);
306             report.setPassed(false);
307             return report;
308         }
309
310         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(idList, ",");
311         String JavaDoc[] ids = new String JavaDoc[st.countTokens()];
312         for (int i=0; i<ids.length; i++) {
313             ids[i] = st.nextToken().toString().trim();
314         }
315
316         for (int i=0; i<ids.length; i++) {
317             String JavaDoc id = ids[i];
318             userAgent = buildUserAgent();
319             builder = new GVTBuilder();
320             ctx = new BridgeContext(userAgent);
321             ctx.setDynamic(true);
322
323             Document JavaDoc cloneDoc = (Document JavaDoc)doc.cloneNode(true);
324             Element JavaDoc insertionPoint = cloneDoc.getElementById(INSERTION_POINT_ID);
325             
326             if (insertionPoint == null) {
327                 report.setErrorCode(ERROR_NO_INSERTION_POINT_IN_DOCUMENT);
328                 report.addDescriptionEntry(ENTRY_KEY_INSERTION_POINT_ID,
329                                            INSERTION_POINT_ID);
330                 report.setPassed(false);
331                 return report;
332             }
333
334             Element JavaDoc target = cloneDoc.getElementById(id);
335
336             if (target == null) {
337                 report.setErrorCode(ERROR_TARGET_ID_NOT_FOUND);
338                 report.addDescriptionEntry(ENTRY_KEY_TARGET_ID,
339                                            id);
340                 report.setPassed(false);
341                 return report;
342             }
343
344             insertionPoint.appendChild(target);
345             th = null;
346             try {
347                 GraphicsNode gn = builder.build(ctx, cloneDoc);
348                 gn.getBounds();
349                 th = userAgent.getDisplayError();
350             } catch (BridgeException e){
351                 th = e;
352             } catch (SecurityException JavaDoc e) {
353                 th = e;
354             } catch (Throwable JavaDoc t) {
355                 th = t;
356             }
357             if (th == null) {
358                 if (secure)
359                     failures.addElement(id);
360             } else if (th instanceof SecurityException JavaDoc) {
361                 if (!secure)
362                     failures.addElement(id);
363             } else if (th instanceof BridgeException) {
364                 BridgeException be = (BridgeException)th;
365                 if (!secure ||
366                     (secure && !ERR_URI_UNSECURE.equals(be.getCode()))) {
367                     report.setErrorCode(ERROR_WHILE_PROCESSING_SVG_DOCUMENT);
368                     report.addDescriptionEntry(ENTRY_KEY_ERROR_DESCRIPTION,
369                                                be.getMessage());
370                     report.setPassed(false);
371                     return report;
372                 }
373             } else {
374                 // Some unknown exception was displayed...
375
report.setErrorCode(ERROR_WHILE_PROCESSING_SVG_DOCUMENT);
376                 report.addDescriptionEntry(ENTRY_KEY_ERROR_DESCRIPTION,
377                                            th.getMessage());
378                 report.setPassed(false);
379                 return report;
380             }
381
382         }
383
384         if (failures.size() == 0) {
385             return reportSuccess();
386         }
387
388         if (secure) {
389             report.setErrorCode(ERROR_UNTHROWN_SECURITY_EXCEPTIONS);
390             for (int i=0; i<failures.size(); i++) {
391                 report.addDescriptionEntry(ENTRY_KEY_EXPECTED_EXCEPTION_ON,
392                                            failures.elementAt(i));
393             }
394         } else {
395             report.setErrorCode(ERROR_THROWN_SECURITY_EXCEPTIONS);
396             for (int i=0; i<failures.size(); i++) {
397                 report.addDescriptionEntry(ENTRY_KEY_UNEXPECTED_EXCEPTION_ON,
398                                            failures.elementAt(i));
399             }
400         }
401
402         report.setPassed(false);
403         return report;
404     }
405
406     protected interface MyUserAgent extends UserAgent {
407         public Exception JavaDoc getDisplayError();
408     }
409
410     protected MyUserAgent buildUserAgent(){
411         if (secure) {
412             return new SecureUserAgent();
413         } else {
414             return new RelaxedUserAgent();
415         }
416     }
417     
418     class MyUserAgentAdapter extends UserAgentAdapter implements MyUserAgent {
419         Exception JavaDoc ex = null;
420         public void displayError(Exception JavaDoc ex) {
421             this.ex = ex;
422             super.displayError(ex);
423         }
424
425         public Exception JavaDoc getDisplayError() { return ex; }
426     }
427     
428     class SecureUserAgent extends MyUserAgentAdapter {
429         public ExternalResourceSecurity
430             getExternalResourceSecurity(ParsedURL resourcePURL,
431                                         ParsedURL docPURL){
432             return new NoLoadExternalResourceSecurity();
433             
434         }
435     }
436
437     class RelaxedUserAgent extends MyUserAgentAdapter {
438         public ExternalResourceSecurity
439             getExternalResourceSecurity(ParsedURL resourcePURL,
440                                         ParsedURL docPURL){
441             return new RelaxedExternalResourceSecurity(resourcePURL,
442                                                        docPURL);
443             
444         }
445     }
446
447 }
448
Popular Tags