| /* |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| package org.apache.batik.test.svg; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NodeList; |
| |
| import org.apache.batik.anim.dom.SAXSVGDocumentFactory; |
| import org.apache.batik.bridge.BaseScriptingEnvironment; |
| import org.apache.batik.bridge.BridgeContext; |
| import org.apache.batik.bridge.BridgeException; |
| import org.apache.batik.bridge.GVTBuilder; |
| import org.apache.batik.bridge.UserAgent; |
| import org.apache.batik.bridge.UserAgentAdapter; |
| import org.apache.batik.test.AbstractTest; |
| import org.apache.batik.test.DefaultTestReport; |
| import org.apache.batik.test.TestReport; |
| import org.apache.batik.util.XMLResourceDescriptor; |
| |
| /** |
| * This test takes an SVG file as an input. It processes the input SVG |
| * (meaning it turns it into a GVT tree) and then dispatches the 'onload' |
| * event. |
| * |
| * The SVG input file should contain script that will position the |
| * result of the test in the DOM using the following namespace: <br> |
| * xmlns:test="http://xml.apache.org/batik/test" <br> |
| * |
| * The result should be set in the <code>result</code> attribute of the |
| * <testResult> element by the script embeded in the input SVG |
| * test file. <br> |
| * |
| * Sample input SVG file:<br><code> |
| * <svg ... onload="runTest(evt)" xmlns:test="http://xml.apache.org/batik/test" > |
| * <script type="text/ecmascript"> |
| * function runTest(evt) { |
| * ...; // do some test |
| * var rootSvg = document.getDocumentElement(); |
| * var result = document.createElementNS("http://xml.apache.org/batik/test", |
| * "testResult"); |
| * result.setAttributeNS(null, "result", "failed"); |
| * result.setAttributeNS(null, "errorCode", "org.apache.batik.css.dom.wrong.computed.value"); |
| * rootSvg.appendChild(result); |
| * } |
| * </script> |
| * </svg></code> |
| * |
| * @author <a href="mailto:vhardy@apache.org">Vincent Hardy</a> |
| * @version $Id$ |
| */ |
| public class SelfContainedSVGOnLoadTest extends AbstractTest { |
| /** |
| * Error when the input file cannot be loaded into a |
| * Document object |
| * {0} = IOException message |
| */ |
| public static final String ERROR_CANNOT_LOAD_SVG_DOCUMENT |
| = "SelfContainedSVGOnLoadTest.error.cannot.load.svg.document"; |
| |
| /** |
| * Error while building the GVT tree or dispatching the |
| * 'onload' event. |
| */ |
| public static final String ERROR_WHILE_PROCESSING_SVG_DOCUMENT |
| = "SelfContainedSVGOnLoadTest.error.while.processing.svg.document"; |
| |
| /** |
| * There is either 0 or more than one <testResult> elements in |
| * the document after dispatching the onload event. |
| */ |
| public static final String ERROR_UNEXPECTED_NUMBER_OF_TEST_RESULT_ELEMENTS |
| = "SelfContainedSVGOnLoadTest.error.unexpected.number.of.test.result.elements"; |
| |
| /** |
| * The 'result' attribute value is neither 'passed' nor 'failed' |
| */ |
| public static final String ERROR_UNEXPECTED_RESULT_VALUE |
| = "SelfContainedSVGOnLoadTest.error.unexpected.result.value"; |
| |
| /** |
| * The result was 'failed' but there was no 'errorCode' attribute or |
| * it was the empty string |
| */ |
| public static final String ERROR_MISSING_OR_EMPTY_ERROR_CODE_ON_FAILED_TEST |
| = "SelfContainedSVGOnLoadTest.error.missing.or.empty.error.code.on.failed.test"; |
| |
| /** |
| * Entry describing the error |
| */ |
| public static final String ENTRY_KEY_ERROR_DESCRIPTION |
| = "SelfContainedSVGOnLoadTest.entry.key.error.description"; |
| |
| /** |
| * Entry describing the number of testResult elements found in the |
| * document after dispatching onload. |
| */ |
| public static final String ENTRY_KEY_NUMBER_OF_TEST_RESULT_ELEMENTS |
| = "SelfContainedSVGOnLoadTest.entry.key.number.of.test.result.elements"; |
| |
| /** |
| * Entry describing the result value (different from 'passed' or 'failed' |
| * found in the 'result' attribute. |
| */ |
| public static final String ENTRY_KEY_RESULT_VALUE |
| = "SelfContainedSVGOnLoadTest.entry.key.result.value"; |
| |
| /** |
| * Test Namespace |
| */ |
| public static final String testNS = "http://xml.apache.org/batik/test"; |
| |
| /** |
| * Test Constants |
| */ |
| public static final String TAG_TEST_RESULT = "testResult"; |
| public static final String TAG_ERROR_DESCRIPTION_ENTRY = "errorDescriptionEntry"; |
| public static final String ATTRIBUTE_RESULT = "result"; |
| public static final String ATTRIBUTE_KEY = "id"; |
| public static final String ATTRIBUTE_VALUE = "value"; |
| public static final String TEST_RESULT_PASSED = "passed"; |
| public static final String TEST_RESULT_FAILED = "failed"; |
| |
| /** |
| * The URL for the input SVG document to be tested |
| */ |
| protected String svgURL; |
| |
| /** |
| * @param svgURL the URL string for the SVG document being tested |
| */ |
| public SelfContainedSVGOnLoadTest(String svgURL){ |
| this.svgURL = resolveURL(svgURL); |
| } |
| |
| /** |
| * Default constructor |
| */ |
| protected SelfContainedSVGOnLoadTest(){ |
| } |
| |
| /** |
| * Resolves the input string as follows. |
| * + First, the string is interpreted as a file description. |
| * If the file exists, then the file name is turned into |
| * a URL. |
| * + Otherwise, the string is supposed to be a URL. If it |
| * is an invalid URL, an IllegalArgumentException is thrown. |
| */ |
| protected String resolveURL(String url){ |
| // Is url a file? |
| File f = (new File(url)).getAbsoluteFile(); |
| if(f.getParentFile().exists()){ |
| try{ |
| return f.toURI().toURL().toString(); |
| }catch(MalformedURLException e){ |
| throw new IllegalArgumentException(); |
| } |
| } |
| |
| // url is not a file. It must be a regular URL... |
| try{ |
| return (new URL(url)).toString(); |
| }catch(MalformedURLException e){ |
| throw new IllegalArgumentException(url); |
| } |
| } |
| |
| |
| /** |
| * Run this test and produce a report. |
| * The test goes through the following steps: <ul> |
| * <li>load the input SVG into a Document</li> |
| * <li>build the GVT tree corresponding to the |
| * Document and dispatch the 'onload' event</li> |
| * <li>looks for one and only one <testResult> element in |
| * the Document. This is used to build the returned |
| * TestReport</li> |
| * </ul> |
| * |
| */ |
| public TestReport runImpl() throws Exception{ |
| DefaultTestReport report |
| = new DefaultTestReport(this); |
| |
| // |
| // First step: |
| // |
| // Load the input SVG into a Document object |
| // |
| String parserClassName = XMLResourceDescriptor.getXMLParserClassName(); |
| SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parserClassName); |
| Document doc = null; |
| |
| try { |
| doc = f.createDocument(svgURL); |
| } catch(IOException e){ |
| report.setErrorCode(ERROR_CANNOT_LOAD_SVG_DOCUMENT); |
| report.addDescriptionEntry(ENTRY_KEY_ERROR_DESCRIPTION, |
| e.getMessage()); |
| report.setPassed(false); |
| return report; |
| } catch(Exception e){ |
| report.setErrorCode(ERROR_CANNOT_LOAD_SVG_DOCUMENT); |
| report.addDescriptionEntry(ENTRY_KEY_ERROR_DESCRIPTION, |
| e.getMessage()); |
| report.setPassed(false); |
| return report; |
| } |
| |
| // |
| // Second step: |
| // |
| // Now that the SVG file has been loaded, build |
| // a GVT Tree from it |
| // |
| UserAgent userAgent = buildUserAgent(); |
| GVTBuilder builder = new GVTBuilder(); |
| BridgeContext ctx = new BridgeContext(userAgent); |
| ctx.setDynamic(true); |
| |
| try { |
| builder.build(ctx, doc); |
| BaseScriptingEnvironment scriptEnvironment |
| = new BaseScriptingEnvironment(ctx); |
| scriptEnvironment.loadScripts(); |
| scriptEnvironment.dispatchSVGLoadEvent(); |
| } catch (BridgeException e){ |
| e.printStackTrace(); |
| report.setErrorCode(ERROR_WHILE_PROCESSING_SVG_DOCUMENT); |
| report.addDescriptionEntry(ENTRY_KEY_ERROR_DESCRIPTION, |
| e.getMessage()); |
| report.setPassed(false); |
| return report; |
| } catch(Exception e){ |
| e.printStackTrace(); |
| report.setErrorCode(ERROR_WHILE_PROCESSING_SVG_DOCUMENT); |
| report.addDescriptionEntry(ENTRY_KEY_ERROR_DESCRIPTION, |
| e.getMessage()); |
| report.setPassed(false); |
| return report; |
| } |
| |
| // |
| // Final step: |
| // |
| // Look for one and only one <testResult> element |
| // |
| NodeList testResultList = doc.getElementsByTagNameNS(testNS, |
| TAG_TEST_RESULT); |
| |
| // Check that there is one and only one testResult element |
| if(testResultList.getLength() != 1){ |
| report.setErrorCode(ERROR_UNEXPECTED_NUMBER_OF_TEST_RESULT_ELEMENTS); |
| report.addDescriptionEntry(ENTRY_KEY_NUMBER_OF_TEST_RESULT_ELEMENTS, |
| "" + testResultList.getLength()); |
| report.setPassed(false); |
| return report; |
| } |
| |
| Element testResult = (Element)testResultList.item(0); |
| |
| // Now, get the result attribute. Whould be either "passed" or "failed" |
| String result = testResult.getAttributeNS(null, ATTRIBUTE_RESULT); |
| boolean passed = true; |
| if(TEST_RESULT_PASSED.equals(result)){ |
| // OK |
| } else if (TEST_RESULT_FAILED.equals(result)){ |
| passed = false; |
| } else { |
| report.setErrorCode(ERROR_UNEXPECTED_RESULT_VALUE); |
| report.addDescriptionEntry(ENTRY_KEY_RESULT_VALUE, result); |
| report.setPassed(false); |
| return report; |
| } |
| |
| // If the test failed, then there should be an error code |
| if( !passed ){ |
| String errorCode = testResult.getAttributeNS(null, "errorCode"); |
| if("".equals(errorCode)){ |
| report.setErrorCode(ERROR_MISSING_OR_EMPTY_ERROR_CODE_ON_FAILED_TEST); |
| report.setPassed(false); |
| return report; |
| } |
| |
| // We got an error code, set it on the report object |
| report.setErrorCode(errorCode); |
| |
| // Now, add descriptions from children <errorDescriptionEntry> elements |
| NodeList desc = testResult.getElementsByTagNameNS(testNS, |
| TAG_ERROR_DESCRIPTION_ENTRY); |
| int nDesc = desc.getLength(); |
| for (int i=0; i<nDesc; i++){ |
| Element entry = (Element)desc.item(i); |
| String key = entry.getAttributeNS(null, ATTRIBUTE_KEY); |
| String value = entry.getAttributeNS(null, ATTRIBUTE_VALUE); |
| report.addDescriptionEntry(key, value); |
| } |
| report.setPassed(false); |
| return report; |
| } |
| |
| return report; |
| } |
| |
| /** |
| * Give subclasses a chance to build their own UserAgent |
| */ |
| protected UserAgent buildUserAgent(){ |
| return new UserAgentAdapter(); |
| } |
| |
| } |