KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > style > XSLKey


1 package net.sf.saxon.style;
2 import net.sf.saxon.Err;
3 import net.sf.saxon.expr.*;
4 import net.sf.saxon.instruct.Executable;
5 import net.sf.saxon.instruct.SlotManager;
6 import net.sf.saxon.om.AttributeCollection;
7 import net.sf.saxon.om.Axis;
8 import net.sf.saxon.om.NamespaceException;
9 import net.sf.saxon.pattern.Pattern;
10 import net.sf.saxon.trans.KeyDefinition;
11 import net.sf.saxon.trans.KeyManager;
12 import net.sf.saxon.trans.XPathException;
13 import net.sf.saxon.type.Type;
14 import net.sf.saxon.value.SequenceType;
15
16 import javax.xml.transform.TransformerConfigurationException JavaDoc;
17 import java.text.Collator JavaDoc;
18 import java.util.Comparator JavaDoc;
19
20 /**
21 * Handler for xsl:key elements in stylesheet. <br>
22 */

23
24 public class XSLKey extends StyleElement implements StylesheetProcedure {
25
26     private Pattern match;
27     private Expression use;
28     private String JavaDoc collationName;
29     SlotManager stackFrameMap;
30                 // needed if variables are used
31
/**
32       * Determine whether this type of element is allowed to contain a sequence constructor
33       * @return true: yes, it may contain a sequence constructor
34       */

35
36     public boolean mayContainSequenceConstructor() {
37         return true;
38     }
39
40     /**
41      * Get the Procedure object that looks after any local variables declared in the content constructor
42      */

43
44     public SlotManager getSlotManager() {
45         return stackFrameMap;
46     }
47
48     public void prepareAttributes() throws XPathException {
49
50         String JavaDoc nameAtt = null;
51         String JavaDoc matchAtt = null;
52         String JavaDoc useAtt = null;
53
54         AttributeCollection atts = getAttributeList();
55
56         for (int a=0; a<atts.getLength(); a++) {
57             int nc = atts.getNameCode(a);
58             String JavaDoc f = getNamePool().getClarkName(nc);
59             if (f==StandardNames.NAME) {
60                 nameAtt = atts.getValue(a).trim();
61             } else if (f==StandardNames.USE) {
62                 useAtt = atts.getValue(a);
63             } else if (f==StandardNames.MATCH) {
64                 matchAtt = atts.getValue(a);
65             } else if (f==StandardNames.COLLATION) {
66                 collationName = atts.getValue(a).trim();
67             } else {
68                 checkUnknownAttribute(nc);
69             }
70         }
71
72         if (nameAtt==null) {
73             reportAbsence("name");
74             return;
75         }
76         try {
77             setObjectNameCode(makeNameCode(nameAtt.trim()));
78         } catch (NamespaceException err) {
79             compileError(err.getMessage(), "XTSE0280");
80         } catch (XPathException err) {
81             compileError(err);
82         }
83
84         if (matchAtt==null) {
85             reportAbsence("match");
86             matchAtt = "*";
87         }
88         match = makePattern(matchAtt);
89
90         if (useAtt!=null) {
91             use = makeExpression(useAtt);
92         }
93     }
94
95     public void validate() throws XPathException {
96
97         stackFrameMap = getConfiguration().makeSlotManager();
98         checkTopLevel(null);
99         if (use!=null) {
100             // the value can be supplied as a content constructor in place of a use expression
101
if (hasChildNodes()) {
102                 compileError("An xsl:key element with a @use attribute must be empty", "XTSE1205");
103             }
104             try {
105                 RoleLocator role =
106                     new RoleLocator(RoleLocator.INSTRUCTION, "xsl:key/use", 0, null);
107                 role.setSourceLocator(new ExpressionLocation(this));
108                 use = TypeChecker.staticTypeCheck(
109                                 use,
110                                 SequenceType.makeSequenceType(Type.ANY_ATOMIC_TYPE, StaticProperty.ALLOWS_ZERO_OR_MORE),
111                                 false, role, getStaticContext());
112             } catch (XPathException err) {
113                 compileError(err);
114             }
115         } else {
116             if (!hasChildNodes()) {
117                 compileError("An xsl:key element must either have a @use attribute or have content", "XTSE1205");
118             }
119         }
120         use = typeCheck("use", use);
121         match = typeCheck("match", match);
122
123         // Do a further check that the use expression makes sense in the context of the match pattern
124
if (use != null) {
125             use = use.typeCheck(getStaticContext(), match.getNodeTest());
126         }
127
128      }
129
130     public Expression compile(Executable exec) throws XPathException {
131
132         Collator JavaDoc collator = null;
133         if (collationName != null) {
134             Comparator JavaDoc comp = getPrincipalStylesheet().findCollation(collationName);
135             if (comp==null) {
136                  compileError("The collation name " + Err.wrap(collationName) + " is not recognized", "XTSE1210");
137             }
138             if (!(comp instanceof Collator JavaDoc)) {
139                 compileError("The collation used for xsl:key must be a java.text.Collator", "XTSE1210");
140             }
141             collator = (Collator JavaDoc)comp;
142         }
143
144         if (use==null) {
145             Expression body = compileSequenceConstructor(exec, iterateAxis(Axis.CHILD), true);
146             try {
147                 use = new Atomizer(body.simplify(getStaticContext()),
148                         getStaticContext().getConfiguration());
149             } catch (XPathException e) {
150                 compileError(e);
151             }
152
153             try {
154                 RoleLocator role =
155                     new RoleLocator(RoleLocator.INSTRUCTION, "xsl:key/use", 0, null);
156                 role.setSourceLocator(new ExpressionLocation(this));
157                 use = TypeChecker.staticTypeCheck(
158                                 use,
159                                 SequenceType.makeSequenceType(Type.ANY_ATOMIC_TYPE, StaticProperty.ALLOWS_ZERO_OR_MORE),
160                                 false, role, getStaticContext());
161                 // Do a further check that the use expression makes sense in the context of the match pattern
162
use = use.typeCheck(getStaticContext(), match.getNodeTest());
163
164             } catch (XPathException err) {
165                 compileError(err);
166             }
167         }
168
169         allocateSlots(use);
170
171
172         KeyManager km = getPrincipalStylesheet().getKeyManager();
173         KeyDefinition keydef = new KeyDefinition(match, use, collationName, collator);
174         keydef.setStackFrameMap(stackFrameMap);
175         keydef.setLocation(getSystemId(), getLineNumber());
176         keydef.setExecutable(getExecutable());
177         keydef.setBackwardsCompatible(backwardsCompatibleModeIsEnabled());
178         try {
179             km.addKeyDefinition(getObjectFingerprint(), keydef);
180         } catch (TransformerConfigurationException JavaDoc err) {
181             compileError(err);
182         }
183         return null;
184     }
185
186 }
187 //
188
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
189
// you may not use this file except in compliance with the License. You may obtain a copy of the
190
// License at http://www.mozilla.org/MPL/
191
//
192
// Software distributed under the License is distributed on an "AS IS" basis,
193
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
194
// See the License for the specific language governing rights and limitations under the License.
195
//
196
// The Original Code is: all this file.
197
//
198
// The Initial Developer of the Original Code is Michael H. Kay.
199
//
200
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
201
//
202
// Contributor(s): none.
203
//
204
Popular Tags