1// Text - Xalan extension element for inserting text
2
3package com.nwalsh.xalan;
4
5import java.io.BufferedReader;
6import java.io.InputStreamReader;
7import java.io.InputStream;
8import java.io.IOException;
9import java.io.FileNotFoundException;
10import java.net.URL;
11import java.net.MalformedURLException;
12
13import org.xml.sax.SAXException;
14import org.xml.sax.ContentHandler;
15
16import org.apache.xpath.objects.XObject;
17import org.apache.xpath.XPath;
18import org.apache.xpath.NodeSet;
19import org.apache.xalan.extensions.XSLProcessorContext;
20import org.apache.xalan.transformer.TransformerImpl;
21import org.apache.xalan.templates.StylesheetRoot;
22import org.apache.xalan.templates.ElemExtensionCall;
23import org.apache.xalan.templates.OutputProperties;
24import org.apache.xalan.res.XSLTErrorResources;
25
26import javax.xml.transform.stream.StreamResult;
27import javax.xml.transform.TransformerException;
28import javax.xml.transform.URIResolver;
29import javax.xml.transform.Source;
30
31/**
32 * <p>Xalan extension element for inserting text
33 *
34 * <p>$Id: Text.java,v 1.2 2006/05/15 11:14:03 nwalsh Exp $</p>
35 *
36 * <p>Copyright (C) 2001 Norman Walsh.</p>
37 *
38 * <p>This class provides a
39 * <a href="http://xml.apache.org/xalan-j/">Xalan</a>
40 * extension element for inserting text into a result tree.</p>
41 *
42 * <p><b>Change Log:</b></p>
43 * <dl>
44 * <dt>1.0</dt>
45 * <dd><p>Initial release.</p></dd>
46 * </dl>
47 *
48 * @author Norman Walsh
49 * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
50 *
51 * @version $Id: Text.java,v 1.2 2006/05/15 11:14:03 nwalsh Exp $
52 *
53 */
54public class Text {
55  /**
56   * <p>Constructor for Text</p>
57   *
58   * <p>Does nothing.</p>
59   */
60  public Text() {
61  }
62
63  public String insertfile(XSLProcessorContext context,
64			     ElemExtensionCall elem)
65    throws MalformedURLException,
66           FileNotFoundException,
67           IOException,
68	   TransformerException {
69    String href = getFilename(context, elem);
70    String encoding = getEncoding(context, elem);
71
72    String baseURI = context.getTransformer().getBaseURLOfSource();
73    URIResolver resolver = context.getTransformer().getURIResolver();
74
75    if (resolver != null) {
76      Source source = resolver.resolve(href, baseURI);
77      href = source.getSystemId();
78    }
79
80    URL baseURL = null;
81    URL fileURL = null;
82
83    try {
84      baseURL = new URL(baseURI);
85    } catch (MalformedURLException e1) {
86      try {
87	baseURL = new URL("file:" + baseURI);
88      } catch (MalformedURLException e2) {
89	System.out.println("Cannot find base URI for " + baseURI);
90	baseURL = null;
91      }
92    }
93
94    String text = "";
95
96    try {
97      try {
98        fileURL = new URL(baseURL, href);
99      } catch (MalformedURLException e1) {
100        try {
101          fileURL = new URL(baseURL, "file:" + href);
102        } catch (MalformedURLException e2) {
103          System.out.println("Cannot open " + href);
104          return "";
105        }
106      }
107
108      InputStreamReader isr = null;
109      if (encoding.equals("") == true)
110        isr = new InputStreamReader(fileURL.openStream());
111      else
112        isr = new InputStreamReader(fileURL.openStream(), encoding);
113
114      BufferedReader is = new BufferedReader(isr);
115
116      final int BUFFER_SIZE = 4096;
117      char chars[] = new char[BUFFER_SIZE];
118      char nchars[] = new char[BUFFER_SIZE];
119      int len = 0;
120      int i = 0;
121      int carry = -1;
122
123      while ((len = is.read(chars)) > 0) {
124        // various new lines are normalized to LF to prevent blank lines
125	// between lines
126
127        int nlen = 0;
128        for (i=0; i<len; i++) {
129          // is current char CR?
130          if (chars[i] == '\r') {
131            if (i < (len - 1)) {
132              // skip it if next char is LF
133              if (chars[i+1] == '\n') continue;
134              // single CR -> LF to normalize MAC line endings
135              nchars[nlen] = '\n';
136              nlen++;
137              continue;
138            } else {
139              // if CR is last char of buffer we must look ahead
140              carry = is.read();
141              nchars[nlen] = '\n';
142              nlen++;
143              if (carry == '\n') {
144                carry = -1;
145              }
146              break;
147            }
148          }
149          nchars[nlen] = chars[i];
150          nlen++;
151        }
152
153	text += String.valueOf(nchars, 0, nlen);
154
155        // handle look aheaded character
156        if (carry != -1) text += String.valueOf((char)carry);
157        carry = -1;
158      }
159      is.close();
160    } catch (Exception e) {
161      System.out.println("Cannot read " + href);
162    }
163
164    return text;
165  }
166
167  private String getFilename(XSLProcessorContext context, ElemExtensionCall elem)
168    throws java.net.MalformedURLException,
169	   java.io.FileNotFoundException,
170	   java.io.IOException,
171	   javax.xml.transform.TransformerException {
172
173    String fileName;
174
175    fileName = ((ElemExtensionCall)elem).getAttribute ("href",
176						       context.getContextNode(),
177						       context.getTransformer());
178
179    if ("".equals(fileName)) {
180      context.getTransformer().getMsgMgr().error(elem,
181						 "No 'href' on text, or not a filename");
182    }
183
184    return fileName;
185  }
186
187  private String getEncoding(XSLProcessorContext context, ElemExtensionCall elem)
188    throws java.net.MalformedURLException,
189	   java.io.FileNotFoundException,
190	   java.io.IOException,
191	   javax.xml.transform.TransformerException {
192
193    String encoding;
194
195    encoding = ((ElemExtensionCall)elem).getAttribute ("encoding",
196						       context.getContextNode(),
197						       context.getTransformer());
198
199    return encoding;
200  }
201}
202