001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.bridge;
020:
021: import java.io.IOException;
022: import java.net.MalformedURLException;
023:
024: import org.apache.batik.dom.AbstractNode;
025: import org.apache.batik.dom.svg.SVGOMDocument;
026: import org.apache.batik.util.ParsedURL;
027: import org.w3c.dom.Document;
028: import org.w3c.dom.Element;
029: import org.w3c.dom.Node;
030: import org.w3c.dom.svg.SVGDocument;
031:
032: /**
033: * This class is used to resolve the URI that can be found in a SVG document.
034: *
035: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
036: * @version $Id: URIResolver.java 475477 2006-11-15 22:44:28Z cam $
037: */
038: public class URIResolver {
039: /**
040: * The reference document.
041: */
042: protected SVGOMDocument document;
043:
044: /**
045: * The document URI.
046: */
047: protected String documentURI;
048:
049: /**
050: * The document loader.
051: */
052: protected DocumentLoader documentLoader;
053:
054: /**
055: * Creates a new URI resolver object.
056: * @param doc The reference document.
057: * @param dl The document loader.
058: */
059: public URIResolver(SVGDocument doc, DocumentLoader dl) {
060: document = (SVGOMDocument) doc;
061: documentLoader = dl;
062: }
063:
064: /**
065: * Imports the Element referenced by the given URI on Element
066: * <tt>ref</tt>.
067: * @param uri The element URI.
068: * @param ref The Element in the DOM tree to evaluate <tt>uri</tt>
069: * from.
070: * @return The referenced element or null if element can't be found.
071: */
072: public Element getElement(String uri, Element ref)
073: throws MalformedURLException, IOException {
074:
075: Node n = getNode(uri, ref);
076: if (n == null) {
077: return null;
078: } else if (n.getNodeType() == Node.DOCUMENT_NODE) {
079: throw new IllegalArgumentException();
080: } else {
081: return (Element) n;
082: }
083: }
084:
085: /**
086: * Imports the Node referenced by the given URI on Element
087: * <tt>ref</tt>.
088: * @param uri The element URI.
089: * @param ref The Element in the DOM tree to evaluate <tt>uri</tt>
090: * from.
091: * @return The referenced Node/Document or null if element can't be found.
092: */
093: public Node getNode(String uri, Element ref)
094: throws MalformedURLException, IOException,
095: SecurityException {
096:
097: String baseURI = getRefererBaseURI(ref);
098: // System.err.println("baseURI: " + baseURI);
099: // System.err.println("URI: " + uri);
100: if (baseURI == null && uri.charAt(0) == '#') {
101: return getNodeByFragment(uri.substring(1), ref);
102: }
103:
104: ParsedURL purl = new ParsedURL(baseURI, uri);
105: // System.err.println("PURL: " + purl);
106:
107: if (documentURI == null)
108: documentURI = document.getURL();
109:
110: String frag = purl.getRef();
111: if ((frag != null) && (documentURI != null)) {
112: ParsedURL pDocURL = new ParsedURL(documentURI);
113: // System.out.println("doc: " + pDocURL);
114: // System.out.println("Purl: " + purl);
115: if (pDocURL.sameFile(purl)) {
116: // System.out.println("match");
117: return document.getElementById(frag);
118: }
119: }
120:
121: // uri is not a reference into this document, so load the
122: // document it does reference after doing a security
123: // check with the UserAgent
124: ParsedURL pDocURL = null;
125: if (documentURI != null) {
126: pDocURL = new ParsedURL(documentURI);
127: }
128:
129: UserAgent userAgent = documentLoader.getUserAgent();
130: userAgent.checkLoadExternalResource(purl, pDocURL);
131:
132: String purlStr = purl.toString();
133: if (frag != null) {
134: purlStr = purlStr.substring(0, purlStr.length()
135: - (frag.length() + 1));
136: }
137:
138: Document doc = documentLoader.loadDocument(purlStr);
139: if (frag != null)
140: return doc.getElementById(frag);
141: return doc;
142: }
143:
144: /**
145: * Returns the base URI of the referer element.
146: */
147: protected String getRefererBaseURI(Element ref) {
148: return ((AbstractNode) ref).getBaseURI();
149: }
150:
151: /**
152: * Returns the node referenced by the given fragment identifier.
153: * This is called when the whole URI just contains a fragment identifier
154: * and there is no XML Base URI in effect.
155: * @param frag the URI fragment
156: * @param ref the context element from which to resolve the URI fragment
157: */
158: protected Node getNodeByFragment(String frag, Element ref) {
159: return ref.getOwnerDocument().getElementById(frag);
160: }
161: }
|