001: /*
002: * Fast Infoset ver. 0.1 software ("Software")
003: *
004: * Copyright, 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * Software is licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License. You may
008: * 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, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations.
016: *
017: * Sun supports and benefits from the global community of open source
018: * developers, and thanks the community for its important contributions and
019: * open standards-based technology, which Sun has adopted into many of its
020: * products.
021: *
022: * Please note that portions of Software may be provided with notices and
023: * open source licenses from such communities and third parties that govern the
024: * use of those portions, and any licenses granted hereunder do not alter any
025: * rights and obligations you may have under such open source licenses,
026: * however, the disclaimer of warranty and limitation of liability provisions
027: * in this License will apply to all Software in this distribution.
028: *
029: * You acknowledge that the Software is not designed, licensed or intended
030: * for use in the design, construction, operation or maintenance of any nuclear
031: * facility.
032: *
033: * Apache License
034: * Version 2.0, January 2004
035: * http://www.apache.org/licenses/
036: *
037: */
038:
039: package com.sun.xml.fastinfoset.tools;
040:
041: import java.io.BufferedInputStream;
042: import java.io.BufferedOutputStream;
043: import java.io.File;
044: import java.io.FileInputStream;
045: import java.io.FileOutputStream;
046: import java.io.IOException;
047: import java.io.InputStream;
048: import java.io.OutputStream;
049: import com.sun.xml.fastinfoset.CommonResourceBundle;
050: import java.net.URI;
051: import java.net.URISyntaxException;
052: import org.xml.sax.EntityResolver;
053: import org.xml.sax.InputSource;
054: import org.xml.sax.SAXException;
055:
056: public abstract class TransformInputOutput {
057:
058: /** Creates a new instance of TransformInputOutput */
059: public TransformInputOutput() {
060: }
061:
062: public void parse(String[] args) throws Exception {
063: InputStream in = null;
064: OutputStream out = null;
065: if (args.length == 0) {
066: in = new BufferedInputStream(System.in);
067: out = new BufferedOutputStream(System.out);
068: } else if (args.length == 1) {
069: in = new BufferedInputStream(new FileInputStream(args[0]));
070: out = new BufferedOutputStream(System.out);
071: } else if (args.length == 2) {
072: in = new BufferedInputStream(new FileInputStream(args[0]));
073: out = new BufferedOutputStream(
074: new FileOutputStream(args[1]));
075: } else {
076: throw new IllegalArgumentException(CommonResourceBundle
077: .getInstance().getString(
078: "message.optinalFileNotSpecified"));
079: }
080:
081: parse(in, out);
082: }
083:
084: abstract public void parse(InputStream in, OutputStream out)
085: throws Exception;
086:
087: // parse alternative with current working directory parameter
088: // is used to process xml documents, which have external imported entities
089: public void parse(InputStream in, OutputStream out,
090: String workingDirectory) throws Exception {
091: throw new UnsupportedOperationException();
092: }
093:
094: private static URI currentJavaWorkingDirectory;
095: static {
096: currentJavaWorkingDirectory = new File(System
097: .getProperty("user.dir")).toURI();
098: }
099:
100: protected static EntityResolver createRelativePathResolver(
101: final String workingDirectory) {
102: return new EntityResolver() {
103: public InputSource resolveEntity(String publicId,
104: String systemId) throws SAXException, IOException {
105: if (systemId != null && systemId.startsWith("file:/")) {
106: URI workingDirectoryURI = new File(workingDirectory)
107: .toURI();
108: URI workingFile;
109: try {
110: // Construction new File(new URI(String)).toURI() is used to be sure URI has correct representation without redundant '/'
111: workingFile = convertToNewWorkingDirectory(
112: currentJavaWorkingDirectory,
113: workingDirectoryURI, new File(new URI(
114: systemId)).toURI());
115: return new InputSource(workingFile.toString());
116: } catch (URISyntaxException ex) {
117: //Should not get here
118: }
119: }
120: return null;
121: }
122: };
123: }
124:
125: private static URI convertToNewWorkingDirectory(URI oldwd,
126: URI newwd, URI file) throws IOException, URISyntaxException {
127: String oldwdStr = oldwd.toString();
128: String newwdStr = newwd.toString();
129: String fileStr = file.toString();
130:
131: String cmpStr = null;
132: // In simpliest case <user.dir>/file.xml - do it faster
133: if (fileStr.startsWith(oldwdStr)
134: && (cmpStr = fileStr.substring(oldwdStr.length()))
135: .indexOf('/') == -1) {
136: return new URI(newwdStr + '/' + cmpStr);
137: }
138:
139: String[] oldwdSplit = oldwdStr.split("/");
140: String[] newwdSplit = newwdStr.split("/");
141: String[] fileSplit = fileStr.split("/");
142:
143: int diff;
144: for (diff = 0; diff < oldwdSplit.length
145: & diff < fileSplit.length; diff++) {
146: if (!oldwdSplit[diff].equals(fileSplit[diff])) {
147: break;
148: }
149: }
150:
151: int diffNew;
152: for (diffNew = 0; diffNew < newwdSplit.length
153: && diffNew < fileSplit.length; diffNew++) {
154: if (!newwdSplit[diffNew].equals(fileSplit[diffNew])) {
155: break;
156: }
157: }
158:
159: //Workaround for case, when extrnal imported entity has imports other entity
160: //in that case systemId has correct path, not based on user.dir
161: if (diffNew > diff) {
162: return file;
163: }
164:
165: int elemsToSub = oldwdSplit.length - diff;
166: StringBuffer resultStr = new StringBuffer(100);
167: for (int i = 0; i < newwdSplit.length - elemsToSub; i++) {
168: resultStr.append(newwdSplit[i]);
169: resultStr.append('/');
170: }
171:
172: for (int i = diff; i < fileSplit.length; i++) {
173: resultStr.append(fileSplit[i]);
174: if (i < fileSplit.length - 1)
175: resultStr.append('/');
176: }
177:
178: return new URI(resultStr.toString());
179: }
180: }
|