KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > instruct > Doctype


1 package net.sf.saxon.instruct;
2
3 import net.sf.saxon.Controller;
4 import net.sf.saxon.event.Receiver;
5 import net.sf.saxon.event.ReceiverOptions;
6 import net.sf.saxon.event.SequenceReceiver;
7 import net.sf.saxon.expr.*;
8 import net.sf.saxon.om.*;
9 import net.sf.saxon.style.StandardNames;
10 import net.sf.saxon.tinytree.TinyBuilder;
11 import net.sf.saxon.trans.DynamicError;
12 import net.sf.saxon.trans.XPathException;
13 import net.sf.saxon.type.ItemType;
14
15 import java.io.PrintStream JavaDoc;
16 import java.util.Iterator JavaDoc;
17
18 /**
19  * A saxon:doctype element in the stylesheet.
20  */

21
22 public class Doctype extends Instruction {
23
24     private Expression content;
25
26     public Doctype(Expression content) {
27         this.content = content;
28     }
29     /**
30      * Simplify an expression. This performs any static optimization (by rewriting the expression
31      * as a different expression). The default implementation does nothing.
32      * @return the simplified expression
33      * @throws net.sf.saxon.trans.XPathException
34      * if an error is discovered during expression rewriting
35      */

36
37     public Expression simplify(StaticContext env) throws XPathException {
38         content = content.simplify(env);
39         return this;
40     }
41
42     public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
43         content = content.typeCheck(env, contextItemType);
44         adoptChildExpression(content);
45         return this;
46     }
47
48     public Expression optimize(Optimizer opt, StaticContext env, ItemType contextItemType) throws XPathException {
49         content = content.optimize(opt, env, contextItemType);
50         adoptChildExpression(content);
51         return this;
52     }
53
54     /**
55      * Get the immediate sub-expressions of this expression. Default implementation
56      * returns a zero-length array, appropriate for an expression that has no
57      * sub-expressions.
58      *
59      * @return an iterator containing the sub-expressions of this expression
60      */

61
62     public Iterator JavaDoc iterateSubExpressions() {
63         return new MonoIterator(content);
64     }
65
66     /**
67      * Handle promotion offers, that is, non-local tree rewrites.
68      * @param offer The type of rewrite being offered
69      * @throws XPathException
70      */

71
72     protected void promoteInst(PromotionOffer offer) throws XPathException {
73         content = doPromotion(content, offer);
74     }
75     /**
76      * Determine whether this instruction creates new nodes.
77      * This implementation returns true.
78      */

79
80     public final boolean createsNewNodes() {
81         return true;
82     }
83
84     /**
85      * Get the name of this instruction for diagnostic and tracing purposes
86      */

87
88     public int getInstructionNameCode() {
89         return StandardNames.SAXON_DOCTYPE;
90     }
91
92      public TailCall processLeavingTail(XPathContext context) throws XPathException {
93         Controller controller = context.getController();
94         XPathContext c2 = context.newMinorContext();
95         c2.setOrigin(this);
96         SequenceReceiver out = c2.getReceiver();
97         TinyBuilder builder = new TinyBuilder();
98         Receiver receiver = builder;
99         receiver.setPipelineConfiguration(controller.makePipelineConfiguration());
100         receiver.open();
101         receiver.startDocument(0);
102         c2.changeOutputDestination(null, receiver, false, Validation.PRESERVE, null);
103         content.process(c2);
104         receiver.endDocument();
105         receiver.close();
106         DocumentInfo dtdRoot = (DocumentInfo)builder.getCurrentRoot();
107
108         SequenceIterator children = dtdRoot.iterateAxis(Axis.CHILD);
109         NodeInfo docType = (NodeInfo) children.next();
110         if (docType == null || !("doctype".equals(docType.getLocalPart()))) {
111             DynamicError e = new DynamicError("saxon:doctype instruction must contain dtd:doctype");
112             e.setXPathContext(context);
113             throw e;
114         }
115         String JavaDoc name = Navigator.getAttributeValue(docType, "", "name");
116         String JavaDoc system = Navigator.getAttributeValue(docType, "", "system");
117         String JavaDoc publicid = Navigator.getAttributeValue(docType, "", "public");
118
119         if (name == null) {
120             DynamicError e = new DynamicError("dtd:doctype must have a name attribute");
121             e.setXPathContext(context);
122             throw e;
123         }
124
125         write(out, "<!DOCTYPE " + name + ' ');
126         if (system != null) {
127             if (publicid != null) {
128                 write(out, "PUBLIC \"" + publicid + "\" \"" + system + '\"');
129             } else {
130                 write(out, "SYSTEM \"" + system + '\"');
131             }
132         }
133
134         boolean openSquare = false;
135         children = docType.iterateAxis(Axis.CHILD);
136
137         NodeInfo child = (NodeInfo) children.next();
138         if (child != null) {
139             write(out, " [");
140             openSquare = true;
141         }
142
143         while (child != null) {
144             String JavaDoc localname = child.getLocalPart();
145
146             if ("element".equals(localname)) {
147                 String JavaDoc elname = Navigator.getAttributeValue(child, "", "name");
148                 String JavaDoc content = Navigator.getAttributeValue(child, "", "content");
149                 if (elname == null) {
150                     DynamicError e = new DynamicError("dtd:element must have a name attribute");
151                     e.setXPathContext(context);
152                     throw e;
153                 }
154                 if (content == null) {
155                     DynamicError e = new DynamicError("dtd:element must have a content attribute");
156                     e.setXPathContext(context);
157                     throw e;
158                 }
159                 write(out, "\n <!ELEMENT " + elname + ' ' + content + '>');
160
161             } else if (localname.equals("attlist")) {
162                 String JavaDoc elname = Navigator.getAttributeValue(child, "", "element");
163                 if (elname == null) {
164                     DynamicError e = new DynamicError("dtd:attlist must have an attribute named 'element'");
165                     e.setXPathContext(context);
166                     throw e;
167                 }
168                 write(out, "\n <!ATTLIST " + elname + ' ');
169
170                 SequenceIterator attributes = child.iterateAxis(Axis.CHILD);
171                 while (true) {
172                     NodeInfo attDef = (NodeInfo) attributes.next();
173                     if (attDef == null) {
174                         break;
175                     }
176
177                     if ("attribute".equals(attDef.getLocalPart())) {
178
179                         String JavaDoc atname = Navigator.getAttributeValue(attDef, "", "name");
180                         String JavaDoc type = Navigator.getAttributeValue(attDef, "", "type");
181                         String JavaDoc value = Navigator.getAttributeValue(attDef, "", "value");
182                         if (atname == null) {
183                             DynamicError e = new DynamicError("dtd:attribute must have a name attribute");
184                             e.setXPathContext(context);
185                             throw e;
186                         }
187                         if (type == null) {
188                             DynamicError e = new DynamicError("dtd:attribute must have a type attribute");
189                             e.setXPathContext(context);
190                             throw e;
191                         }
192                         if (value == null) {
193                             DynamicError e = new DynamicError("dtd:attribute must have a value attribute");
194                             e.setXPathContext(context);
195                             throw e;
196                         }
197                         write(out, "\n " + atname + ' ' + type + ' ' + value);
198                     } else {
199                         DynamicError e = new DynamicError("Unrecognized element within dtd:attlist");
200                         e.setXPathContext(context);
201                         throw e;
202                     }
203                 }
204                 write(out, ">");
205
206             } else if (localname.equals("entity")) {
207
208                 String JavaDoc entname = Navigator.getAttributeValue(child, "", "name");
209                 String JavaDoc parameter = Navigator.getAttributeValue(child, "", "parameter");
210                 String JavaDoc esystem = Navigator.getAttributeValue(child, "", "system");
211                 String JavaDoc epublicid = Navigator.getAttributeValue(child, "", "public");
212                 String JavaDoc notation = Navigator.getAttributeValue(child, "", "notation");
213
214                 if (entname == null) {
215                     DynamicError e = new DynamicError("dtd:entity must have a name attribute");
216                     e.setXPathContext(context);
217                     throw e;
218                 }
219
220                 // we could do a lot more checking now...
221

222                 write(out, "\n <!ENTITY ");
223                 if ("yes".equals(parameter)) {
224                     write(out, "% ");
225                 }
226                 write(out, entname + ' ');
227                 if (esystem != null) {
228                     if (epublicid != null) {
229                         write(out, "PUBLIC \"" + epublicid + "\" \"" + esystem + "\" ");
230                     } else {
231                         write(out, "SYSTEM \"" + esystem + "\" ");
232                     }
233                 }
234                 if (notation != null) {
235                     write(out, "NDATA " + notation + ' ');
236                 }
237
238                 SequenceIterator contents = child.iterateAxis(Axis.CHILD);
239                 while (true) {
240                     NodeInfo content = (NodeInfo) contents.next();
241                     if (content == null) {
242                         break;
243                     }
244                     content.copy(out, NodeInfo.NO_NAMESPACES, false, locationId);
245                 }
246                 write(out, ">");
247
248             } else if (localname.equals("notation")) {
249                 String JavaDoc notname = Navigator.getAttributeValue(child, "", "name");
250                 String JavaDoc nsystem = Navigator.getAttributeValue(child, "", "system");
251                 String JavaDoc npublicid = Navigator.getAttributeValue(child, "", "public");
252                 if (notname == null) {
253                     DynamicError e = new DynamicError("dtd:notation must have a name attribute");
254                     e.setXPathContext(context);
255                     throw e;
256                 }
257                 if ((nsystem == null) && (npublicid == null)) {
258                     DynamicError e = new DynamicError("dtd:notation must have a system attribute or a public attribute");
259                     e.setXPathContext(context);
260                     throw e;
261                 }
262                 write(out, "\n <!NOTATION " + notname);
263                 if (npublicid != null) {
264                     write(out, " PUBLIC \"" + npublicid + "\" ");
265                     if (nsystem != null) {
266                         write(out, '\"' + nsystem + "\" ");
267                     }
268                 } else {
269                     write(out, " SYSTEM \"" + nsystem + "\" ");
270                 }
271                 write(out, ">");
272             } else {
273                 DynamicError e = new DynamicError("Unrecognized element " + localname + " in DTD output");
274                 e.setXPathContext(context);
275                 throw e;
276             }
277             child = (NodeInfo) children.next();
278         }
279
280         if (openSquare) {
281             write(out, "\n]");
282         }
283         write(out, ">\n");
284
285         return null;
286
287     }
288
289     private void write(Receiver out, String JavaDoc s) throws XPathException {
290         out.characters(s, locationId, ReceiverOptions.DISABLE_ESCAPING);
291     }
292
293     /**
294      * Diagnostic print of expression structure. The expression is written to the System.err
295      * output stream
296      *
297      * @param level indentation level for this expression
298      * @param out
299      */

300
301     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
302         out.println(ExpressionTool.indent(level) + "saxon:doctype");
303     }
304 }
305
306 //
307
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
308
// you may not use this file except in compliance with the License. You may obtain a copy of the
309
// License at http://www.mozilla.org/MPL/
310
//
311
// Software distributed under the License is distributed on an "AS IS" basis,
312
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
313
// See the License for the specific language governing rights and limitations under the License.
314
//
315
// The Original Code is: all this file.
316
//
317
// The Initial Developer of the Original Code is Michael H. Kay.
318
//
319
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
320
//
321
// Contributor(s): none.
322
//
323
Popular Tags