KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.sf.saxon.instruct;
2 import net.sf.saxon.event.Receiver;
3 import net.sf.saxon.expr.*;
4 import net.sf.saxon.om.NamePool;
5 import net.sf.saxon.om.Validation;
6 import net.sf.saxon.pattern.CombinedNodeTest;
7 import net.sf.saxon.pattern.ContentTypeTest;
8 import net.sf.saxon.pattern.NameTest;
9 import net.sf.saxon.style.StandardNames;
10 import net.sf.saxon.trace.InstructionInfo;
11 import net.sf.saxon.trace.Location;
12 import net.sf.saxon.trans.StaticError;
13 import net.sf.saxon.trans.XPathException;
14 import net.sf.saxon.type.*;
15
16 import java.io.PrintStream JavaDoc;
17
18
19 /**
20 * An instruction that creates an element node whose name is known statically.
21  * Used for literal results elements in XSLT, for direct element constructors
22  * in XQuery, and for xsl:element in cases where the name and namespace are
23  * known statically.
24 */

25
26 public class FixedElement extends ElementCreator {
27
28     private int nameCode;
29     protected int[] namespaceCodes = null;
30     private ItemType itemType;
31
32     /**
33      * Create an instruction that creates a new element node
34      * @param nameCode Represents the name of the element node
35      * @param namespaceCodes List of namespaces to be added to the element node.
36      * May be null if none are required.
37      * @param inheritNamespaces true if the children of this element are to inherit its namespaces
38      * @param schemaType Type annotation for the new element node
39      */

40     public FixedElement(int nameCode,
41                         int[] namespaceCodes,
42                         boolean inheritNamespaces,
43                         SchemaType schemaType,
44                         int validation) {
45         this.nameCode = nameCode;
46         this.namespaceCodes = namespaceCodes;
47         this.inheritNamespaces = inheritNamespaces;
48         setSchemaType(schemaType);
49         this.validation = validation;
50     }
51
52     public InstructionInfo getInstructionInfo() {
53         InstructionDetails details = (InstructionDetails)super.getInstructionInfo();
54         details.setConstructType(Location.LITERAL_RESULT_ELEMENT);
55         details.setObjectNameCode(nameCode);
56         return details;
57     }
58
59     /**
60      * Simplify an expression. This performs any static optimization (by rewriting the expression
61      * as a different expression).
62      *
63      * @return the simplified expression
64      * @throws net.sf.saxon.trans.XPathException
65      * if an error is discovered during expression rewriting
66      */

67
68     public Expression simplify(StaticContext env) throws XPathException {
69         setLazyConstruction(env.getConfiguration().isLazyConstructionMode());
70         if (getSchemaType() == null) {
71             if (validation == Validation.STRICT) {
72                 SchemaDeclaration decl = env.getConfiguration().getElementDeclaration(nameCode & 0xfffff);
73                 if (decl == null) {
74                     StaticError err = new StaticError("There is no global element declaration for " +
75                             env.getNamePool().getDisplayName(nameCode) +
76                             ", so strict validation will fail");
77                     err.setIsTypeError(true);
78                     err.setLocator(this);
79                     throw err;
80                 }
81                 setSchemaType(decl.getType());
82                 itemType = new CombinedNodeTest(
83                         new NameTest(Type.ELEMENT, nameCode, env.getNamePool()),
84                         Token.INTERSECT,
85                         new ContentTypeTest(Type.ELEMENT, getSchemaType(), env.getConfiguration()));
86                 getSchemaType().analyzeContentExpression(content, Type.ELEMENT, env);
87             } else if (validation == Validation.LAX) {
88                 SchemaDeclaration decl = env.getConfiguration().getElementDeclaration(nameCode & 0xfffff);
89                 if (decl == null) {
90                     env.issueWarning("There is no global element declaration for " +
91                             env.getNamePool().getDisplayName(nameCode) +
92                             ", so lax validation has no effect", this);
93                     itemType = new CombinedNodeTest(
94                         new NameTest(Type.ELEMENT, nameCode, env.getNamePool()),
95                         Token.INTERSECT,
96                         new ContentTypeTest(Type.ELEMENT,
97                                 BuiltInSchemaFactory.getSchemaType(StandardNames.XDT_UNTYPED),
98                                 env.getConfiguration()));
99                 } else {
100                     setSchemaType(decl.getType());
101                     itemType = new CombinedNodeTest(
102                             new NameTest(Type.ELEMENT, nameCode, env.getNamePool()),
103                             Token.INTERSECT,
104                             new ContentTypeTest(Type.ELEMENT, getSchemaType(), env.getConfiguration()));
105                     getSchemaType().analyzeContentExpression(content, Type.ELEMENT, env);
106                 }
107             } else if (validation == Validation.PRESERVE) {
108                 // we know the result will be an element of type xs:anyType
109
itemType = new CombinedNodeTest(
110                         new NameTest(Type.ELEMENT, nameCode, env.getNamePool()),
111                         Token.INTERSECT,
112                         new ContentTypeTest(Type.ELEMENT,
113                                 BuiltInSchemaFactory.getSchemaType(StandardNames.XS_ANY_TYPE),
114                                 env.getConfiguration()));
115             } else {
116                 // we know the result will be an untyped element
117
itemType = new CombinedNodeTest(
118                         new NameTest(Type.ELEMENT, nameCode, env.getNamePool()),
119                         Token.INTERSECT,
120                         new ContentTypeTest(Type.ELEMENT,
121                                 BuiltInSchemaFactory.getSchemaType(StandardNames.XDT_UNTYPED),
122                                 env.getConfiguration()));
123             }
124         } else {
125             itemType = new CombinedNodeTest(
126                     new NameTest(Type.ELEMENT, nameCode, env.getNamePool()),
127                     Token.INTERSECT,
128                     new ContentTypeTest(Type.ELEMENT, getSchemaType(), env.getConfiguration())
129             );
130             getSchemaType().analyzeContentExpression(content, Type.ELEMENT, env);
131         }
132         return super.simplify(env);
133     }
134
135     /**
136      * Get the type of the item returned by this instruction
137      * @return the item type
138      */

139     public ItemType getItemType() {
140         if (itemType == null) {
141             return super.getItemType();
142         }
143         return itemType;
144     }
145
146     /**
147      * Callback from the superclass ElementCreator to get the nameCode
148      * for the element name
149      * @param context The evaluation context (not used)
150      * @return the name code for the element name
151      */

152
153     public int getNameCode(XPathContext context) {
154         return nameCode;
155     }
156
157     /**
158      * Check that any elements and attributes constructed or returned by this expression are acceptable
159      * in the content model of a given complex type. It's always OK to say yes, since the check will be
160      * repeated at run-time. The process of checking element and attribute constructors against the content
161      * model of a complex type also registers the type of content expected of those constructors, so the
162      * static validation can continue recursively.
163      */

164
165     public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole) throws XPathException {
166         if (parentType instanceof SimpleType) {
167             StaticError err = new StaticError("Element " + env.getNamePool().getDisplayName(nameCode) +
168                     " is not permitted here: the containing element is of simple type " + parentType.getDescription());
169             err.setIsTypeError(true);
170             err.setLocator(this);
171             throw err;
172         } else if (((ComplexType)parentType).isSimpleContent()) {
173             StaticError err = new StaticError("Element " + env.getNamePool().getDisplayName(nameCode) +
174                     " is not permitted here: the containing element has a complex type with simple content");
175             err.setIsTypeError(true);
176             err.setLocator(this);
177             throw err;
178         }
179         SchemaType type;
180         try {
181             type = ((ComplexType)parentType).getElementParticleType(nameCode & 0xfffff);
182         } catch (SchemaException e) {
183             throw new StaticError(e);
184         }
185         if (type == null) {
186             if (parentType.allowsDerivation(SchemaType.DERIVATION_EXTENSION)) {
187                 // TODO: identify other cases where this can be a hard compile-time error
188
env.issueWarning("Element " + env.getNamePool().getDisplayName(nameCode) +
189                         " is not permitted in the content model of the complex type " +
190                         parentType.getDescription() +
191                         ". Validation will fail unless there is an extended type that permits this element", this);
192                 return;
193             } else {
194                 StaticError err = new StaticError("Element " + env.getNamePool().getDisplayName(nameCode) +
195                     " is not permitted in the content model of the complex type " +
196                     parentType.getDescription());
197                 err.setIsTypeError(true);
198                 err.setLocator(this);
199                 throw err;
200             }
201         }
202         if (type instanceof AnyType) {
203             return;
204         }
205
206         try {
207             content.checkPermittedContents(type, env, true);
208         } catch (XPathException e) {
209             if (e.getLocator() == null || e.getLocator() == e) {
210                 e.setLocator(this);
211             }
212             throw e;
213         }
214     }
215
216     /**
217      * Callback from the superclass ElementCreator to output the namespace nodes
218      * @param context The evaluation context (not used)
219      * @param out The receiver to handle the output
220      */

221
222     protected void outputNamespaceNodes(XPathContext context, Receiver out)
223     throws XPathException {
224         if (namespaceCodes != null) {
225             for (int i=0; i<namespaceCodes.length; i++) {
226                 out.namespace(namespaceCodes[i], 0);
227             }
228         }
229     }
230
231     /**
232      * Callback to get a list of the intrinsic namespaces that need to be generated for the element.
233      * The result is an array of namespace codes, the codes either occupy the whole array or are
234      * terminated by a -1 entry. A result of null is equivalent to a zero-length array.
235      */

236
237     public int[] getActiveNamespaces() throws XPathException {
238         return namespaceCodes;
239     }
240
241     /**
242      * Display this instruction as an expression, for diagnostics
243      */

244
245     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
246         out.println(ExpressionTool.indent(level) + "element ");
247         out.println(ExpressionTool.indent(level+1) + "name " +
248                 (pool==null ? nameCode+"" : pool.getDisplayName(nameCode)));
249         out.println(ExpressionTool.indent(level+1) + "content");
250         content.display(level+1, pool, out);
251     }
252 }
253
254 //
255
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
256
// you may not use this file except in compliance with the License. You may obtain a copy of the
257
// License at http://www.mozilla.org/MPL/
258
//
259
// Software distributed under the License is distributed on an "AS IS" basis,
260
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
261
// See the License for the specific language governing rights and limitations under the License.
262
//
263
// The Original Code is: all this file.
264
//
265
// The Initial Developer of the Original Code is Michael H. Kay.
266
//
267
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
268
//
269
// Contributor(s): none.
270
//
271
Popular Tags