KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.sf.saxon.style;
2 import net.sf.saxon.Configuration;
3 import net.sf.saxon.Err;
4 import net.sf.saxon.expr.Expression;
5 import net.sf.saxon.expr.ExpressionTool;
6 import net.sf.saxon.expr.ErrorExpression;
7 import net.sf.saxon.instruct.Attribute;
8 import net.sf.saxon.instruct.Executable;
9 import net.sf.saxon.instruct.FixedAttribute;
10 import net.sf.saxon.om.*;
11 import net.sf.saxon.trans.XPathException;
12 import net.sf.saxon.trans.DynamicError;
13 import net.sf.saxon.type.SchemaType;
14 import net.sf.saxon.type.SimpleType;
15 import net.sf.saxon.value.StringValue;
16
17 /**
18 * xsl:attribute element in stylesheet. <br>
19 */

20
21 public final class XSLAttribute extends XSLStringConstructor {
22
23     private Expression attributeName;
24     private Expression separator;
25     private Expression namespace = null;
26     private int validationAction = Validation.PRESERVE;
27     private SimpleType schemaType;
28
29     public void prepareAttributes() throws XPathException {
30
31         AttributeCollection atts = getAttributeList();
32
33         String JavaDoc nameAtt = null;
34         String JavaDoc namespaceAtt = null;
35         String JavaDoc selectAtt = null;
36         String JavaDoc separatorAtt = null;
37         String JavaDoc validationAtt = null;
38         String JavaDoc typeAtt = null;
39
40         for (int a=0; a<atts.getLength(); a++) {
41             int nc = atts.getNameCode(a);
42             String JavaDoc f = getNamePool().getClarkName(nc);
43             if (f==StandardNames.NAME) {
44                 nameAtt = atts.getValue(a).trim();
45             } else if (f==StandardNames.NAMESPACE) {
46                 namespaceAtt = atts.getValue(a).trim();
47             } else if (f==StandardNames.SELECT) {
48                 selectAtt = atts.getValue(a);
49             } else if (f==StandardNames.SEPARATOR) {
50                 separatorAtt = atts.getValue(a);
51             } else if (f==StandardNames.VALIDATION) {
52                 validationAtt = atts.getValue(a).trim();
53             } else if (f==StandardNames.TYPE) {
54                 typeAtt = atts.getValue(a).trim();
55             } else {
56                 checkUnknownAttribute(nc);
57             }
58         }
59
60         if (nameAtt==null) {
61             reportAbsence("name");
62             return;
63         }
64         attributeName = makeAttributeValueTemplate(nameAtt);
65         if (attributeName instanceof StringValue) {
66             if (!Name.isQName(((StringValue)attributeName).getStringValue())) {
67                 invalidAttributeName("Attribute name " + Err.wrap(nameAtt) + " is not a valid QName");
68             }
69             if (nameAtt.equals("xmlns")) {
70                 if (namespace==null) {
71                     invalidAttributeName("Invalid attribute name: xmlns");
72                 }
73             }
74             if (nameAtt.startsWith("xmlns:")) {
75                 if (namespaceAtt == null) {
76                     invalidAttributeName("Invalid attribute name: " + Err.wrap(nameAtt));
77                 } else {
78                     // ignore the prefix "xmlns"
79
nameAtt = nameAtt.substring(6);
80                     attributeName = new StringValue(nameAtt);
81                 }
82             }
83         }
84
85
86         if (namespaceAtt!=null) {
87             namespace = makeAttributeValueTemplate(namespaceAtt);
88         }
89
90         if (selectAtt!=null) {
91             select = makeExpression(selectAtt);
92         }
93
94         if (separatorAtt == null) {
95             if (selectAtt == null) {
96                 separator = StringValue.EMPTY_STRING;
97             } else {
98                 separator = StringValue.SINGLE_SPACE;
99             }
100         } else {
101             separator = makeAttributeValueTemplate(separatorAtt);
102         }
103
104         if (validationAtt!=null) {
105             validationAction = Validation.getCode(validationAtt);
106             if (validationAction != Validation.STRIP && !getConfiguration().isSchemaAware(Configuration.XSLT)) {
107                 reportInvalidAttribute("To perform validation, a schema-aware XSLT processor is needed", "XTSE1660");
108                 validationAction = getContainingStylesheet().getDefaultValidation();
109             }
110             if (validationAction == Validation.INVALID) {
111                 reportInvalidAttribute("Invalid value of validation attribute", "XTSE0020");
112                 validationAction = getContainingStylesheet().getDefaultValidation();
113             }
114         } else {
115             validationAction = getContainingStylesheet().getDefaultValidation();
116         }
117
118         if (typeAtt!=null) {
119             if (!getConfiguration().isSchemaAware(Configuration.XSLT)) {
120                 reportInvalidAttribute(
121                         "The @type attribute is available only with a schema-aware XSLT processor", "XTSE1660");
122             } else {
123                 SchemaType type = getSchemaType(typeAtt);
124                 if (type == null) {
125                     reportInvalidAttribute("Unknown attribute type " + typeAtt, "XTSE1520");
126                 } else {
127                     if (type.isSimpleType()) {
128                         schemaType = (SimpleType)type;
129                     } else {
130                         reportInvalidAttribute("Type annotation for attributes must be a simple type", "XTSE1530");
131                         type = null;
132                     }
133                 }
134             }
135         }
136
137         if (typeAtt != null && validationAtt != null) {
138             reportInvalidAttribute("The validation and type attributes are mutually exclusive", "XTSE1505");
139             validationAction = getContainingStylesheet().getDefaultValidation();
140             schemaType = null;
141         }
142     }
143
144     private void invalidAttributeName(String JavaDoc message) throws XPathException {
145         if (forwardsCompatibleModeIsEnabled()) {
146             DynamicError err = new DynamicError(message);
147             err.setErrorCode("XTDE0850");
148             err.setLocator(this);
149             attributeName = new ErrorExpression(err);
150         } else {
151             compileError(message, "XTDE0850");
152             // prevent a duplicate error message...
153
attributeName = new StringValue("saxon-error-attribute");
154         }
155     }
156
157     public void validate() throws XPathException {
158         if (!(getParent() instanceof XSLAttributeSet)) {
159             checkWithinTemplate();
160         }
161         if (schemaType != null) {
162             if (schemaType.isNamespaceSensitive()) {
163                 compileError("Validation at attribute level must not specify a " +
164                         "namespace-sensitive type (xs:QName or xs:NOTATION)", "XTSE1545");
165             }
166         }
167         attributeName = typeCheck("name", attributeName);
168         namespace = typeCheck("namespace", namespace);
169         select = typeCheck("select", select);
170         separator = typeCheck("separator", separator);
171         super.validate();
172     }
173
174     public Expression compile(Executable exec) throws XPathException {
175         NamespaceResolver nsContext = null;
176
177         int annotation = getTypeAnnotation(schemaType);
178
179         // deal specially with the case where the attribute name is known statically
180

181         if (attributeName instanceof StringValue) {
182             String JavaDoc qName = ((StringValue)attributeName).getStringValue().trim();
183             String JavaDoc[] parts;
184             try {
185                 parts = Name.getQNameParts(qName);
186             } catch (QNameException e) {
187                 // This can't happen, because of previous checks
188
return null;
189             }
190
191
192             if (namespace==null) {
193                 String JavaDoc nsuri = "";
194                 if (!parts[0].equals("")) {
195                     nsuri = getURIForPrefix(parts[0], false);
196                     if (nsuri == null) {
197                         undeclaredNamespaceError(parts[0], "XTSE0280");
198                         return null;
199                     }
200                 }
201                 int nameCode = getTargetNamePool().allocate(parts[0], nsuri, parts[1]);
202                 FixedAttribute inst = new FixedAttribute(nameCode,
203                                                          validationAction,
204                                                          schemaType,
205                                                          annotation);
206                 inst.setParentExpression(this); // temporarily
207
compileContent(exec, inst, separator);
208                 //inst.setSeparator(separator);
209
ExpressionTool.makeParentReferences(inst);
210                 return inst;
211             } else if (namespace instanceof StringValue) {
212                 String JavaDoc nsuri = ((StringValue)namespace).getStringValue();
213                 if (nsuri.equals("")) {
214                     parts[0] = "";
215                 } else if (parts[0].equals("")) {
216                     // Need to choose an arbitrary prefix
217
// First see if the requested namespace is declared in the stylesheet
218
AxisIterator iter = iterateAxis(Axis.NAMESPACE);
219                     while (true) {
220                         NodeInfo ns = (NodeInfo)iter.next();
221                         if (ns == null) {
222                             break;
223                         }
224                         if (ns.getStringValue().equals(nsuri)) {
225                             parts[0] = ns.getLocalPart();
226                             break;
227                         }
228                     }
229                     // Otherwise see the URI is known to the namepool
230
if (parts[0].equals("")) {
231                         String JavaDoc p = getTargetNamePool().suggestPrefixForURI(
232                                 ((StringValue)namespace).getStringValue());
233                         if (p != null) {
234                             parts[0] = p;
235                         }
236                     }
237                     // Otherwise choose something arbitrary. This will get changed
238
// if it clashes with another attribute
239
if (parts[0].equals("")) {
240                         parts[0] = "ns0";
241                     }
242                 }
243                 int nameCode = getTargetNamePool().allocate(parts[0], nsuri, parts[1]);
244                 FixedAttribute inst = new FixedAttribute(nameCode,
245                                                          validationAction,
246                                                          schemaType,
247                                                          annotation);
248                 compileContent(exec, inst, separator);
249                 //inst.setSeparator(separator);
250
ExpressionTool.makeParentReferences(inst);
251                 return inst;
252             }
253         } else {
254             // if the namespace URI must be deduced at run-time from the attribute name
255
// prefix, we need to save the namespace context of the instruction
256

257             if (namespace==null) {
258                 nsContext = makeNamespaceContext();
259             }
260         }
261
262         Attribute inst = new Attribute( attributeName,
263                                         namespace,
264                                         nsContext,
265                                         validationAction,
266                                         schemaType,
267                                         annotation,
268                                         false);
269         compileContent(exec, inst, separator);
270         return inst;
271     }
272
273 }
274
275 //
276
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
277
// you may not use this file except in compliance with the License. You may obtain a copy of the
278
// License at http://www.mozilla.org/MPL/
279
//
280
// Software distributed under the License is distributed on an "AS IS" basis,
281
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
282
// See the License for the specific language governing rights and limitations under the License.
283
//
284
// The Original Code is: all this file.
285
//
286
// The Initial Developer of the Original Code is Michael H. Kay.
287
//
288
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
289
//
290
// Contributor(s): none.
291
//
292
Popular Tags