001: package net.sf.saxon.event;
002:
003: import net.sf.saxon.OutputURIResolver;
004: import net.sf.saxon.trans.DynamicError;
005: import net.sf.saxon.trans.XPathException;
006:
007: import javax.xml.transform.Result;
008: import javax.xml.transform.stream.StreamResult;
009: import java.io.File;
010: import java.io.IOException;
011: import java.io.OutputStream;
012: import java.net.*;
013:
014: /**
015: * This class defines the default OutputURIResolver. This is a counterpart to the JAXP
016: * URIResolver, but is used to map the URI of a secondary result document to a Result object
017: * which acts as the destination for the new document.
018: * @author Michael H. Kay
019: */
020:
021: public class StandardOutputResolver implements OutputURIResolver {
022:
023: private static StandardOutputResolver theInstance = new StandardOutputResolver();
024:
025: /**
026: * Get a singular instance
027: */
028:
029: public static StandardOutputResolver getInstance() {
030: return theInstance;
031: }
032:
033: /**
034: * Resolve an output URI
035: * @param href The relative URI of the output document. This corresponds to the
036: * href attribute of the xsl:result-document instruction.
037: * @param base The base URI that should be used. This is the base output URI,
038: * normally the URI of the principal output file.
039: * @return a Result object representing the destination for the XML document
040: */
041:
042: public Result resolve(String href, String base)
043: throws XPathException {
044:
045: // System.err.println("Output URI Resolver (href='" + href + "', base='" + base + "')");
046:
047: try {
048: URI absoluteURI;
049: if (href.equals("")) {
050: if (base == null) {
051: throw new DynamicError(
052: "The system identifier of the principal output file is unknown");
053: }
054: absoluteURI = new URI(base);
055: } else {
056: absoluteURI = new URI(href);
057: }
058: if (!absoluteURI.isAbsolute()) {
059: if (base == null) {
060: throw new DynamicError(
061: "The system identifier of the principal output file is unknown");
062: }
063: URI baseURI = new URI(base);
064: absoluteURI = baseURI.resolve(href);
065: }
066:
067: if (absoluteURI.getScheme().equals("file")) {
068: File newFile = new File(absoluteURI);
069: try {
070: if (!newFile.exists()) {
071: String parent = newFile.getParent();
072: if (parent != null) {
073: File parentPath = new File(parent);
074: if (parentPath != null
075: && !parentPath.exists()) {
076: parentPath.mkdirs();
077: }
078: newFile.createNewFile();
079: }
080: }
081:
082: //StreamResult result = new StreamResult(new FileOutputStream(newFile));
083: StreamResult result = new StreamResult(newFile
084: .toURI().toASCIIString());
085: // The call new StreamResult(newFile) does file-to-URI conversion incorrectly
086: //result.setSystemId(newFile);
087: return result;
088:
089: } catch (java.io.IOException err) {
090: throw new DynamicError(
091: "Failed to create output file "
092: + absoluteURI, err);
093: }
094:
095: } else {
096:
097: // See if the Java VM can conjure up a writable URL connection for us.
098: // This is optimistic: I have yet to discover a URL scheme that it can handle.
099:
100: URLConnection connection = absoluteURI.toURL()
101: .openConnection();
102: connection.setDoInput(false);
103: connection.setDoOutput(true);
104: connection.connect();
105: OutputStream stream = connection.getOutputStream();
106: StreamResult result = new StreamResult(stream);
107: result.setSystemId(absoluteURI.toASCIIString());
108: return result;
109: }
110: } catch (URISyntaxException err) {
111: throw new DynamicError("Invalid syntax for base URI", err);
112: } catch (IllegalArgumentException err2) {
113: throw new DynamicError("Invalid URI syntax", err2);
114: } catch (MalformedURLException err3) {
115: throw new DynamicError("Resolved URL is malformed", err3);
116: } catch (UnknownServiceException err5) {
117: throw new DynamicError(
118: "Specified protocol does not allow output", err5);
119: } catch (IOException err4) {
120: throw new DynamicError(
121: "Cannot open connection to specified URL", err4);
122: }
123: }
124:
125: /**
126: * Signal completion of the result document. This method is called by the system
127: * when the result document has been successfully written. It allows the resolver
128: * to perform tidy-up actions such as closing output streams, or firing off
129: * processes that take this result tree as input. Note that the OutputURIResolver
130: * is stateless, so the original href is supplied to identify the document
131: * that has been completed.
132: */
133:
134: public void close(Result result) throws XPathException {
135: if (result instanceof StreamResult) {
136: OutputStream stream = ((StreamResult) result)
137: .getOutputStream();
138: if (stream != null) {
139: try {
140: stream.close();
141: } catch (java.io.IOException err) {
142: throw new DynamicError(
143: "Failed while closing output file", err);
144: }
145: }
146: }
147: }
148:
149: // public static void main(String[] args) {
150: // System.err.println("supplied base file: " + args[0]);
151: // System.err.println("relative URI: " + args[1]);
152: // System.err.println("base URI: " + new File(args[0]).toURI().toString());
153: // System.err.println("resolved URI: " + new File(args[0]).toURI().resolve(args[1]).toString());
154: // }
155:
156: }
157:
158: //
159: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
160: // you may not use this file except in compliance with the License. You may obtain a copy of the
161: // License at http://www.mozilla.org/MPL/
162: //
163: // Software distributed under the License is distributed on an "AS IS" basis,
164: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
165: // See the License for the specific language governing rights and limitations under the License.
166: //
167: // The Original Code is: all this file.
168: //
169: // The Initial Developer of the Original Code is Michael H. Kay
170: //
171: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
172: //
173: // Contributor(s): none.
174: //
|