001: package net.sf.saxon.event;
002:
003: import net.sf.saxon.Configuration;
004: import net.sf.saxon.StandardURIResolver;
005: import net.sf.saxon.om.ProcInstParser;
006: import net.sf.saxon.trans.DynamicError;
007: import net.sf.saxon.trans.XPathException;
008:
009: import javax.xml.transform.Source;
010: import javax.xml.transform.TransformerException;
011: import javax.xml.transform.URIResolver;
012: import javax.xml.transform.sax.SAXSource;
013: import java.util.ArrayList;
014:
015: /**
016: * The PIGrabber class is a Receiver that looks for xml-stylesheet processing
017: * instructions and tests whether they match specified criteria; for those that do, it creates
018: * an InputSource object referring to the relevant stylesheet
019: * @author Michael H. Kay
020: */
021:
022: public class PIGrabber extends ProxyReceiver {
023:
024: private Configuration config = null;
025: private String reqMedia = null;
026: private String reqTitle = null;
027: private String baseURI = null;
028: private URIResolver uriResolver = null;
029: private ArrayList stylesheets = new ArrayList();
030: private boolean terminated = false;
031:
032: public void setFactory(Configuration config) {
033: this .config = config;
034: }
035:
036: public void setCriteria(String media, String title, String charset) {
037: this .reqMedia = media;
038: this .reqTitle = title;
039: }
040:
041: /**
042: * Set the base URI
043: */
044:
045: public void setBaseURI(String uri) {
046: baseURI = uri;
047: }
048:
049: /**
050: * Set the URI resolver to be used for the href attribute
051: */
052:
053: public void setURIResolver(URIResolver resolver) {
054: uriResolver = resolver;
055: }
056:
057: public void open() {
058: nextReceiver = new Sink();
059: }
060:
061: /**
062: * Abort the parse when the first start element tag is found
063: */
064:
065: public void startElement(int namecode, int typecode,
066: int locationId, int properties) throws XPathException {
067: terminated = true;
068: // abort the parse when the first start element tag is found
069: throw new DynamicError("#start#");
070: }
071:
072: /**
073: * Determine whether the parse terminated because the first start element tag was found
074: */
075:
076: public boolean isTerminated() {
077: return terminated;
078: }
079:
080: /**
081: * Handle xml-stylesheet PI
082: */
083:
084: public void processingInstruction(String target, CharSequence data,
085: int locationId, int properties) throws XPathException {
086: if (target.equals("xml-stylesheet")) {
087:
088: String value = data.toString();
089: String piMedia = ProcInstParser.getPseudoAttribute(value,
090: "media");
091: String piTitle = ProcInstParser.getPseudoAttribute(value,
092: "title");
093: String piType = ProcInstParser.getPseudoAttribute(value,
094: "type");
095: String piAlternate = ProcInstParser.getPseudoAttribute(
096: value, "alternate");
097:
098: if (piType == null)
099: return;
100:
101: // System.err.println("Found xml-stylesheet media=" + piMedia + " title=" + piTitle);
102:
103: if ((piType.equals("text/xml")
104: || piType.equals("application/xml")
105: || piType.equals("text/xsl")
106: || piType.equals("applicaton/xsl") || piType
107: .equals("application.xml+xslt"))
108: &&
109:
110: (reqMedia == null || piMedia == null || reqMedia
111: .equals(piMedia))
112: &&
113:
114: ((piTitle == null && (piAlternate == null || piAlternate
115: .equals("no")))
116: || (reqTitle == null) || (piTitle != null && piTitle
117: .equals(reqTitle)))) {
118: String href = ProcInstParser.getPseudoAttribute(value,
119: "href");
120: if (href == null) {
121: throw new DynamicError(
122: "xml-stylesheet PI has no href attribute");
123: }
124:
125: // System.err.println("Adding " + href);
126: if (piTitle == null
127: && (piAlternate == null || piAlternate
128: .equals("no"))) {
129: stylesheets.add(0, href);
130: } else {
131: stylesheets.add(href);
132: }
133: } else {
134: //System.err.println("No match on required media=" + reqMedia + " title=" + reqTitle );
135: }
136: }
137: }
138:
139: /**
140: * Return list of stylesheets that matched, as an array of Source objects
141: * @return null if there were no matching stylesheets.
142: * @throws net.sf.saxon.trans.XPathException if a URI cannot be resolved
143: */
144:
145: public Source[] getAssociatedStylesheets()
146: throws TransformerException {
147: if (stylesheets.size() == 0) {
148: return null;
149: }
150: if (uriResolver == null) {
151: uriResolver = new StandardURIResolver(config);
152: }
153: Source[] result = new Source[stylesheets.size()];
154: for (int i = 0; i < stylesheets.size(); i++) {
155: String href = (String) stylesheets.get(i);
156: Source s = uriResolver.resolve(href, baseURI);
157: if (s instanceof SAXSource) {
158: ((SAXSource) s).setXMLReader(config.getStyleParser());
159: }
160: if (s == null) {
161: s = config.getSystemURIResolver()
162: .resolve(href, baseURI);
163: }
164: result[i] = s;
165: }
166: return result;
167: }
168:
169: }
170: //
171: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
172: // you may not use this file except in compliance with the License. You may obtain a copy of the
173: // License at http://www.mozilla.org/MPL/
174: //
175: // Software distributed under the License is distributed on an "AS IS" basis,
176: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
177: // See the License for the specific language governing rights and limitations under the License.
178: //
179: // The Original Code is: all this file.
180: //
181: // The Initial Developer of the Original Code is Michael H. Kay.
182: //
183: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
184: //
185: // Contributor(s): none.
186: //
|