KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > type > ExternalObjectType


1 package net.sf.saxon.type;
2
3 import net.sf.saxon.expr.Expression;
4 import net.sf.saxon.expr.StaticContext;
5 import net.sf.saxon.instruct.ValueOf;
6 import net.sf.saxon.om.*;
7 import net.sf.saxon.style.StandardNames;
8 import net.sf.saxon.trans.XPathException;
9 import net.sf.saxon.value.AtomicValue;
10 import net.sf.saxon.value.ObjectValue;
11 import net.sf.saxon.value.Value;
12 import net.sf.saxon.value.Whitespace;
13 import net.sf.saxon.ConversionContext;
14
15 import java.io.Serializable JavaDoc;
16
17 /**
18  * This class represents the type of an external Java object returned by
19  * an extension function, or supplied as an external variable/parameter.
20  */

21
22 public class ExternalObjectType implements AtomicType, Serializable JavaDoc {
23
24     private Class JavaDoc javaClass;
25     int fingerprint;
26     int baseFingerprint = -1;
27
28     public ExternalObjectType(Class JavaDoc javaClass) {
29         this.javaClass = javaClass;
30         this.fingerprint = StandardNames.SAXON_JAVA_LANG_OBJECT;
31     }
32
33     /**
34      * Get the most specific possible atomic type that all items in this SimpleType belong to
35      * @return the lowest common supertype of all member types
36      */

37
38     public AtomicType getCommonAtomicType() {
39         return this;
40     }
41
42     /**
43      * Get the validation status - always valid
44      */

45     public final int getValidationStatus() {
46         return VALIDATED;
47     }
48
49     /**
50      * Returns the value of the 'block' attribute for this type, as a bit-signnificant
51      * integer with fields such as {@link SchemaType#DERIVATION_LIST} and {@link SchemaType#DERIVATION_EXTENSION}
52      *
53      * @return the value of the 'block' attribute for this type
54      */

55
56     public final int getBlock() {
57         return 0;
58     }
59
60     /**
61      * Gets the integer code of the derivation method used to derive this type from its
62      * parent. Returns zero for primitive types.
63      *
64      * @return a numeric code representing the derivation method, for example {@link SchemaType#DERIVATION_RESTRICTION}
65      */

66
67     public final int getDerivationMethod() {
68         return SchemaType.DERIVATION_RESTRICTION;
69     }
70
71     /**
72      * Determines whether derivation (of a particular kind)
73      * from this type is allowed, based on the "final" property
74      *
75      * @param derivation the kind of derivation, for example {@link SchemaType#DERIVATION_LIST}
76      * @return true if this kind of derivation is allowed
77      */

78
79     public final boolean allowsDerivation(int derivation) {
80         return true;
81     }
82
83     /**
84      * Get the namecode of the name of this type. This includes the prefix from the original
85      * type declaration: in the case of built-in types, there may be a conventional prefix
86      * or there may be no prefix.
87      */

88
89     public int getNameCode() {
90         return fingerprint;
91     }
92
93     /**
94      * Test whether this SchemaType is a complex type
95      *
96      * @return true if this SchemaType is a complex type
97      */

98
99     public final boolean isComplexType() {
100         return false;
101     }
102
103     /**
104      * Returns the base type that this type inherits from. This method can be used to get the
105      * base type of a type that is known to be valid.
106      * If this type is a Simpletype that is a built in primitive type then null is returned.
107      *
108      * @return the base type.
109      * @throws IllegalStateException if this type is not valid.
110      */

111
112     public final SchemaType getBaseType() {
113         return BuiltInSchemaFactory.getSchemaType(StandardNames.XDT_ANY_ATOMIC_TYPE);
114     }
115
116     /**
117      * Get the primitive item type corresponding to this item type. For item(),
118      * this is Type.ITEM. For node(), it is Type.NODE. For specific node kinds,
119      * it is the value representing the node kind, for example Type.ELEMENT.
120      * For anyAtomicValue it is Type.ATOMIC_VALUE. For numeric it is Type.NUMBER.
121      * For other atomic types it is the primitive type as defined in XML Schema,
122      * except that INTEGER is considered to be a primitive type.
123      */

124
125     public ItemType getPrimitiveItemType() {
126         return this;
127     }
128
129     /**
130      * Get the primitive type corresponding to this item type. For item(),
131      * this is Type.ITEM. For node(), it is Type.NODE. For specific node kinds,
132      * it is the value representing the node kind, for example Type.ELEMENT.
133      * For anyAtomicValue it is Type.ATOMIC. For numeric it is Type.NUMBER.
134      * For other atomic types it is the primitive type as defined in XML Schema,
135      * except that INTEGER is considered to be a primitive type.
136      */

137
138     public int getPrimitiveType() {
139         return Type.ATOMIC;
140     }
141
142     /**
143      * Produce a representation of this type name for use in error messages.
144      * Where this is a QName, it will use conventional prefixes
145      */

146
147     public String JavaDoc toString(NamePool pool) {
148         return getDisplayName();
149     }
150
151     /**
152      * Get the item type of the atomic values that will be produced when an item
153      * of this type is atomized
154      */

155
156     public AtomicType getAtomizedItemType() {
157         return this;
158     }
159
160     /**
161      * Returns the base type that this type inherits from. This method can be used to get the
162      * base type of a type that is known to be valid.
163      * If this type is a Simpletype that is a built in primitive type then null is returned.
164      *
165      * @return the base type.
166      * @throws IllegalStateException if this type is not valid.
167      */

168
169     public SchemaType getKnownBaseType() {
170         return getBaseType();
171     }
172
173     /**
174      * Test whether this is the same type as another type. They are considered to be the same type
175      * if they are derived from the same type definition in the original XML representation (which
176      * can happen when there are multiple includes of the same file)
177      */

178
179     public boolean isSameType(SchemaType other) {
180         return (other.getFingerprint() == this.getFingerprint());
181     }
182
183     public String JavaDoc getDescription() {
184         return getDisplayName();
185     }
186
187     /**
188      * Check that this type is validly derived from a given type
189      *
190      * @param type the type from which this type is derived
191      * @param block the derivations that are blocked by the relevant element declaration
192      * @throws SchemaException if the derivation is not allowed
193      */

194
195     public void isTypeDerivationOK(SchemaType type, int block) throws SchemaException, ValidationException {
196         return;
197     }
198
199     /**
200      * Returns true if this SchemaType is a SimpleType
201      *
202      * @return true (always)
203      */

204
205     public final boolean isSimpleType() {
206         return true;
207     }
208
209     /**
210      * Test whether this Simple Type is an atomic type
211      * @return true, this is considered to be an atomic type
212      */

213
214     public boolean isAtomicType() {
215         return true;
216     }
217
218
219     /**
220      * Returns true if this type is derived by list, or if it is derived by restriction
221      * from a list type, or if it is a union that contains a list as one of its members
222      *
223      * @return true if this is a list type
224      */

225
226     public boolean isListType() {
227         return false;
228     }
229
230     /**
231      * Return true if this type is a union type (that is, if its variety is union)
232      *
233      * @return true for a union type
234      */

235
236     public boolean isUnionType() {
237         return false;
238     }
239
240     /**
241      * Determine the whitespace normalization required for values of this type
242      *
243      * @return one of PRESERVE, REPLACE, COLLAPSE
244      */

245
246     public int getWhitespaceAction() {
247         return Whitespace.PRESERVE;
248     }
249
250     /**
251      * Apply the whitespace normalization rules for this simple type
252      *
253      * @param value the string before whitespace normalization
254      * @return the string after whitespace normalization
255      */

256
257     public CharSequence JavaDoc applyWhitespaceNormalization(CharSequence JavaDoc value) throws ValidationException {
258         return value;
259     }
260
261     /**
262      * Returns the built-in base type this type is derived from.
263      *
264      * @return the first built-in type found when searching up the type hierarchy
265      */

266     public SchemaType getBuiltInBaseType() throws ValidationException {
267         return this;
268     }
269
270     /**
271      * Test whether this simple type is namespace-sensitive, that is, whether
272      * it is derived from xs:QName or xs:NOTATION
273      *
274      * @return true if this type is derived from xs:QName or xs:NOTATION
275      */

276
277     public boolean isNamespaceSensitive() {
278         return false;
279     }
280
281     /**
282      * Get the typed value of a node that is annotated with this schema type
283      *
284      * @param node the node whose typed value is required
285      * @return an iterator over the items making up the typed value of this node. The objects
286      * returned by this SequenceIterator will all be of type {@link net.sf.saxon.value.AtomicValue}
287      */

288
289     public final SequenceIterator getTypedValue(NodeInfo node) {
290         throw new IllegalStateException JavaDoc("The type annotation of a node cannot be an external object type");
291     }
292
293     /**
294      * Get the typed value of a node that is annotated with this schema type. The result of this method will always be consistent with the method
295      * {@link #getTypedValue}. However, this method is often more convenient and may be
296      * more efficient, especially in the common case where the value is expected to be a singleton.
297      *
298      * @param node the node whose typed value is required
299      * @return the typed value.
300      * @since 8.5
301      */

302
303     public Value atomize(NodeInfo node) throws XPathException {
304         throw new IllegalStateException JavaDoc("The type annotation of a node cannot be an external object type");
305     }
306
307     /**
308      * Get the typed value corresponding to a given string value, assuming it is
309      * valid against this type
310      *
311      * @param value the string value
312      * @param resolver a namespace resolver used to resolve any namespace prefixes appearing
313      * in the content of values. Can supply null, in which case any namespace-sensitive content
314      * will be rejected.
315      * @param conversion
316      * @return an iterator over the atomic sequence comprising the typed value. The objects
317      * returned by this SequenceIterator will all be of type {@link net.sf.saxon.value.AtomicValue}
318      */

319
320     public SequenceIterator getTypedValue(CharSequence JavaDoc value, NamespaceResolver resolver, ConversionContext conversion)
321             throws ValidationException {
322         throw new ValidationException("Cannot validate a string against an external object type");
323     }
324
325
326     /**
327      * Factory method to create values of a derived atomic type. This method
328      * is not used to create values of a built-in type, even one that is not
329      * primitive.
330      *
331      * @param primValue the value in the value space of the primitive type
332      * @param lexicalValue the value in the lexical space. If null, the string value of primValue
333       * @param validate true if the value is to be validated against the facets of the derived
334      * type; false if the caller knows that the value is already valid.
335      */

336
337     public AtomicValue makeDerivedValue(AtomicValue primValue, CharSequence JavaDoc lexicalValue, boolean validate) {
338         throw new UnsupportedOperationException JavaDoc("makeDerivedValue is not supported for external object types");
339     }
340
341     /**
342      * Analyze an expression to see whether the expression is capable of delivering a value of this
343      * type.
344      *
345      * @param expression the expression that delivers the content
346      * @param kind the node kind whose content is being delivered: {@link Type#ELEMENT},
347      * {@link Type#ATTRIBUTE}, or {@link Type#DOCUMENT}
348      * @param env
349      * @throws net.sf.saxon.trans.XPathException
350      * if the expression will never deliver a value of the correct type
351      */

352
353     public void analyzeContentExpression(Expression expression, int kind, StaticContext env) throws XPathException {
354         analyzeContentExpression(this, expression, env, kind);
355     }
356
357    /**
358      * Analyze an expression to see whether the expression is capable of delivering a value of this
359      * type.
360      * @param simpleType the simple type against which the expression is to be checked
361      * @param expression the expression that delivers the content
362      * @param kind the node kind whose content is being delivered: {@link Type#ELEMENT},
363      * {@link Type#ATTRIBUTE}, or {@link Type#DOCUMENT}
364      * @throws net.sf.saxon.trans.XPathException
365      * if the expression will never deliver a value of the correct type
366      */

367
368     public static void analyzeContentExpression(SimpleType simpleType, Expression expression, StaticContext env, int kind)
369     throws XPathException {
370         if (kind == Type.ELEMENT) {
371             expression.checkPermittedContents(simpleType, env, true);
372         } else if (kind == Type.ATTRIBUTE) {
373             // for attributes, do a check only for text nodes and atomic values: anything else gets atomized
374
if (expression instanceof ValueOf || expression instanceof Value) {
375                 expression.checkPermittedContents(simpleType, env, true);
376             }
377         }
378     }
379
380
381     public Class JavaDoc getJavaClass() {
382         return javaClass;
383     }
384
385     public boolean isBuiltIn() {
386         return true;
387     }
388
389     public boolean matchesItem(Item item) {
390         if (item instanceof ObjectValue) {
391             Object JavaDoc obj = ((ObjectValue)item).getObject();
392             return javaClass.isAssignableFrom(obj.getClass());
393         }
394         return false;
395     }
396
397     /**
398      * Check whether a given input string is valid according to this SimpleType
399      * @param value the input string to be checked
400      * @param nsResolver a namespace resolver used to resolve namespace prefixes if the type
401      * is namespace sensitive. The value supplied may be null; in this case any namespace-sensitive
402      * content will throw an UnsupportedOperationException.
403      * @param conversion
404      * @return null if validation succeeds; return a ValidationException describing the validation failure
405      * if validation fails, unless throwException is true, in which case the exception is thrown rather than
406      * being returned.
407      * @throws UnsupportedOperationException if the type is namespace-sensitive and no namespace
408      * resolver is supplied
409      */

410
411     public ValidationException validateContent(CharSequence JavaDoc value, NamespaceResolver nsResolver, ConversionContext conversion) {
412         throw new UnsupportedOperationException JavaDoc("Cannot use an external object type for validation");
413     }
414
415     public ItemType getSuperType() {
416         // TODO: reflect the Java class hierarchy, to give better type checking
417
return Type.ANY_ATOMIC_TYPE;
418     }
419
420     public int getFingerprint() {
421         return StandardNames.SAXON_JAVA_LANG_OBJECT;
422     }
423
424     public String JavaDoc toString() {
425         String JavaDoc name = javaClass.getName();
426         name = name.replace('$', '-');
427         return "java:" + name;
428     }
429
430     public String JavaDoc getDisplayName() {
431         return toString();
432     }
433 }
434
435 //
436
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
437
// you may not use this file except in compliance with the License. You may obtain a copy of the
438
// License at http://www.mozilla.org/MPL/
439
//
440
// Software distributed under the License is distributed on an "AS IS" basis,
441
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
442
// See the License for the specific language governing rights and limitations under the License.
443
//
444
// The Original Code is: all this file.
445
//
446
// The Initial Developer of the Original Code is Saxonica Limited
447
//
448
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
449
//
450
// Contributor(s): none
451
//
Popular Tags