001: // Text - Saxon extension element for inserting text
002:
003: package com.nwalsh.saxon;
004:
005: import java.io.BufferedReader;
006: import java.io.InputStreamReader;
007: import java.io.InputStream;
008: import java.io.IOException;
009: import java.io.FileNotFoundException;
010: import java.net.URL;
011: import java.net.MalformedURLException;
012:
013: import javax.xml.transform.TransformerException;
014: import javax.xml.transform.TransformerConfigurationException;
015: import javax.xml.transform.URIResolver;
016: import javax.xml.transform.Source;
017:
018: import com.icl.saxon.Context;
019: import com.icl.saxon.style.StyleElement;
020: import com.icl.saxon.output.Outputter;
021: import com.icl.saxon.expr.Expression;
022:
023: import org.xml.sax.AttributeList;
024:
025: /**
026: * <p>Saxon extension element for inserting text
027: *
028: * <p>$Id: Text.java,v 1.1 2007-05-18 15:03:13 sinisa Exp $</p>
029: *
030: * <p>Copyright (C) 2000 Norman Walsh.</p>
031: *
032: * <p>This class provides a
033: * <a href="http://saxon.sourceforge.net/">Saxon</a>
034: * extension element for inserting text into a result tree.</p>
035: *
036: * <p><b>Change Log:</b></p>
037: * <dl>
038: * <dt>1.0</dt>
039: * <dd><p>Initial release.</p></dd>
040: * </dl>
041: *
042: * @author Norman Walsh
043: * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
044: *
045: * @version $Id: Text.java,v 1.1 2007-05-18 15:03:13 sinisa Exp $
046: *
047: */
048: public class Text extends StyleElement {
049: /**
050: * <p>Constructor for Text</p>
051: *
052: * <p>Does nothing.</p>
053: */
054: public Text() {
055: }
056:
057: /**
058: * <p>Is this element an instruction?</p>
059: *
060: * <p>Yes, it is.</p>
061: *
062: * @return true
063: */
064: public boolean isInstruction() {
065: return true;
066: }
067:
068: /**
069: * <p>Can this element contain a template-body?</p>
070: *
071: * <p>Yes, it can, but only so that it can contain xsl:fallback.</p>
072: *
073: * @return true
074: */
075: public boolean mayContainTemplateBody() {
076: return true;
077: }
078:
079: /**
080: * <p>Validate the arguments</p>
081: *
082: * <p>The element must have an href attribute.</p>
083: */
084: public void prepareAttributes()
085: throws TransformerConfigurationException {
086: // Get mandatory href attribute
087: String fnAtt = getAttribute("href");
088: if (fnAtt == null) {
089: reportAbsence("href");
090: }
091: }
092:
093: /** Validate that the element occurs in a reasonable place. */
094: public void validate() throws TransformerConfigurationException {
095: checkWithinTemplate();
096: }
097:
098: /**
099: * <p>Insert the text of the file into the result tree</p>
100: *
101: * <p>Processing this element inserts the contents of the URL named
102: * by the href attribute into the result tree as plain text.</p>
103: *
104: * <p>Optional encoding attribute can specify encoding of resource.
105: * If not specified default system encoding is used.</p>
106: *
107: */
108: public void process(Context context) throws TransformerException {
109: Outputter out = context.getOutputter();
110:
111: String hrefAtt = getAttribute("href");
112: Expression hrefExpr = makeAttributeValueTemplate(hrefAtt);
113: String href = hrefExpr.evaluateAsString(context);
114:
115: String encodingAtt = getAttribute("encoding");
116: Expression encodingExpr = makeAttributeValueTemplate(encodingAtt);
117: String encoding = encodingExpr.evaluateAsString(context);
118:
119: String baseURI = context.getContextNodeInfo().getBaseURI();
120:
121: URIResolver resolver = context.getController().getURIResolver();
122:
123: if (resolver != null) {
124: Source source = resolver.resolve(href, baseURI);
125: href = source.getSystemId();
126: }
127:
128: URL baseURL = null;
129: URL fileURL = null;
130:
131: try {
132: baseURL = new URL(baseURI);
133: } catch (MalformedURLException e0) {
134: // what the!?
135: baseURL = null;
136: }
137:
138: try {
139: try {
140: fileURL = new URL(baseURL, href);
141: } catch (MalformedURLException e1) {
142: try {
143: fileURL = new URL(baseURL, "file:" + href);
144: } catch (MalformedURLException e2) {
145: System.out.println("Cannot open " + href);
146: return;
147: }
148: }
149:
150: InputStreamReader isr = null;
151: if (encoding.equals("") == true)
152: isr = new InputStreamReader(fileURL.openStream());
153: else
154: isr = new InputStreamReader(fileURL.openStream(),
155: encoding);
156:
157: BufferedReader is = new BufferedReader(isr);
158:
159: final int BUFFER_SIZE = 4096;
160: char chars[] = new char[BUFFER_SIZE];
161: char nchars[] = new char[BUFFER_SIZE];
162: int len = 0;
163: int i = 0;
164: int carry = -1;
165:
166: while ((len = is.read(chars)) > 0) {
167: // various new lines are normalized to LF to prevent blank lines
168: // between lines
169:
170: int nlen = 0;
171: for (i = 0; i < len; i++) {
172: // is current char CR?
173: if (chars[i] == '\r') {
174: if (i < (len - 1)) {
175: // skip it if next char is LF
176: if (chars[i + 1] == '\n')
177: continue;
178: // single CR -> LF to normalize MAC line endings
179: nchars[nlen] = '\n';
180: nlen++;
181: continue;
182: } else {
183: // if CR is last char of buffer we must look ahead
184: carry = is.read();
185: nchars[nlen] = '\n';
186: nlen++;
187: if (carry == '\n') {
188: carry = -1;
189: }
190: break;
191: }
192: }
193: nchars[nlen] = chars[i];
194: nlen++;
195: }
196: out.writeContent(nchars, 0, nlen);
197: // handle look aheaded character
198: if (carry != -1)
199: out.writeContent(String.valueOf((char) carry));
200: carry = -1;
201: }
202: is.close();
203: } catch (Exception e) {
204: System.out.println("Cannot read " + href);
205: }
206: }
207: }
|