KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > query > model > Identifier


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.query.model;
17
18 import org.outerj.daisy.query.QueryContext;
19 import org.outerj.daisy.repository.schema.FieldType;
20 import org.outerj.daisy.repository.schema.DocumentType;
21 import org.outerj.daisy.repository.schema.DocumentTypeNotFoundException;
22 import org.outerj.daisy.repository.schema.PartType;
23 import org.outerj.daisy.repository.*;
24 import org.outerj.daisy.repository.query.QueryException;
25 import org.outerj.daisy.repository.query.EvaluationContext;
26 import org.outerj.daisy.repository.variant.Branch;
27 import org.outerj.daisy.repository.variant.Language;
28 import org.outerj.daisy.xmlutil.LocalSAXParserFactory;
29 import org.apache.xmlbeans.XmlObject;
30 import org.apache.xmlbeans.XmlCursor;
31 import org.apache.xmlbeans.XmlOptions;
32
33 import java.sql.PreparedStatement JavaDoc;
34 import java.sql.SQLException JavaDoc;
35 import java.util.Map JavaDoc;
36 import java.util.HashMap JavaDoc;
37 import java.util.Locale JavaDoc;
38 import java.util.ResourceBundle JavaDoc;
39 import java.lang.reflect.Constructor JavaDoc;
40 import java.io.ByteArrayInputStream JavaDoc;
41
42 public final class Identifier implements ValueExpr, Cloneable JavaDoc {
43     private final String JavaDoc id;
44     private DelegateIdentifier delegate;
45     private QueryContext queryContext;
46     private int line = -1;
47     private int column = -1;
48     private static final Map JavaDoc delegateClasses = new HashMap JavaDoc();
49     static {
50         try {
51             delegateClasses.put(DocumentTypeIdentifier.NAME, DocumentTypeIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
52             delegateClasses.put(DocumentNameIdentifier.NAME, DocumentNameIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
53             delegateClasses.put(CreationTimeIdentifier.NAME, CreationTimeIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
54             delegateClasses.put(DocumentIdIdentifier.NAME, DocumentIdIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
55             delegateClasses.put(DocumentLinkIdentifier.NAME, DocumentLinkIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
56             delegateClasses.put(SummaryIdentifier.NAME, SummaryIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
57             delegateClasses.put(VersionCreationTimeIdentifier.NAME, VersionCreationTimeIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
58             delegateClasses.put(VersionCreatorIdIdentifier.NAME, VersionCreatorIdIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
59             delegateClasses.put(VersionCreatorNameIdentifier.NAME, VersionCreatorNameIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
60             delegateClasses.put(VersionCreatorLoginIdentifier.NAME, VersionCreatorLoginIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
61             delegateClasses.put(VersionStateIdentifier.NAME, VersionStateIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
62             delegateClasses.put(TotalSizeOfPartsIdentifier.NAME, TotalSizeOfPartsIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
63             delegateClasses.put(VersionStateLastModifiedIdentifier.NAME, VersionStateLastModifiedIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
64             delegateClasses.put(RetiredIdentifier.NAME, RetiredIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
65             delegateClasses.put(PrivateIdentifier.NAME, PrivateIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
66             delegateClasses.put(LockTypeIdentifier.NAME, LockTypeIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
67             delegateClasses.put(LockOwnerIdIdentifier.NAME, LockOwnerIdIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
68             delegateClasses.put(LockOwnerLoginIdentifier.NAME, LockOwnerLoginIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
69             delegateClasses.put(LockOwnerNameIdentifier.NAME, LockOwnerNameIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
70             delegateClasses.put(LockDurationIdentifier.NAME, LockDurationIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
71             delegateClasses.put(LockTimeAcquiredIdentifier.NAME, LockTimeAcquiredIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
72             delegateClasses.put(OwnerIdIdentifier.NAME, OwnerIdIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
73             delegateClasses.put(OwnerLoginIdentifier.NAME, OwnerLoginIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
74             delegateClasses.put(OwnerNameIdentifier.NAME, OwnerNameIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
75             delegateClasses.put(LastModifierIdIdentifier.NAME, LastModifierIdIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
76             delegateClasses.put(LastModifierLoginIdentifier.NAME, LastModifierLoginIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
77             delegateClasses.put(LastModifierNameIdentifier.NAME, LastModifierNameIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
78             delegateClasses.put(LastModifiedIdentifier.NAME, LastModifiedIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
79             delegateClasses.put(BranchIdIdentifier.NAME, BranchIdIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
80             delegateClasses.put(BranchNameIdentifier.NAME, BranchNameIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
81             delegateClasses.put(LanguageIdIdentifier.NAME, LanguageIdIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
82             delegateClasses.put(LanguageNameIdentifier.NAME, LanguageNameIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
83             delegateClasses.put(VariantLastModifiedIdentifier.NAME, VariantLastModifiedIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
84             delegateClasses.put(VariantLastModifierIdIdentifier.NAME, VariantLastModifierIdIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
85             delegateClasses.put(VariantLastModifierLoginIdentifier.NAME, VariantLastModifierLoginIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
86             delegateClasses.put(VariantLastModifierNameIdentifier.NAME, VariantLastModifierNameIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
87             delegateClasses.put(CollectionsIdentifier.NAME, CollectionsIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
88             delegateClasses.put(CollectionsValueCountIdentifier.NAME, CollectionsValueCountIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
89             delegateClasses.put(VersionIdIdentifier.NAME, VersionIdIdentifier.class.getConstructor(new Class JavaDoc[] { Identifier.class }));
90         } catch (Exception JavaDoc e) {
91             throw new RuntimeException JavaDoc("Error initializing delegate identifier map.", e);
92         }
93     }
94     private static final QValueType[] valueTypeToOutputValueType;
95     static {
96         valueTypeToOutputValueType = new QValueType[9];
97         valueTypeToOutputValueType[ValueType.STRING.getCode()] = QValueType.STRING;
98         valueTypeToOutputValueType[ValueType.DATE.getCode()] = QValueType.DATE;
99         valueTypeToOutputValueType[ValueType.DATETIME.getCode()] = QValueType.DATETIME;
100         valueTypeToOutputValueType[ValueType.LONG.getCode()] = QValueType.LONG;
101         valueTypeToOutputValueType[ValueType.DOUBLE.getCode()] = QValueType.DOUBLE;
102         valueTypeToOutputValueType[ValueType.DECIMAL.getCode()] = QValueType.DECIMAL;
103         valueTypeToOutputValueType[ValueType.BOOLEAN.getCode()] = QValueType.BOOLEAN;
104         valueTypeToOutputValueType[ValueType.LINK.getCode()] = QValueType.LINK;
105     }
106     private static final long CONTENT_INCLUDE_LIMIT = 200000; // about 200k
107

108     public Identifier(String JavaDoc id) {
109         this.id = id;
110     }
111
112     protected Identifier(String JavaDoc id, QueryContext context, DelegateIdentifier delegate) {
113         this.id = id;
114         this.queryContext = context;
115         this.delegate = delegate;
116     }
117
118     protected Object JavaDoc clone() {
119         Identifier clone = new Identifier(this.id);
120         try {
121             if (this.queryContext != null)
122                 clone.prepare(this.queryContext);
123         } catch (QueryException e) {
124             throw new RuntimeException JavaDoc("Unexpected exception while cloning identifier", e);
125         }
126         return clone;
127     }
128
129     public void setLocation(int line, int column) {
130         this.line = line;
131         this.column = column;
132     }
133
134     public String JavaDoc getLocation() {
135         if (line == -1 && column == -1)
136             return "(location unknown)";
137         else
138             return "line " + line + ", column " + column;
139     }
140
141     public int getLine() {
142         return line;
143     }
144
145     public int getColumn() {
146         return column;
147     }
148
149     public void prepare(QueryContext context) throws QueryException {
150         this.queryContext = context;
151         if (id.charAt(0) == '$') { // id's starting with $ represent fields
152
String JavaDoc fieldName = id.substring(1);
153
154             // a field name can optionally be followed by "dot something".
155
String JavaDoc subFieldId = null;
156             int dotPos = fieldName.indexOf('.');
157             if (dotPos != -1) {
158                 subFieldId = fieldName.substring(dotPos + 1);
159                 fieldName = fieldName.substring(0, dotPos);
160             }
161
162             FieldType fieldType;
163             try {
164                 fieldType = context.getFieldTypeByName(fieldName);
165             } catch (RepositoryException e) {
166                 throw new QueryException("Error with identifier \"" + id + "\".", e);
167             }
168
169             if (subFieldId == null) {
170                 this.delegate = new FieldIdentifier(fieldType);
171             } else if (subFieldId.equals(FieldValueCountIdentifier.NAME)) {
172                 this.delegate = new FieldValueCountIdentifier(fieldType);
173             } else if (subFieldId.equals(LinkFieldDocumentIdIdentifier.NAME)) {
174                 if (fieldType.getValueType() != ValueType.LINK)
175                     throw new QueryException("Sub-field identifier " + LinkFieldDocumentIdIdentifier.NAME + " can only be used with link-type fields.");
176                 this.delegate = new LinkFieldDocumentIdIdentifier(fieldType);
177             } else if (subFieldId.equals(LinkFieldBranchIdIdentifier.NAME)) {
178                 if (fieldType.getValueType() != ValueType.LINK)
179                     throw new QueryException("Sub-field identifier " + LinkFieldBranchIdIdentifier.NAME + " can only be used with link-type fields.");
180                 this.delegate = new LinkFieldBranchIdIdentifier(fieldType);
181             } else if (subFieldId.equals(LinkFieldLanguageIdIdentifier.NAME)) {
182                 if (fieldType.getValueType() != ValueType.LINK)
183                     throw new QueryException("Sub-field identifier " + LinkFieldLanguageIdIdentifier.NAME + " can only be used with link-type fields.");
184                 this.delegate = new LinkFieldLanguageIdIdentifier(fieldType);
185             } else if (subFieldId.equals(LinkFieldBranchIdentifier.NAME)) {
186                 if (fieldType.getValueType() != ValueType.LINK)
187                     throw new QueryException("Sub-field identifier " + LinkFieldBranchIdentifier.NAME + " can only be used with link-type fields.");
188                 this.delegate = new LinkFieldBranchIdentifier(fieldType);
189             } else if (subFieldId.equals(LinkFieldLanguageIdentifier.NAME)) {
190                 if (fieldType.getValueType() != ValueType.LINK)
191                     throw new QueryException("Sub-field identifier " + LinkFieldLanguageIdentifier.NAME + " can only be used with link-type fields.");
192                 this.delegate = new LinkFieldLanguageIdentifier(fieldType);
193             } else {
194                 throw new QueryException("Invalid sub-field identifier: " + subFieldId);
195             }
196         } else if (id.charAt(0) == '%') { // id's starting with % represent parts
197
String JavaDoc partId = id.substring(1);
198             int dotPos = partId.indexOf('.');
199             if (dotPos == -1)
200                 throw new QueryException("Identifier \"" + id + "\": missing sub-part identifier (ie a dot followed by what information of the part to use).");
201             String JavaDoc subPartId = partId.substring(dotPos + 1);
202             String JavaDoc partName = partId.substring(0, dotPos);
203
204             PartType partType;
205             try {
206                 partType = context.getPartTypeByName(partName);
207             } catch (RepositoryException e) {
208                 throw new QueryException("Error with identifier \"" + id + "\".", e);
209             }
210
211             if (subPartId.equals("content")) {
212                 this.delegate = new PartContentIdentifier(id, partType);
213             } else if (subPartId.equals("mimeType")) {
214                 this.delegate = new PartMimeTypeIdentifier(id, partType);
215             } else if (subPartId.equals("size")) {
216                 this.delegate = new PartSizeIdentifier(id, partType);
217             } else {
218                 throw new QueryException("Identifier \"" + id + "\": invalid subpart id \"" + subPartId + "\".");
219             }
220         } else if (id.charAt(0) == '#') {
221             String JavaDoc customFieldName = id.substring(1);
222             this.delegate = new CustomFieldIdentifier(customFieldName);
223         } else {
224             Constructor JavaDoc constructor = (Constructor JavaDoc)delegateClasses.get(id);
225             if (constructor == null) {
226                 throw new QueryException("Unknown identifier: \"" + id + "\".");
227             } else {
228                 try {
229                     this.delegate = (DelegateIdentifier)constructor.newInstance(new Object JavaDoc[] { this });
230                 } catch (Exception JavaDoc e) {
231                     throw new QueryException("Error instantiating identifier class.", e);
232                 }
233             }
234         }
235     }
236
237     public Object JavaDoc evaluate(QValueType valueType, EvaluationContext evaluationContext) {
238         throw new RuntimeException JavaDoc("Identifier \"" + getExpression() + "\"is used in a place where it cannot be evaluated.");
239     }
240
241     public Object JavaDoc evaluate(QValueType valueType, Document document, Version version, EvaluationContext evaluationContext) throws QueryException {
242         return delegate.evaluate(document, version);
243     }
244
245     public String JavaDoc getSqlPreConditions(SqlGenerationContext context) throws QueryException {
246         return delegate.getSqlPreConditions(context);
247     }
248
249     public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) throws QueryException {
250         delegate.generateSqlValueExpr(sql, context);
251     }
252
253     public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc, QueryException {
254         return delegate.bindPreConditions(stmt, bindPos);
255     }
256
257     public int bindValueExpr(PreparedStatement JavaDoc stmt, int bindPos, QValueType valueType,
258             EvaluationContext evaluationContext) throws SQLException JavaDoc, QueryException {
259         return delegate.bindValueExpr(stmt, bindPos, valueType);
260     }
261
262     public QValueType getValueType() {
263         return delegate.getValueType();
264     }
265
266     public boolean isMultiValue() {
267         return delegate.isMultiValue();
268     }
269
270     public boolean isComparable() {
271         return getValueType() != QValueType.BOOLEAN && getValueType() != QValueType.UNDEFINED && !isMultiValue();
272     }
273
274     public QValueType getOutputValueType() {
275         return delegate.getOutputValueType();
276     }
277
278     public final Object JavaDoc getOutputValue(Document document, Version version, EvaluationContext evaluationContext) {
279         return delegate.getOutputValue(document, version);
280     }
281
282     public String JavaDoc getTitle(Locale JavaDoc locale) {
283         return delegate.getTitle(locale);
284     }
285
286     public String JavaDoc getExpression() {
287         return id;
288     }
289
290     /**
291      * May this identifier be used in ACL evaluation expressions?
292      */

293     public AclConditionViolation isAclAllowed() {
294         return delegate.isAclAllowed();
295     }
296
297     /**
298      * Must only be implemented by classes for which
299      * isAclAllowed returns null.
300      */

301     public boolean canTestAppliesTo() {
302         return delegate.canTestappliesTo();
303     }
304
305     public boolean isSymbolicIdentifier() {
306         return delegate.isSymbolic();
307     }
308
309     public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
310         return delegate.translateSymbolic(valueExpr, evaluationContext);
311     }
312
313     /**
314      * If true, then this identifier does not present a field on which can be searched,
315      * and only the method getOutputValue should be called on it.
316      */

317     public boolean isOutputOnly() {
318         return delegate.isOutputOnly();
319     }
320
321     public DelegateIdentifier getDelegate() {
322         return delegate;
323     }
324
325     /**
326      * If isMultiValue() returns true, this method returns the corresponding value count
327      * identifier.
328      */

329     Identifier getValueCountIdentifier() {
330         return delegate.getValueCountIdentifier();
331     }
332
333     interface DelegateIdentifier {
334         QValueType getValueType();
335         boolean isMultiValue();
336         Identifier getValueCountIdentifier();
337         Object JavaDoc evaluate(Document document, Version version) throws QueryException;
338         AclConditionViolation isAclAllowed();
339         String JavaDoc getSqlPreConditions(SqlGenerationContext context) throws QueryException;
340         void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) throws QueryException;
341         int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc, QueryException;
342         public int bindValueExpr(PreparedStatement JavaDoc stmt, int bindPos, QValueType valueType) throws SQLException JavaDoc, QueryException;
343         boolean isSymbolic();
344         Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException;
345         QValueType getOutputValueType();
346         Object JavaDoc getOutputValue(Document document, Version version);
347         boolean canTestappliesTo();
348         boolean isOutputOnly();
349         String JavaDoc getName();
350         String JavaDoc getTitle(Locale JavaDoc locale);
351     }
352
353     public abstract class AbstractIdentifier implements DelegateIdentifier {
354         public boolean isMultiValue() {
355             return false;
356         }
357
358         public Identifier getValueCountIdentifier() {
359             return null;
360         }
361
362         public AclConditionViolation isAclAllowed() {
363             return null;
364         }
365
366         public String JavaDoc getTitle(Locale JavaDoc locale) {
367             return getLocalizedString(getName(), locale);
368         }
369
370         public boolean isSymbolic() {
371             return false;
372         }
373
374         public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
375             throw new QueryException("translateSymbolic should not be called if isSymbolic returns false");
376         }
377
378         public boolean canTestappliesTo() {
379             return false;
380         }
381
382         public String JavaDoc getSqlPreConditions(SqlGenerationContext context) throws QueryException {
383             return null;
384         }
385
386         public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc, QueryException {
387             return bindPos;
388         }
389
390         public int bindValueExpr(PreparedStatement JavaDoc stmt, int bindPos, QValueType valueType) throws SQLException JavaDoc, QueryException {
391             return bindPos;
392         }
393
394         public boolean isOutputOnly() {
395             return false;
396         }
397     }
398
399     public abstract class AbstractNonAclIdentifier extends AbstractIdentifier {
400         public AclConditionViolation isAclAllowed() {
401             return new AclConditionViolation("Identifier '" + getName() + "' is not allowed in ACL conditions.");
402         }
403     }
404
405     public final class FieldIdentifier extends AbstractIdentifier {
406         private FieldType fieldType;
407         private String JavaDoc alias;
408         private QValueType valueType;
409
410         public FieldIdentifier(FieldType fieldType) {
411             this.fieldType = fieldType;
412         }
413
414         public String JavaDoc getName() {
415             return "$" + fieldType.getName();
416         }
417
418         public long getfieldTypeId() {
419             return fieldType.getId();
420         }
421
422         public QValueType getValueType() {
423             if (valueType == null) {
424                 ValueType fieldValueType = fieldType.getValueType();
425                 if (fieldValueType == ValueType.STRING)
426                     valueType = QValueType.STRING;
427                 else if (fieldValueType == ValueType.DATE)
428                     valueType = QValueType.DATE;
429                 else if (fieldValueType == ValueType.DATETIME)
430                     valueType = QValueType.DATETIME;
431                 else if (fieldValueType == ValueType.LONG)
432                     valueType = QValueType.LONG;
433                 else if (fieldValueType == ValueType.DOUBLE)
434                     valueType = QValueType.DOUBLE;
435                 else if (fieldValueType == ValueType.DECIMAL)
436                     valueType = QValueType.DECIMAL;
437                 else if (fieldValueType == ValueType.BOOLEAN)
438                     valueType = QValueType.BOOLEAN;
439                 else if (fieldValueType == ValueType.LINK)
440                     valueType = QValueType.LINK;
441                 else
442                     throw new RuntimeException JavaDoc("Unrecognized field value type: " + fieldValueType);
443             }
444             return valueType;
445         }
446
447         public boolean isMultiValue() {
448             return fieldType.isMultiValue();
449         }
450
451         public Identifier getValueCountIdentifier() {
452             return new Identifier(getName() + ".valueCount", queryContext, new FieldValueCountIdentifier(fieldType));
453         }
454
455         public Object JavaDoc evaluate(Document document, Version version) {
456             if (version != null && version.hasField(fieldType.getId()))
457                 return processValue(version.getField(fieldType.getId()).getValue(), document);
458             else if (version == null && document.hasField(fieldType.getId()))
459                 return processValue(document.getField(fieldType.getId()).getValue(), document);
460             else
461                 return null;
462         }
463
464         private Object JavaDoc processValue(Object JavaDoc value, Document document) {
465             if (fieldType.getValueType() == ValueType.LINK) {
466                 if (fieldType.isMultiValue()) {
467                     Object JavaDoc[] values = (Object JavaDoc[])value;
468                     VariantKey[] keys = new VariantKey[values.length];
469                     for (int i = 0; i < values.length; i++) {
470                         VariantKey key = (VariantKey)values[i];
471                         if (key.getBranchId() == -1 || key.getLanguageId() == -1) {
472                             keys[i] = new VariantKey(key.getDocumentId(),
473                                     key.getBranchId() == -1 ? document.getBranchId() : key.getBranchId(),
474                                     key.getLanguageId() == -1 ? document.getLanguageId() : key.getLanguageId());
475                         } else {
476                             keys[i] = key;
477                         }
478                     }
479                     return keys;
480                 } else {
481                     VariantKey key = (VariantKey)value;
482                     if (key.getBranchId() == -1 || key.getLanguageId() == -1)
483                         return new VariantKey(key.getDocumentId(),
484                                 key.getBranchId() == -1 ? document.getBranchId() : key.getBranchId(),
485                                 key.getLanguageId() == -1 ? document.getLanguageId() : key.getLanguageId());
486                     else
487                         return key;
488                 }
489             } else {
490                 return value;
491             }
492         }
493
494         public QValueType getOutputValueType() {
495             return valueTypeToOutputValueType[fieldType.getValueType().getCode()];
496         }
497
498         public Object JavaDoc getOutputValue(Document document, Version version) {
499             return evaluate(document, version);
500         }
501
502         public AclConditionViolation isAclAllowed() {
503             if (!fieldType.isAclAllowed()) {
504                 return new AclConditionViolation("Field \"" + fieldType.getName() + "\" (ID: " + fieldType.getId() + ") may not be used in ACL object expressions.");
505             } else {
506                 return null;
507             }
508         }
509
510         public boolean canTestappliesTo() {
511             return false;
512         }
513
514         public String JavaDoc getSqlPreConditions(SqlGenerationContext context) {
515             alias = context.getNewFieldsTableAlias();
516             return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? ";
517         }
518
519         public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
520             String JavaDoc valueColumn = SqlGenerationContext.FieldsTable.getValueColumn(getValueType());
521             sql.append(alias).append(".").append(valueColumn);
522         }
523
524         public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc {
525             stmt.setLong(bindPos, fieldType.getId());
526             return ++bindPos;
527         }
528
529         public String JavaDoc getTitle(Locale JavaDoc locale) {
530             return fieldType.getLabel(locale);
531         }
532     }
533
534     public final class FieldValueCountIdentifier extends AbstractNonAclIdentifier {
535         static final String JavaDoc NAME = "valueCount";
536         private final FieldType fieldType;
537         private String JavaDoc alias;
538
539         public FieldValueCountIdentifier(FieldType fieldType) {
540             this.fieldType = fieldType;
541         }
542
543         public String JavaDoc getTitle(Locale JavaDoc locale) {
544             String JavaDoc fieldLabel = fieldType.getLabel(locale);
545             String JavaDoc valueCount = getLocalizedString("fieldValueCount", locale);
546             return fieldLabel + ": " + valueCount;
547         }
548
549         public QValueType getValueType() {
550             return QValueType.LONG;
551         }
552
553         public Object JavaDoc evaluate(Document document, Version version) {
554             if (version != null && version.hasField(fieldType.getId())) {
555                 if (fieldType.isMultiValue()) {
556                     return new Long JavaDoc(((Object JavaDoc[])version.getField(fieldType.getId()).getValue()).length);
557                 } else {
558                     return new Long JavaDoc(1);
559                 }
560             } else if (version == null && document.hasField(fieldType.getId())) {
561                 if (fieldType.isMultiValue()) {
562                     return new Long JavaDoc(((Object JavaDoc[])document.getField(fieldType.getId()).getValue()).length);
563                 } else {
564                     return new Long JavaDoc(1);
565                 }
566             } else {
567                 return new Long JavaDoc(0);
568             }
569         }
570
571         public String JavaDoc getSqlPreConditions(SqlGenerationContext context) {
572             alias = context.getNewFieldsTableAlias();
573             return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? ";
574         }
575
576         public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
577             sql.append(alias).append('.').append("value_count");
578         }
579
580         public QValueType getOutputValueType() {
581             return QValueType.LONG;
582         }
583
584         public Object JavaDoc getOutputValue(Document document, Version version) {
585             return evaluate(document, version);
586         }
587
588         public String JavaDoc getName() {
589             return "$" + fieldType.getName() + "." + NAME;
590         }
591
592         public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc {
593             stmt.setLong(bindPos, fieldType.getId());
594             return ++bindPos;
595         }
596     }
597
598     public final class LinkFieldDocumentIdIdentifier extends AbstractIdentifier {
599         public static final String JavaDoc NAME = "documentId";
600         private final FieldType fieldType;
601         private String JavaDoc alias;
602
603         public LinkFieldDocumentIdIdentifier(FieldType fieldType) {
604             this.fieldType = fieldType;
605         }
606
607         public String JavaDoc getName() {
608             return "$" + fieldType.getName() + "." + NAME;
609         }
610
611         public boolean isMultiValue() {
612             return fieldType.isMultiValue();
613         }
614
615         public QValueType getValueType() {
616             return QValueType.LONG;
617         }
618
619         public Object JavaDoc evaluate(Document document, Version version) {
620             if (version != null && version.hasField(fieldType.getId())) {
621                 Object JavaDoc value = version.getField(fieldType.getId()).getValue();
622                 return extractDocIds(value);
623             } else if (version == null && document.hasField(fieldType.getId())) {
624                 VariantKey value = (VariantKey)document.getField(fieldType.getId()).getValue();
625                 return extractDocIds(value);
626             } else {
627                 return null;
628             }
629         }
630
631         private Object JavaDoc extractDocIds(Object JavaDoc value) {
632             if (fieldType.isMultiValue()) {
633                 Object JavaDoc[] values = (Object JavaDoc[])value;
634                 Long JavaDoc[] ids = new Long JavaDoc[values.length];
635                 for (int i = 0; i < values.length; i++)
636                     ids[i] = new Long JavaDoc(((VariantKey)values[i]).getDocumentId());
637                 return ids;
638             } else {
639                 return new Long JavaDoc(((VariantKey)value).getDocumentId());
640             }
641         }
642
643         public String JavaDoc getSqlPreConditions(SqlGenerationContext context) {
644             alias = context.getNewFieldsTableAlias();
645             return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? ";
646         }
647
648         public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc {
649             stmt.setLong(bindPos, fieldType.getId());
650             return ++bindPos;
651         }
652
653         public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
654             sql.append(alias).append('.').append(SqlGenerationContext.FieldsTable.LINK_DOCID);
655         }
656
657         public QValueType getOutputValueType() {
658             return QValueType.LONG;
659         }
660
661         public Object JavaDoc getOutputValue(Document document, Version version) {
662             return evaluate(document, version);
663         }
664
665         public String JavaDoc getTitle(Locale JavaDoc locale) {
666             String JavaDoc fieldLabel = fieldType.getLabel(locale);
667             String JavaDoc branchId = getLocalizedString("id", locale);
668             return fieldLabel + ": " + branchId;
669         }
670     }
671
672     public class LinkFieldBranchIdIdentifier extends AbstractIdentifier {
673         public static final String JavaDoc NAME = "branchId";
674         protected final FieldType fieldType;
675         private String JavaDoc alias;
676
677         public LinkFieldBranchIdIdentifier(FieldType fieldType) {
678             this.fieldType = fieldType;
679         }
680
681         public String JavaDoc getName() {
682             return "$" + fieldType.getName() + "." + NAME;
683         }
684
685         public QValueType getValueType() {
686             return QValueType.LONG;
687         }
688
689         public boolean isMultiValue() {
690             return fieldType.isMultiValue();
691         }
692
693         public Object JavaDoc evaluate(Document document, Version version) {
694             if (version != null && version.hasField(fieldType.getId())) {
695                 Object JavaDoc value = version.getField(fieldType.getId()).getValue();
696                 return extractBranchIds(value, document.getBranchId());
697             } else if (version == null && document.hasField(fieldType.getId())) {
698                 Object JavaDoc value = document.getField(fieldType.getId()).getValue();
699                 return extractBranchIds(value, document.getBranchId());
700             } else {
701                 return null;
702             }
703         }
704
705         private Object JavaDoc extractBranchIds(Object JavaDoc value, long documentBranchId) {
706             if (fieldType.isMultiValue()) {
707                 Object JavaDoc[] values = (Object JavaDoc[])value;
708                 Long JavaDoc[] ids = new Long JavaDoc[values.length];
709                 for (int i = 0; i < values.length; i++) {
710                     VariantKey key = (VariantKey)values[i];
711                     ids[i] = new Long JavaDoc(key.getBranchId() != -1 ? key.getBranchId() : documentBranchId);
712                 }
713                 return ids;
714             } else {
715                 VariantKey key = (VariantKey)value;
716                 return new Long JavaDoc(key.getBranchId() != -1 ? key.getBranchId() : documentBranchId);
717             }
718         }
719
720         public String JavaDoc getSqlPreConditions(SqlGenerationContext context) {
721             alias = context.getNewFieldsTableAlias();
722             return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? ";
723         }
724
725         public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc {
726             stmt.setLong(bindPos, fieldType.getId());
727             return ++bindPos;
728         }
729
730         public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
731             sql.append(alias).append('.').append(SqlGenerationContext.FieldsTable.LINK_SEARCHBRANCHID);
732         }
733
734         public QValueType getOutputValueType() {
735             return QValueType.LONG;
736         }
737
738         public Object JavaDoc getOutputValue(Document document, Version version) {
739             return evaluate(document, version);
740         }
741
742         public String JavaDoc getTitle(Locale JavaDoc locale) {
743             String JavaDoc fieldLabel = fieldType.getLabel(locale);
744             String JavaDoc branchId = getLocalizedString("branchId", locale);
745             return fieldLabel + ": " + branchId;
746         }
747     }
748
749     public class LinkFieldLanguageIdIdentifier extends AbstractIdentifier {
750         public static final String JavaDoc NAME = "languageId";
751         protected final FieldType fieldType;
752         private String JavaDoc alias;
753
754         public LinkFieldLanguageIdIdentifier(FieldType fieldType) {
755             this.fieldType = fieldType;
756         }
757
758         public String JavaDoc getName() {
759             return "$" + fieldType.getName() + "." + NAME;
760         }
761
762         public boolean isMultiValue() {
763             return fieldType.isMultiValue();
764         }
765
766         public QValueType getValueType() {
767             return QValueType.LONG;
768         }
769
770         public Object JavaDoc evaluate(Document document, Version version) {
771             if (version != null && version.hasField(fieldType.getId())) {
772                 Object JavaDoc value = version.getField(fieldType.getId()).getValue();
773                 return extractLanguageIds(value, document.getLanguageId());
774             } else if (version == null && document.hasField(fieldType.getId())) {
775                 Object JavaDoc value = document.getField(fieldType.getId()).getValue();
776                 return extractLanguageIds(value, document.getLanguageId());
777             } else {
778                 return null;
779             }
780         }
781
782         private Object JavaDoc extractLanguageIds(Object JavaDoc value, long documentLanguageId) {
783             if (fieldType.isMultiValue()) {
784                 Object JavaDoc[] values = (Object JavaDoc[])value;
785                 Long JavaDoc[] ids = new Long JavaDoc[values.length];
786                 for (int i = 0; i < values.length; i++) {
787                     VariantKey key = (VariantKey)values[i];
788                     ids[i] = new Long JavaDoc(key.getLanguageId() != -1 ? key.getLanguageId() : documentLanguageId);
789                 }
790                 return ids;
791             } else {
792                 VariantKey key = (VariantKey)value;
793                 return new Long JavaDoc(key.getLanguageId() != -1 ? key.getLanguageId() : documentLanguageId);
794             }
795         }
796
797         public String JavaDoc getSqlPreConditions(SqlGenerationContext context) {
798             alias = context.getNewFieldsTableAlias();
799             return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? ";
800         }
801
802         public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc {
803             stmt.setLong(bindPos, fieldType.getId());
804             return ++bindPos;
805         }
806
807         public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
808             sql.append(alias).append('.').append(SqlGenerationContext.FieldsTable.LINK_SEARCHLANGID);
809         }
810
811         public QValueType getOutputValueType() {
812             return QValueType.LONG;
813         }
814
815         public Object JavaDoc getOutputValue(Document document, Version version) {
816             return evaluate(document, version);
817         }
818
819         public String JavaDoc getTitle(Locale JavaDoc locale) {
820             String JavaDoc fieldLabel = fieldType.getLabel(locale);
821             String JavaDoc languageId = getLocalizedString("languageId", locale);
822             return fieldLabel + ": " + languageId;
823         }
824     }
825
826     public final class LinkFieldBranchIdentifier extends LinkFieldBranchIdIdentifier {
827         public static final String JavaDoc NAME = "branch";
828
829         public LinkFieldBranchIdentifier(FieldType fieldType) {
830             super(fieldType);
831         }
832
833         public String JavaDoc getName() {
834             return "$" + fieldType.getName() + "." + NAME;
835         }
836
837         public QValueType getOutputValueType() {
838             return QValueType.STRING;
839         }
840
841         public Object JavaDoc getOutputValue(Document document, Version version) {
842             try {
843                 Object JavaDoc result = evaluate(document, version);
844                 if (result == null)
845                     return null;
846                 if (fieldType.isMultiValue()) {
847                     Object JavaDoc[] results = (Object JavaDoc[])result;
848                     String JavaDoc[] names = new String JavaDoc[results.length];
849                     for (int i = 0; i < results.length; i++) {
850                         names[i] = queryContext.getBranch(((Long JavaDoc)results[i]).longValue()).getName();
851                     }
852                     return names;
853                 } else {
854                     return queryContext.getBranch(((Long JavaDoc)result).longValue()).getName();
855                 }
856             } catch (RepositoryException e) {
857                 throw new RuntimeException JavaDoc(e);
858             }
859         }
860
861         public boolean isSymbolic() {
862             return true;
863         }
864
865         public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
866             String JavaDoc branchName = (String JavaDoc)valueExpr.evaluate(QValueType.STRING, evaluationContext);
867             Branch branch;
868             try {
869                 branch = queryContext.getBranchByName(branchName);
870             } catch (RepositoryException e) {
871                 throw new QueryException("Error with branch name \"" + branchName + "\".", e);
872             }
873             return new Long JavaDoc(branch.getId());
874         }
875
876         public String JavaDoc getTitle(Locale JavaDoc locale) {
877             String JavaDoc fieldLabel = fieldType.getLabel(locale);
878             String JavaDoc branch = getLocalizedString("branch", locale);
879             return fieldLabel + ": " + branch;
880         }
881     }
882
883     public final class LinkFieldLanguageIdentifier extends LinkFieldLanguageIdIdentifier {
884         public static final String JavaDoc NAME = "language";
885
886         public LinkFieldLanguageIdentifier(FieldType fieldType) {
887             super(fieldType);
888         }
889
890         public String JavaDoc getName() {
891             return "$" + fieldType.getName() + "." + NAME;
892         }
893
894         public QValueType getOutputValueType() {
895             return QValueType.STRING;
896         }
897
898         public Object JavaDoc getOutputValue(Document document, Version version) {
899             try {
900                 Object JavaDoc result = evaluate(document, version);
901                 if (result == null)
902                     return null;
903                 if (fieldType.isMultiValue()) {
904                     Object JavaDoc[] results = (Object JavaDoc[])result;
905                     String JavaDoc[] names = new String JavaDoc[results.length];
906                     for (int i = 0; i < results.length; i++)
907                         names[i] = queryContext.getLanguage(((Long JavaDoc)results[i]).longValue()).getName();
908                     return names;
909                 } else {
910                     return queryContext.getLanguage(((Long JavaDoc)result).longValue()).getName();
911                 }
912             } catch (RepositoryException e) {
913                 throw new RuntimeException JavaDoc(e);
914             }
915         }
916
917         public boolean isSymbolic() {
918             return true;
919         }
920
921         public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
922             String JavaDoc languageName = (String JavaDoc)valueExpr.evaluate(QValueType.STRING, evaluationContext);
923             Language language;
924             try {
925                 language = queryContext.getLanguageByName(languageName);
926             } catch (RepositoryException e) {
927                 throw new QueryException("Error with language name \"" + languageName + "\".", e);
928             }
929             return new Long JavaDoc(language.getId());
930         }
931
932         public String JavaDoc getTitle(Locale JavaDoc locale) {
933             String JavaDoc fieldLabel = fieldType.getLabel(locale);
934             String JavaDoc language = getLocalizedString("language", locale);
935             return fieldLabel + ": " + language;
936         }
937     }
938
939     public final class CollectionsIdentifier extends AbstractIdentifier {
940         public static final String JavaDoc NAME = "collections";
941
942         public CollectionsIdentifier() {
943         }
944
945         public String JavaDoc getName() {
946             return NAME;
947         }
948
949         public QValueType getValueType() {
950             return QValueType.LONG;
951         }
952
953         public boolean isMultiValue() {
954             return true;
955         }
956
957         public Identifier getValueCountIdentifier() {
958             return new Identifier(CollectionsValueCountIdentifier.NAME, queryContext, new CollectionsValueCountIdentifier());
959         }
960
961         public Object JavaDoc evaluate(Document document, Version version) {
962             DocumentCollection[] collections = document.getCollections().getArray();
963             if (collections.length == 0)
964                 return null;
965             Long JavaDoc[] collectionIds = new Long JavaDoc[collections.length];
966             for (int i = 0; i < collectionIds.length; i++)
967                 collectionIds[i] = new Long JavaDoc(collections[i].getId());
968             return collectionIds;
969         }
970
971         public QValueType getOutputValueType() {
972             return QValueType.STRING;
973         }
974
975         public Object JavaDoc getOutputValue(Document document, Version version) {
976             DocumentCollection[] collections = document.getCollections().getArray();
977             if (collections.length == 0)
978                 return null;
979             String JavaDoc[] collectionNames = new String JavaDoc[collections.length];
980             for (int i = 0; i < collectionNames.length; i++)
981                 collectionNames[i] = collections[i].getName();
982             return collectionNames;
983         }
984
985         public boolean canTestappliesTo() {
986             return true;
987         }
988
989         public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
990             String JavaDoc alias = context.getNewCollectionsTableAlias();
991             sql.append(alias).append(".collection_id");
992         }
993
994         public boolean isSymbolic() {
995             return true;
996         }
997
998         public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
999             String JavaDoc collectionName = (String JavaDoc)valueExpr.evaluate(QValueType.STRING, evaluationContext);
1000            DocumentCollection collection;
1001            try {
1002                collection = queryContext.getCollection(collectionName);
1003            } catch (CollectionNotFoundException e) {
1004                throw new QueryException("\"" + collectionName + "\" is not an existing collection.");
1005            } catch (RepositoryException e) {
1006                throw new QueryException("Error consulting collection information.", e);
1007            }
1008            return new Long JavaDoc(collection.getId());
1009        }
1010    }
1011
1012    public final class CollectionsValueCountIdentifier extends AbstractNonAclIdentifier {
1013        public static final String JavaDoc NAME = "collections.valueCount";
1014
1015        public String JavaDoc getName() {
1016            return NAME;
1017        }
1018
1019        public QValueType getValueType() {
1020            return QValueType.LONG;
1021        }
1022
1023        public Object JavaDoc evaluate(Document document, Version version) {
1024            return new Long JavaDoc(document.getCollections().getArray().length);
1025        }
1026
1027        public QValueType getOutputValueType() {
1028            return QValueType.LONG;
1029        }
1030
1031        public Object JavaDoc getOutputValue(Document document, Version version) {
1032            return evaluate(document, version);
1033        }
1034
1035        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1036            sql.append(" (select count(*) from document_collections where document_id = documents.id and branch_id = document_variants.branch_id and lang_id = document_variants.lang_id) ");
1037        }
1038
1039        public boolean isSymbolic() {
1040            return false;
1041        }
1042
1043        public boolean isOutputOnly() {
1044            return false;
1045        }
1046
1047        public String JavaDoc getTitle(Locale JavaDoc locale) {
1048            return getLocalizedString(getName(), locale);
1049        }
1050    }
1051
1052    private static Version getLastVersion(Document document) {
1053        try {
1054            return document.getLastVersion();
1055        } catch (RepositoryException e) {
1056            throw new RuntimeException JavaDoc("Error getting last version of document " + document.getId(), e);
1057        }
1058    }
1059
1060    private String JavaDoc getUserDisplayName(long userId) {
1061        try {
1062            return queryContext.getUserDisplayName(userId);
1063        } catch (RepositoryException e) {
1064            throw new RuntimeException JavaDoc("Error getting display name for user " + userId, e);
1065        }
1066    }
1067
1068    private String JavaDoc getUserLogin(long userId) {
1069        try {
1070            return queryContext.getUserLogin(userId);
1071        } catch (RepositoryException e) {
1072            throw new RuntimeException JavaDoc("Error getting login for user " + userId, e);
1073        }
1074    }
1075
1076    private static String JavaDoc getLocalizedString(String JavaDoc name, Locale JavaDoc locale) {
1077        ResourceBundle JavaDoc bundle = ResourceBundle.getBundle("org/outerj/daisy/query/model/messages", locale);
1078        return bundle.getString(name);
1079    }
1080
1081    public final class DocumentTypeIdentifier extends AbstractIdentifier {
1082        public static final String JavaDoc NAME = "documentType";
1083
1084        public String JavaDoc getName() {
1085            return NAME;
1086        }
1087
1088        public QValueType getValueType() {
1089            return QValueType.LONG;
1090        }
1091
1092        public Object JavaDoc evaluate(Document document, Version version) {
1093            return new Long JavaDoc(document.getDocumentTypeId());
1094        }
1095
1096        public QValueType getOutputValueType() {
1097            return QValueType.STRING;
1098        }
1099
1100        public Object JavaDoc getOutputValue(Document document, Version version) {
1101            try {
1102                return queryContext.getDocumentTypeById(document.getDocumentTypeId()).getName();
1103            } catch (RepositoryException e) {
1104                return "<ERROR>";
1105            }
1106        }
1107
1108        public boolean canTestappliesTo() {
1109            return true;
1110        }
1111
1112        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1113            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME);
1114            sql.append('.');
1115            sql.append(SqlGenerationContext.DocumentVariantsTable.DOCTYPE_ID);
1116        }
1117
1118        public boolean isSymbolic() {
1119            return true;
1120        }
1121
1122        public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
1123            String JavaDoc documentTypeName = (String JavaDoc)valueExpr.evaluate(QValueType.STRING, evaluationContext);
1124            DocumentType documentType;
1125            try {
1126                documentType = queryContext.getDocumentTypeByName(documentTypeName);
1127            } catch (DocumentTypeNotFoundException e) {
1128                throw new QueryException("\"" + documentTypeName + "\" is not a valid document type name.");
1129            } catch (RepositoryException e) {
1130                throw new QueryException("Error consulting repository schema information.", e);
1131            }
1132            return new Long JavaDoc(documentType.getId());
1133        }
1134    }
1135
1136    public final class DocumentNameIdentifier extends AbstractNonAclIdentifier {
1137        public static final String JavaDoc NAME = "name";
1138
1139        public String JavaDoc getName() {
1140            return NAME;
1141        }
1142
1143        public QValueType getValueType() {
1144            return QValueType.STRING;
1145        }
1146
1147        public Object JavaDoc evaluate(Document document, Version version) {
1148            return version != null ? version.getDocumentName() : null;
1149        }
1150
1151        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1152            context.needsJoinWithTable(SqlGenerationContext.VERSIONS_TABLE);
1153
1154            sql.append(SqlGenerationContext.VERSIONS_TABLE.getName());
1155            sql.append('.');
1156            sql.append(SqlGenerationContext.VersionsTable.NAME);
1157        }
1158
1159        public QValueType getOutputValueType() {
1160            return QValueType.STRING;
1161        }
1162
1163        public Object JavaDoc getOutputValue(Document document, Version version) {
1164            return evaluate(document, version);
1165        }
1166    }
1167
1168    public final class CreationTimeIdentifier extends AbstractNonAclIdentifier {
1169        public static final String JavaDoc NAME = "creationTime";
1170
1171        public String JavaDoc getName() {
1172            return NAME;
1173        }
1174
1175        public QValueType getValueType() {
1176            return QValueType.DATETIME;
1177        }
1178
1179        public Object JavaDoc evaluate(Document document, Version version) {
1180            return document.getCreated();
1181        }
1182
1183        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1184            sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME);
1185            sql.append('.');
1186            sql.append(SqlGenerationContext.DocumentsTable.CREATED);
1187        }
1188
1189        public QValueType getOutputValueType() {
1190            return QValueType.DATETIME;
1191        }
1192
1193        public Object JavaDoc getOutputValue(Document document, Version version) {
1194            return evaluate(document, version);
1195        }
1196    }
1197
1198    public final class DocumentIdIdentifier extends AbstractIdentifier {
1199        public static final String JavaDoc NAME = "id";
1200
1201        public String JavaDoc getName() {
1202            return NAME;
1203        }
1204
1205        public QValueType getValueType() {
1206            return QValueType.LONG;
1207        }
1208
1209        public Object JavaDoc evaluate(Document document, Version version) {
1210            return new Long JavaDoc(document.getId());
1211        }
1212
1213        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1214            sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME);
1215            sql.append('.');
1216            sql.append(SqlGenerationContext.DocumentsTable.ID);
1217        }
1218
1219        public QValueType getOutputValueType() {
1220            return QValueType.LONG;
1221        }
1222
1223        public Object JavaDoc getOutputValue(Document document, Version version) {
1224            return new Long JavaDoc(document.getId());
1225        }
1226    }
1227
1228    public final class DocumentLinkIdentifier extends AbstractIdentifier {
1229        public static final String JavaDoc NAME = "link";
1230
1231        public String JavaDoc getName() {
1232            return NAME;
1233        }
1234
1235        public QValueType getValueType() {
1236            return QValueType.LINK;
1237        }
1238
1239        public Object JavaDoc evaluate(Document document, Version version) {
1240            return document.getVariantKey();
1241        }
1242
1243        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1244            sql.append(" CONCAT(");
1245            sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME).append(".").append(SqlGenerationContext.DocumentsTable.ID);
1246            sql.append(", '@', ");
1247            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME).append('.').append(SqlGenerationContext.DocumentVariantsTable.BRANCH_ID);
1248            sql.append(", ':', ");
1249            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME).append('.').append(SqlGenerationContext.DocumentVariantsTable.LANG_ID);
1250            sql.append(") ");
1251        }
1252
1253        public QValueType getOutputValueType() {
1254            return QValueType.LINK;
1255        }
1256
1257        public Object JavaDoc getOutputValue(Document document, Version version) {
1258            return evaluate(document, version);
1259        }
1260    }
1261
1262    public final class BranchIdIdentifier extends AbstractIdentifier {
1263        public static final String JavaDoc NAME = "branchId";
1264
1265        public String JavaDoc getName() {
1266            return NAME;
1267        }
1268
1269        public QValueType getValueType() {
1270            return QValueType.LONG;
1271        }
1272
1273        public Object JavaDoc evaluate(Document document, Version version) {
1274            return new Long JavaDoc(document.getBranchId());
1275        }
1276
1277        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1278            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME);
1279            sql.append('.');
1280            sql.append(SqlGenerationContext.DocumentVariantsTable.BRANCH_ID);
1281        }
1282
1283        public QValueType getOutputValueType() {
1284            return QValueType.LONG;
1285        }
1286
1287        public Object JavaDoc getOutputValue(Document document, Version version) {
1288            return evaluate(document, version);
1289        }
1290    }
1291
1292    public final class BranchNameIdentifier extends AbstractIdentifier {
1293        public static final String JavaDoc NAME = "branch";
1294
1295        public String JavaDoc getName() {
1296            return NAME;
1297        }
1298
1299        public QValueType getValueType() {
1300            return QValueType.LONG;
1301        }
1302
1303        public Object JavaDoc evaluate(Document document, Version version) {
1304            return new Long JavaDoc(document.getBranchId());
1305        }
1306
1307        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1308            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME);
1309            sql.append('.');
1310            sql.append(SqlGenerationContext.DocumentVariantsTable.BRANCH_ID);
1311        }
1312
1313        public QValueType getOutputValueType() {
1314            return QValueType.STRING;
1315        }
1316
1317        public Object JavaDoc getOutputValue(Document document, Version version) {
1318            try {
1319                return queryContext.getBranch(document.getBranchId()).getName();
1320            } catch (RepositoryException e) {
1321                throw new RuntimeException JavaDoc(e);
1322            }
1323        }
1324
1325        public boolean isSymbolic() {
1326            return true;
1327        }
1328
1329        public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
1330            String JavaDoc branchName = (String JavaDoc)valueExpr.evaluate(QValueType.STRING, evaluationContext);
1331            Branch branch;
1332            try {
1333                branch = queryContext.getBranchByName(branchName);
1334            } catch (RepositoryException e) {
1335                throw new QueryException("Error with branch name \"" + branchName + "\".", e);
1336            }
1337            return new Long JavaDoc(branch.getId());
1338        }
1339    }
1340
1341    public final class LanguageIdIdentifier extends AbstractIdentifier {
1342        public static final String JavaDoc NAME = "languageId";
1343
1344        public String JavaDoc getName() {
1345            return NAME;
1346        }
1347
1348        public QValueType getValueType() {
1349            return QValueType.LONG;
1350        }
1351
1352        public Object JavaDoc evaluate(Document document, Version version) {
1353            return new Long JavaDoc(document.getLanguageId());
1354        }
1355
1356        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1357            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME);
1358            sql.append('.');
1359            sql.append(SqlGenerationContext.DocumentVariantsTable.LANG_ID);
1360        }
1361
1362        public QValueType getOutputValueType() {
1363            return QValueType.LONG;
1364        }
1365
1366        public Object JavaDoc getOutputValue(Document document, Version version) {
1367            return new Long JavaDoc(document.getLanguageId());
1368        }
1369    }
1370
1371    public final class LanguageNameIdentifier extends AbstractIdentifier {
1372        public static final String JavaDoc NAME = "language";
1373
1374        public String JavaDoc getName() {
1375            return NAME;
1376        }
1377
1378        public QValueType getValueType() {
1379            return QValueType.LONG;
1380        }
1381
1382        public Object JavaDoc evaluate(Document document, Version version) {
1383            return new Long JavaDoc(document.getLanguageId());
1384        }
1385
1386        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1387            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME);
1388            sql.append('.');
1389            sql.append(SqlGenerationContext.DocumentVariantsTable.LANG_ID);
1390        }
1391
1392        public QValueType getOutputValueType() {
1393            return QValueType.STRING;
1394        }
1395
1396        public Object JavaDoc getOutputValue(Document document, Version version) {
1397            try {
1398                return queryContext.getLanguage(document.getLanguageId()).getName();
1399            } catch (RepositoryException e) {
1400                throw new RuntimeException JavaDoc(e);
1401            }
1402        }
1403
1404        public boolean isSymbolic() {
1405            return true;
1406        }
1407
1408        public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
1409            String JavaDoc languageName = (String JavaDoc)valueExpr.evaluate(QValueType.STRING, evaluationContext);
1410            Language language;
1411            try {
1412                language = queryContext.getLanguageByName(languageName);
1413            } catch (RepositoryException e) {
1414                throw new QueryException("Error with language name \"" + languageName + "\".", e);
1415            }
1416            return new Long JavaDoc(language.getId());
1417        }
1418    }
1419
1420    public final class VersionCreationTimeIdentifier extends AbstractNonAclIdentifier {
1421        public static final String JavaDoc NAME = "versionCreationTime";
1422
1423        public String JavaDoc getName() {
1424            return NAME;
1425        }
1426
1427        public QValueType getValueType() {
1428            return QValueType.DATETIME;
1429        }
1430
1431        public Object JavaDoc evaluate(Document document, Version version) {
1432            if (version != null) {
1433                return version.getCreated();
1434            } else {
1435                version = getLastVersion(document);
1436                return version != null ? version.getCreated() : null;
1437            }
1438        }
1439
1440        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1441            context.needsJoinWithTable(SqlGenerationContext.VERSIONS_TABLE);
1442
1443            sql.append(SqlGenerationContext.VERSIONS_TABLE.getName());
1444            sql.append('.');
1445            sql.append(SqlGenerationContext.VersionsTable.CREATED_ON);
1446        }
1447
1448        public QValueType getOutputValueType() {
1449            return QValueType.DATETIME;
1450        }
1451
1452        public Object JavaDoc getOutputValue(Document document, Version version) {
1453            return evaluate(document, version);
1454        }
1455    }
1456
1457    public final class TotalSizeOfPartsIdentifier extends AbstractNonAclIdentifier {
1458        public static final String JavaDoc NAME = "totalSizeOfParts";
1459
1460        public String JavaDoc getName() {
1461            return NAME;
1462        }
1463
1464        public QValueType getValueType() {
1465            return QValueType.LONG;
1466        }
1467
1468        public Object JavaDoc evaluate(Document document, Version version) {
1469            if (version != null) {
1470                return new Long JavaDoc(version.getTotalSizeOfParts());
1471            } else {
1472                version = getLastVersion(document);
1473                return version != null ? new Long JavaDoc(version.getTotalSizeOfParts()) : null;
1474            }
1475        }
1476
1477        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1478            context.needsJoinWithTable(SqlGenerationContext.VERSIONS_TABLE);
1479
1480            sql.append(SqlGenerationContext.VERSIONS_TABLE.getName());
1481            sql.append('.');
1482            sql.append(SqlGenerationContext.VersionsTable.TOTAL_SIZE_OF_PARTS);
1483        }
1484
1485        public QValueType getOutputValueType() {
1486            return QValueType.LONG;
1487        }
1488
1489        public Object JavaDoc getOutputValue(Document document, Version version) {
1490            return evaluate(document, version);
1491        }
1492    }
1493
1494    public final class VersionStateLastModifiedIdentifier extends AbstractNonAclIdentifier {
1495        public static final String JavaDoc NAME = "versionStateLastModified";
1496
1497        public String JavaDoc getName() {
1498            return NAME;
1499        }
1500
1501        public QValueType getValueType() {
1502            return QValueType.DATETIME;
1503        }
1504
1505        public Object JavaDoc evaluate(Document document, Version version) {
1506            if (version != null) {
1507                return version.getStateLastModified();
1508            } else {
1509                version = getLastVersion(document);
1510                return version != null ? version.getStateLastModified() : null;
1511            }
1512        }
1513
1514        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1515            context.needsJoinWithTable(SqlGenerationContext.VERSIONS_TABLE);
1516
1517            sql.append(SqlGenerationContext.VERSIONS_TABLE.getName());
1518            sql.append('.');
1519            sql.append(SqlGenerationContext.VersionsTable.STATE_LAST_MODIFIED);
1520        }
1521
1522        public QValueType getOutputValueType() {
1523            return QValueType.DATETIME;
1524        }
1525
1526        public Object JavaDoc getOutputValue(Document document, Version version) {
1527            return evaluate(document, version);
1528        }
1529    }
1530
1531    public final class VersionCreatorIdIdentifier extends AbstractNonAclIdentifier {
1532        public static final String JavaDoc NAME = "versionCreatorId";
1533
1534        public String JavaDoc getName() {
1535            return NAME;
1536        }
1537
1538        public QValueType getValueType() {
1539            return QValueType.LONG;
1540        }
1541
1542        public Object JavaDoc evaluate(Document document, Version version) {
1543            if (version != null) {
1544                return new Long JavaDoc(version.getCreator());
1545            } else {
1546                version = getLastVersion(document);
1547                return version != null ? new Long JavaDoc(version.getCreator()) : null;
1548            }
1549        }
1550
1551        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1552            context.needsJoinWithTable(SqlGenerationContext.VERSIONS_TABLE);
1553
1554            sql.append(SqlGenerationContext.VERSIONS_TABLE.getName());
1555            sql.append('.');
1556            sql.append(SqlGenerationContext.VersionsTable.CREATED_BY);
1557        }
1558
1559        public QValueType getOutputValueType() {
1560            return QValueType.LONG;
1561        }
1562
1563        public Object JavaDoc getOutputValue(Document document, Version version) {
1564            return evaluate(document, version);
1565        }
1566    }
1567
1568    public abstract class AbstractLoginIdentifier extends AbstractNonAclIdentifier {
1569        public QValueType getValueType() {
1570            return QValueType.LONG;
1571        }
1572
1573        public QValueType getOutputValueType() {
1574            return QValueType.STRING;
1575        }
1576
1577        public boolean isSymbolic() {
1578            return true;
1579        }
1580
1581        public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
1582            String JavaDoc login = (String JavaDoc)valueExpr.evaluate(QValueType.STRING, evaluationContext);
1583            long userId;
1584            try {
1585                userId = queryContext.getUserId(login);
1586            } catch (RepositoryException e) {
1587                throw new QueryException("Error getting user information for user with login \"" + login + "\".", e);
1588            }
1589            return new Long JavaDoc(userId);
1590        }
1591    }
1592
1593    public final class VersionCreatorLoginIdentifier extends AbstractLoginIdentifier {
1594        public static final String JavaDoc NAME = "versionCreatorLogin";
1595
1596        public String JavaDoc getName() {
1597            return NAME;
1598        }
1599
1600        public Object JavaDoc evaluate(Document document, Version version) {
1601            if (version != null) {
1602                return new Long JavaDoc(version.getCreator());
1603            } else {
1604                version = getLastVersion(document);
1605                return version != null ? new Long JavaDoc(version.getCreator()) : null;
1606            }
1607        }
1608
1609        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1610            context.needsJoinWithTable(SqlGenerationContext.VERSIONS_TABLE);
1611
1612            sql.append(SqlGenerationContext.VERSIONS_TABLE.getName());
1613            sql.append('.');
1614            sql.append(SqlGenerationContext.VersionsTable.CREATED_BY);
1615        }
1616
1617        public Object JavaDoc getOutputValue(Document document, Version version) {
1618            Long JavaDoc creatorId = (Long JavaDoc)evaluate(document, version);
1619            return creatorId != null ? getUserLogin(creatorId.longValue()) : null;
1620        }
1621    }
1622
1623    public final class PrivateIdentifier extends AbstractNonAclIdentifier {
1624        public static final String JavaDoc NAME = "private";
1625
1626        public String JavaDoc getName() {
1627            return NAME;
1628        }
1629
1630        public QValueType getValueType() {
1631            return QValueType.BOOLEAN;
1632        }
1633
1634        public Object JavaDoc evaluate(Document document, Version version) {
1635            return document.isPrivate() ? Boolean.TRUE : Boolean.FALSE;
1636        }
1637
1638        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1639            sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME);
1640            sql.append('.');
1641            sql.append(SqlGenerationContext.DocumentsTable.PRIVATE);
1642        }
1643
1644        public QValueType getOutputValueType() {
1645            return QValueType.BOOLEAN;
1646        }
1647
1648        public Object JavaDoc getOutputValue(Document document, Version version) {
1649            return evaluate(document, version);
1650        }
1651    }
1652
1653    public final class RetiredIdentifier extends AbstractNonAclIdentifier {
1654        public static final String JavaDoc NAME = "retired";
1655
1656        public String JavaDoc getName() {
1657            return NAME;
1658        }
1659
1660        public QValueType getValueType() {
1661            return QValueType.BOOLEAN;
1662        }
1663
1664        public Object JavaDoc evaluate(Document document, Version version) {
1665            return document.isRetired() ? Boolean.TRUE : Boolean.FALSE;
1666        }
1667
1668        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1669            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME);
1670            sql.append('.');
1671            sql.append(SqlGenerationContext.DocumentVariantsTable.RETIRED);
1672        }
1673
1674        public QValueType getOutputValueType() {
1675            return QValueType.BOOLEAN;
1676        }
1677
1678        public Object JavaDoc getOutputValue(Document document, Version version) {
1679            return evaluate(document, version);
1680        }
1681    }
1682
1683    public final class VersionCreatorNameIdentifier extends AbstractOutputIdentifier {
1684        public static final String JavaDoc NAME = "versionCreatorName";
1685
1686        public QValueType getValueType() {
1687            return QValueType.STRING;
1688        }
1689
1690        public String JavaDoc getName() {
1691            return NAME;
1692        }
1693
1694        public QValueType getOutputValueType() {
1695            return QValueType.STRING;
1696        }
1697
1698        public Object JavaDoc getOutputValue(Document document, Version version) {
1699            return version != null ? getUserDisplayName(version.getCreator()) : null;
1700        }
1701    }
1702
1703    public abstract class AbstractOutputIdentifier extends AbstractIdentifier {
1704        public boolean isOutputOnly() {
1705            return true;
1706        }
1707
1708        public QValueType getValueType() {
1709            return getOutputValueType();
1710        }
1711
1712        public Object JavaDoc evaluate(Document document, Version version) throws QueryException {
1713            return getOutputValue(document, version);
1714        }
1715
1716        public AclConditionViolation isAclAllowed() {
1717            return new AclConditionViolation("Identifier \"" + getName() + "\" is not allowed in ACL conditions.");
1718        }
1719
1720        public boolean canTestappliesTo() {
1721            return false;
1722        }
1723
1724        public String JavaDoc getSqlPreConditions(SqlGenerationContext context) throws QueryException {
1725            throw new QueryException("It is not possible to search on identifier " + getName());
1726        }
1727
1728        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) throws QueryException {
1729            throw new QueryException("It is not possible to search on identifier " + getName());
1730        }
1731
1732        public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc, QueryException {
1733            // This will never be reached, as the SQL generation methods throw exceptions
1734
throw new IllegalStateException JavaDoc();
1735        }
1736
1737        public int bindValueExpr(PreparedStatement JavaDoc stmt, int bindPos, QValueType valueType) throws SQLException JavaDoc, QueryException {
1738            // This will never be reached, as the SQL generation methods throw exceptions
1739
throw new IllegalStateException JavaDoc();
1740        }
1741    }
1742
1743    public final class SummaryIdentifier extends AbstractOutputIdentifier {
1744        public static final String JavaDoc NAME = "summary";
1745
1746        public String JavaDoc getName() {
1747            return NAME;
1748        }
1749
1750        public QValueType getOutputValueType() {
1751            return QValueType.STRING;
1752        }
1753
1754        public Object JavaDoc getOutputValue(Document document, Version version) {
1755            return document.getSummary();
1756        }
1757    }
1758
1759    public final class VersionStateIdentifier extends AbstractNonAclIdentifier {
1760        public static final String JavaDoc NAME = "versionState";
1761
1762        public String JavaDoc getName() {
1763            return NAME;
1764        }
1765
1766        public QValueType getOutputValueType() {
1767            return QValueType.VERSION_STATE;
1768        }
1769
1770        public Object JavaDoc getOutputValue(Document document, Version version) {
1771            if (version != null) {
1772                return version.getState();
1773            } else {
1774                version = getLastVersion(document);
1775                return version.getState();
1776            }
1777        }
1778
1779        public QValueType getValueType() {
1780            return QValueType.STRING;
1781        }
1782
1783        public Object JavaDoc evaluate(Document document, Version version) {
1784            if (version != null) {
1785                return version.getState().getCode();
1786            } else {
1787                version = getLastVersion(document);
1788                return version.getState().getCode();
1789            }
1790        }
1791
1792        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1793            context.needsJoinWithTable(SqlGenerationContext.VERSIONS_TABLE);
1794
1795            sql.append(SqlGenerationContext.VERSIONS_TABLE.getName());
1796            sql.append('.');
1797            sql.append(SqlGenerationContext.VersionsTable.STATE);
1798        }
1799
1800        public boolean isSymbolic() {
1801            return true;
1802        }
1803
1804        public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
1805            String JavaDoc versionStateName = (String JavaDoc)valueExpr.evaluate(QValueType.STRING, evaluationContext);
1806            VersionState versionState = VersionState.fromString(versionStateName);
1807            return versionState.getCode();
1808        }
1809    }
1810
1811    public final class PartContentIdentifier extends AbstractOutputIdentifier {
1812        private final String JavaDoc name;
1813        private final PartType partType;
1814
1815        public PartContentIdentifier(String JavaDoc name, PartType partType) {
1816            this.name = name;
1817            this.partType = partType;
1818        }
1819
1820        public QValueType getOutputValueType() {
1821            return QValueType.XML;
1822        }
1823
1824        public Object JavaDoc getOutputValue(Document document, Version version) {
1825            if (version != null && version.hasPart(partType.getId())) {
1826                try {
1827                    Part part = version.getPart(partType.getId());
1828                    if (part.getMimeType().equals("text/xml") && part.getSize() < CONTENT_INCLUDE_LIMIT) {
1829                        XmlOptions xmlOptions = new XmlOptions().setLoadUseXMLReader(LocalSAXParserFactory.newXmlReader());
1830                        return XmlObject.Factory.parse(new ByteArrayInputStream JavaDoc(part.getData()), xmlOptions);
1831                    }
1832                } catch (Exception JavaDoc e) {
1833                    XmlObject error = XmlObject.Factory.newInstance();
1834                    XmlCursor cursor = error.newCursor();
1835                    cursor.toNextToken();
1836                    cursor.beginElement("p");
1837                    cursor.insertAttributeWithValue("class", "daisy-error");
1838                    cursor.insertChars("Error getting part data for part " + partType.getId() + " of document " + document.getId() + " in version " + version.getId() + ", error message: " + e.getMessage());
1839                    cursor.dispose();
1840                    return error;
1841                }
1842            }
1843            return null;
1844        }
1845
1846        public String JavaDoc getName() {
1847            return name;
1848        }
1849
1850        public String JavaDoc getTitle(Locale JavaDoc locale) {
1851            return partType.getLabel(locale);
1852        }
1853    }
1854
1855    public final class PartMimeTypeIdentifier extends AbstractNonAclIdentifier {
1856        private final String JavaDoc name;
1857        private final PartType partType;
1858        private String JavaDoc alias;
1859
1860        public PartMimeTypeIdentifier(String JavaDoc name, PartType partType) {
1861            this.name = name;
1862            this.partType = partType;
1863        }
1864
1865        public QValueType getValueType() {
1866            return QValueType.STRING;
1867        }
1868
1869        public Object JavaDoc evaluate(Document document, Version version) {
1870            if (version != null && version.hasPart(partType.getId())) {
1871                return version.getPart(partType.getId()).getMimeType();
1872            } else if (version == null && document.hasPart(partType.getId())) {
1873                return document.getPart(partType.getId()).getMimeType();
1874            } else {
1875                return null;
1876            }
1877        }
1878
1879        public String JavaDoc getSqlPreConditions(SqlGenerationContext context) {
1880            alias = context.getNewPartsTableAlias();
1881            return alias + '.' + SqlGenerationContext.PartsTable.PARTTYPE_ID + " = ? ";
1882        }
1883
1884        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1885            sql.append(alias).append('.').append(SqlGenerationContext.PartsTable.MIMETYPE);
1886        }
1887
1888        public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc {
1889            stmt.setLong(bindPos, partType.getId());
1890            return ++bindPos;
1891        }
1892
1893        public QValueType getOutputValueType() {
1894            return QValueType.STRING;
1895        }
1896
1897        public Object JavaDoc getOutputValue(Document document, Version version) {
1898            return evaluate(document, version);
1899        }
1900
1901        public String JavaDoc getName() {
1902            return name;
1903        }
1904
1905        public String JavaDoc getTitle(Locale JavaDoc locale) {
1906            return partType.getLabel(locale) + " (" + getLocalizedString("part.mimetype", locale) + ")";
1907        }
1908    }
1909
1910    public final class PartSizeIdentifier extends AbstractNonAclIdentifier {
1911        private final String JavaDoc name;
1912        private final PartType partType;
1913        private String JavaDoc alias;
1914
1915        public PartSizeIdentifier(String JavaDoc name, PartType partType) {
1916            this.name = name;
1917            this.partType = partType;
1918        }
1919
1920        public QValueType getValueType() {
1921            return QValueType.LONG;
1922        }
1923
1924        public Object JavaDoc evaluate(Document document, Version version) {
1925            if (version != null && version.hasPart(partType.getId())) {
1926                return new Long JavaDoc(version.getPart(partType.getId()).getSize());
1927            } else if (version == null && document.hasPart(partType.getId())) {
1928                return new Long JavaDoc(document.getPart(partType.getId()).getSize());
1929            } else {
1930                return null;
1931            }
1932        }
1933
1934        public String JavaDoc getSqlPreConditions(SqlGenerationContext context) {
1935            alias = context.getNewPartsTableAlias();
1936            return alias + '.' + SqlGenerationContext.PartsTable.PARTTYPE_ID + " = ? ";
1937        }
1938
1939        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1940            sql.append(alias).append('.').append(SqlGenerationContext.PartsTable.SIZE);
1941        }
1942
1943        public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc {
1944            stmt.setLong(bindPos, partType.getId());
1945            return ++bindPos;
1946        }
1947
1948        public QValueType getOutputValueType() {
1949            return QValueType.LONG;
1950        }
1951
1952        public Object JavaDoc getOutputValue(Document document, Version version) {
1953            return evaluate(document, version);
1954        }
1955
1956        public String JavaDoc getName() {
1957            return name;
1958        }
1959
1960        public String JavaDoc getTitle(Locale JavaDoc locale) {
1961            return partType.getLabel(locale) + " (" + getLocalizedString("part.size", locale) + ")";
1962        }
1963    }
1964
1965    public final class LockTypeIdentifier extends AbstractNonAclIdentifier {
1966        public static final String JavaDoc NAME = "lockType";
1967
1968        public QValueType getValueType() {
1969            return QValueType.STRING;
1970        }
1971
1972        public Object JavaDoc evaluate(Document document, Version version) {
1973            LockInfo lockInfo;
1974            try {
1975                lockInfo = document.getLockInfo(false);
1976            } catch (RepositoryException e) {
1977                throw new RuntimeException JavaDoc(e);
1978            }
1979            if (lockInfo.hasLock()) {
1980                return lockInfo.getType().getCode();
1981            } else {
1982                return null;
1983            }
1984        }
1985
1986        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
1987            context.needsJoinWithTable(SqlGenerationContext.LOCKS_TABLE);
1988
1989            sql.append(SqlGenerationContext.LOCKS_TABLE.getName());
1990            sql.append('.');
1991            sql.append(SqlGenerationContext.LocksTable.LOCKTYPE);
1992        }
1993
1994        public boolean isSymbolic() {
1995            return true;
1996        }
1997
1998        public Object JavaDoc translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException {
1999            String JavaDoc lockTypeName = (String JavaDoc)valueExpr.evaluate(QValueType.STRING, evaluationContext);
2000            LockType lockType = LockType.fromString(lockTypeName);
2001            return lockType.getCode();
2002        }
2003
2004        public QValueType getOutputValueType() {
2005            return QValueType.STRING;
2006        }
2007
2008        public Object JavaDoc getOutputValue(Document document, Version version) {
2009            LockInfo lockInfo;
2010            try {
2011                lockInfo = document.getLockInfo(false);
2012            } catch (RepositoryException e) {
2013                throw new RuntimeException JavaDoc(e);
2014            }
2015            if (lockInfo.hasLock()) {
2016                return lockInfo.getType().toString();
2017            } else {
2018                return null;
2019            }
2020        }
2021
2022        public String JavaDoc getName() {
2023            return NAME;
2024        }
2025    }
2026
2027    public final class LockOwnerIdIdentifier extends AbstractNonAclIdentifier {
2028        public static final String JavaDoc NAME = "lockOwnerId";
2029
2030        public QValueType getValueType() {
2031            return QValueType.LONG;
2032        }
2033
2034        public Object JavaDoc evaluate(Document document, Version version) {
2035            LockInfo lockInfo;
2036            try {
2037                lockInfo = document.getLockInfo(false);
2038            } catch (RepositoryException e) {
2039                throw new RuntimeException JavaDoc(e);
2040            }
2041            if (lockInfo.hasLock()) {
2042                return new Long JavaDoc(lockInfo.getUserId());
2043            } else {
2044                return null;
2045            }
2046        }
2047
2048        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2049            context.needsJoinWithTable(SqlGenerationContext.LOCKS_TABLE);
2050
2051            sql.append(SqlGenerationContext.LOCKS_TABLE.getName());
2052            sql.append('.');
2053            sql.append(SqlGenerationContext.LocksTable.OWNER_ID);
2054        }
2055
2056        public QValueType getOutputValueType() {
2057            return QValueType.LONG;
2058        }
2059
2060        public Object JavaDoc getOutputValue(Document document, Version version) {
2061            return evaluate(document, version);
2062        }
2063
2064        public String JavaDoc getName() {
2065            return NAME;
2066        }
2067    }
2068
2069    public final class LockOwnerLoginIdentifier extends AbstractLoginIdentifier {
2070        public static final String JavaDoc NAME = "lockOwnerLogin";
2071
2072        public Object JavaDoc evaluate(Document document, Version version) {
2073            LockInfo lockInfo;
2074            try {
2075                lockInfo = document.getLockInfo(false);
2076            } catch (RepositoryException e) {
2077                throw new RuntimeException JavaDoc(e);
2078            }
2079            if (lockInfo.hasLock()) {
2080                return new Long JavaDoc(lockInfo.getUserId());
2081            } else {
2082                return null;
2083            }
2084        }
2085
2086        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2087            context.needsJoinWithTable(SqlGenerationContext.LOCKS_TABLE);
2088
2089            sql.append(SqlGenerationContext.LOCKS_TABLE.getName());
2090            sql.append('.');
2091            sql.append(SqlGenerationContext.LocksTable.OWNER_ID);
2092        }
2093
2094        public Object JavaDoc getOutputValue(Document document, Version version) {
2095            LockInfo lockInfo;
2096            try {
2097                lockInfo = document.getLockInfo(false);
2098            } catch (RepositoryException e) {
2099                throw new RuntimeException JavaDoc(e);
2100            }
2101            if (lockInfo.hasLock()) {
2102                return getUserLogin(lockInfo.getUserId());
2103            } else {
2104                return null;
2105            }
2106        }
2107
2108        public String JavaDoc getName() {
2109            return NAME;
2110        }
2111    }
2112
2113    public final class LockOwnerNameIdentifier extends AbstractOutputIdentifier {
2114        public static final String JavaDoc NAME = "lockOwnerName";
2115
2116        public QValueType getOutputValueType() {
2117            return QValueType.STRING;
2118        }
2119
2120        public Object JavaDoc getOutputValue(Document document, Version version) {
2121            LockInfo lockInfo;
2122            try {
2123                lockInfo = document.getLockInfo(false);
2124            } catch (RepositoryException e) {
2125                throw new RuntimeException JavaDoc(e);
2126            }
2127            if (lockInfo.hasLock()) {
2128                return getUserDisplayName(lockInfo.getUserId());
2129            } else {
2130                return null;
2131            }
2132        }
2133
2134        public String JavaDoc getName() {
2135            return NAME;
2136        }
2137    }
2138
2139    public final class LockTimeAcquiredIdentifier extends AbstractNonAclIdentifier {
2140        public static final String JavaDoc NAME = "lockTimeAcquired";
2141
2142        public QValueType getValueType() {
2143            return QValueType.DATETIME;
2144        }
2145
2146        public Object JavaDoc evaluate(Document document, Version version) {
2147            LockInfo lockInfo;
2148            try {
2149                lockInfo = document.getLockInfo(false);
2150            } catch (RepositoryException e) {
2151                throw new RuntimeException JavaDoc(e);
2152            }
2153            if (lockInfo.hasLock()) {
2154                return lockInfo.getTimeAcquired();
2155            } else {
2156                return null;
2157            }
2158        }
2159
2160        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2161            context.needsJoinWithTable(SqlGenerationContext.LOCKS_TABLE);
2162
2163            sql.append(SqlGenerationContext.LOCKS_TABLE.getName());
2164            sql.append('.');
2165            sql.append(SqlGenerationContext.LocksTable.TIME_ACQUIRED);
2166        }
2167
2168        public QValueType getOutputValueType() {
2169            return QValueType.DATETIME;
2170        }
2171
2172        public Object JavaDoc getOutputValue(Document document, Version version) {
2173            return evaluate(document, version);
2174        }
2175
2176        public String JavaDoc getName() {
2177            return NAME;
2178        }
2179    }
2180
2181    public final class LockDurationIdentifier extends AbstractNonAclIdentifier {
2182        public static final String JavaDoc NAME = "lockDuration";
2183
2184        public QValueType getValueType() {
2185            return QValueType.LONG;
2186        }
2187
2188        public Object JavaDoc evaluate(Document document, Version version) {
2189            LockInfo lockInfo;
2190            try {
2191                lockInfo = document.getLockInfo(false);
2192            } catch (RepositoryException e) {
2193                throw new RuntimeException JavaDoc(e);
2194            }
2195            if (lockInfo.hasLock()) {
2196                return new Long JavaDoc(lockInfo.getDuration());
2197            } else {
2198                return null;
2199            }
2200        }
2201
2202        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2203            context.needsJoinWithTable(SqlGenerationContext.LOCKS_TABLE);
2204
2205            sql.append(SqlGenerationContext.LOCKS_TABLE.getName());
2206            sql.append('.');
2207            sql.append(SqlGenerationContext.LocksTable.DURATION);
2208        }
2209
2210        public QValueType getOutputValueType() {
2211            return QValueType.LONG;
2212        }
2213
2214        public Object JavaDoc getOutputValue(Document document, Version version) {
2215            return evaluate(document, version);
2216        }
2217
2218        public String JavaDoc getName() {
2219            return NAME;
2220        }
2221    }
2222
2223    public final class OwnerIdIdentifier extends AbstractNonAclIdentifier {
2224        public static final String JavaDoc NAME = "ownerId";
2225
2226        public QValueType getValueType() {
2227            return QValueType.LONG;
2228        }
2229
2230        public Object JavaDoc evaluate(Document document, Version version) {
2231            return new Long JavaDoc(document.getOwner());
2232        }
2233
2234        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2235            sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME);
2236            sql.append('.');
2237            sql.append(SqlGenerationContext.DocumentsTable.OWNER);
2238        }
2239
2240        public QValueType getOutputValueType() {
2241            return QValueType.LONG;
2242        }
2243
2244        public Object JavaDoc getOutputValue(Document document, Version version) {
2245            return evaluate(document, version);
2246        }
2247
2248        public String JavaDoc getName() {
2249            return NAME;
2250        }
2251    }
2252
2253    public final class OwnerLoginIdentifier extends AbstractLoginIdentifier {
2254        public static final String JavaDoc NAME = "ownerLogin";
2255
2256        public Object JavaDoc evaluate(Document document, Version version) {
2257            return new Long JavaDoc(document.getOwner());
2258        }
2259
2260        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2261            sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME);
2262            sql.append('.');
2263            sql.append(SqlGenerationContext.DocumentsTable.OWNER);
2264        }
2265
2266        public Object JavaDoc getOutputValue(Document document, Version version) {
2267            return getUserLogin(document.getOwner());
2268        }
2269
2270        public String JavaDoc getName() {
2271            return NAME;
2272        }
2273    }
2274
2275    public final class OwnerNameIdentifier extends AbstractOutputIdentifier {
2276        public static final String JavaDoc NAME = "ownerName";
2277
2278        public QValueType getOutputValueType() {
2279            return QValueType.STRING;
2280        }
2281
2282        public Object JavaDoc getOutputValue(Document document, Version version) {
2283            return getUserDisplayName(document.getOwner());
2284        }
2285
2286        public String JavaDoc getName() {
2287            return NAME;
2288        }
2289    }
2290
2291    public final class LastModifierIdIdentifier extends AbstractNonAclIdentifier {
2292        public static final String JavaDoc NAME = "lastModifierId";
2293
2294        public QValueType getValueType() {
2295            return QValueType.LONG;
2296        }
2297
2298        public Object JavaDoc evaluate(Document document, Version version) {
2299            return new Long JavaDoc(document.getLastModifier());
2300        }
2301
2302        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2303            sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME);
2304            sql.append('.');
2305            sql.append(SqlGenerationContext.DocumentsTable.LAST_MODIFIER);
2306        }
2307
2308        public QValueType getOutputValueType() {
2309            return QValueType.LONG;
2310        }
2311
2312        public Object JavaDoc getOutputValue(Document document, Version version) {
2313            return evaluate(document, version);
2314        }
2315
2316        public String JavaDoc getName() {
2317            return NAME;
2318        }
2319    }
2320
2321    public final class LastModifierLoginIdentifier extends AbstractLoginIdentifier {
2322        public static final String JavaDoc NAME = "lastModifierLogin";
2323
2324        public Object JavaDoc evaluate(Document document, Version version) {
2325            return new Long JavaDoc(document.getLastModifier());
2326        }
2327
2328        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2329            sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME);
2330            sql.append('.');
2331            sql.append(SqlGenerationContext.DocumentsTable.LAST_MODIFIER);
2332        }
2333
2334        public Object JavaDoc getOutputValue(Document document, Version version) {
2335            long lastModifier = document.getLastModifier();
2336            return lastModifier != -1 ? getUserLogin(lastModifier) : null;
2337        }
2338
2339        public String JavaDoc getName() {
2340            return NAME;
2341        }
2342    }
2343
2344    public final class LastModifierNameIdentifier extends AbstractOutputIdentifier {
2345        public static final String JavaDoc NAME = "lastModifierName";
2346
2347        public QValueType getOutputValueType() {
2348            return QValueType.STRING;
2349        }
2350
2351        public Object JavaDoc getOutputValue(Document document, Version version) {
2352            long lastModifier = document.getLastModifier();
2353            return lastModifier != -1 ? getUserDisplayName(lastModifier) : null;
2354        }
2355
2356        public String JavaDoc getName() {
2357            return NAME;
2358        }
2359    }
2360
2361    public final class VariantLastModifierIdIdentifier extends AbstractNonAclIdentifier {
2362        public static final String JavaDoc NAME = "variantLastModifierId";
2363
2364        public QValueType getValueType() {
2365            return QValueType.LONG;
2366        }
2367
2368        public Object JavaDoc evaluate(Document document, Version version) {
2369            return new Long JavaDoc(document.getVariantLastModifier());
2370        }
2371
2372        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2373            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME);
2374            sql.append('.');
2375            sql.append(SqlGenerationContext.DocumentVariantsTable.LAST_MODIFIER);
2376        }
2377
2378        public QValueType getOutputValueType() {
2379            return QValueType.LONG;
2380        }
2381
2382        public Object JavaDoc getOutputValue(Document document, Version version) {
2383            return evaluate(document, version);
2384        }
2385
2386        public String JavaDoc getName() {
2387            return NAME;
2388        }
2389    }
2390
2391    public final class VariantLastModifierLoginIdentifier extends AbstractLoginIdentifier {
2392        public static final String JavaDoc NAME = "variantLastModifierLogin";
2393
2394        public Object JavaDoc evaluate(Document document, Version version) {
2395            return new Long JavaDoc(document.getLastModifier());
2396        }
2397
2398        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2399            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME);
2400            sql.append('.');
2401            sql.append(SqlGenerationContext.DocumentVariantsTable.LAST_MODIFIER);
2402        }
2403
2404        public Object JavaDoc getOutputValue(Document document, Version version) {
2405            long lastModifier = document.getVariantLastModifier();
2406            return lastModifier != -1 ? getUserLogin(lastModifier) : null;
2407        }
2408
2409        public String JavaDoc getName() {
2410            return NAME;
2411        }
2412    }
2413
2414    public final class VariantLastModifierNameIdentifier extends AbstractOutputIdentifier {
2415        public static final String JavaDoc NAME = "variantLastModifierName";
2416
2417        public QValueType getOutputValueType() {
2418            return QValueType.STRING;
2419        }
2420
2421        public Object JavaDoc getOutputValue(Document document, Version version) {
2422            long lastModifier = document.getVariantLastModifier();
2423            return lastModifier != -1 ? getUserDisplayName(lastModifier) : null;
2424        }
2425
2426        public String JavaDoc getName() {
2427            return NAME;
2428        }
2429    }
2430
2431    public final class LastModifiedIdentifier extends AbstractNonAclIdentifier {
2432        public static final String JavaDoc NAME = "lastModified";
2433
2434        public QValueType getValueType() {
2435            return QValueType.DATETIME;
2436        }
2437
2438        public Object JavaDoc evaluate(Document document, Version version) {
2439            return document.getLastModified();
2440        }
2441
2442        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2443            sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME);
2444            sql.append('.');
2445            sql.append(SqlGenerationContext.DocumentsTable.LAST_MODIFIED);
2446        }
2447
2448        public QValueType getOutputValueType() {
2449            return QValueType.DATETIME;
2450        }
2451
2452        public Object JavaDoc getOutputValue(Document document, Version version) {
2453            return evaluate(document, version);
2454        }
2455
2456        public String JavaDoc getName() {
2457            return NAME;
2458        }
2459    }
2460
2461    public final class VariantLastModifiedIdentifier extends AbstractNonAclIdentifier {
2462        public static final String JavaDoc NAME = "variantLastModified";
2463
2464        public QValueType getValueType() {
2465            return QValueType.DATETIME;
2466        }
2467
2468        public Object JavaDoc evaluate(Document document, Version version) {
2469            return document.getVariantLastModified();
2470        }
2471
2472        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2473            sql.append(SqlGenerationContext.DocumentVariantsTable.TABLE_NAME);
2474            sql.append('.');
2475            sql.append(SqlGenerationContext.DocumentVariantsTable.LAST_MODIFIED);
2476        }
2477
2478        public QValueType getOutputValueType() {
2479            return QValueType.DATETIME;
2480        }
2481
2482        public Object JavaDoc getOutputValue(Document document, Version version) {
2483            return evaluate(document, version);
2484        }
2485
2486        public String JavaDoc getName() {
2487            return NAME;
2488        }
2489    }
2490
2491    public final class VersionIdIdentifier extends AbstractNonAclIdentifier {
2492        public static final String JavaDoc NAME = "versionId";
2493
2494        public QValueType getValueType() {
2495            return QValueType.LONG;
2496        }
2497
2498        public Object JavaDoc evaluate(Document document, Version version) {
2499            if (version != null) {
2500                return new Long JavaDoc(version.getId());
2501            } else {
2502                return new Long JavaDoc(document.getLastVersionId());
2503            }
2504        }
2505
2506        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2507            context.needsJoinWithTable(SqlGenerationContext.VERSIONS_TABLE);
2508
2509            sql.append(SqlGenerationContext.VERSIONS_TABLE.getName());
2510            sql.append('.');
2511            sql.append(SqlGenerationContext.VersionsTable.ID);
2512        }
2513
2514        public QValueType getOutputValueType() {
2515            return QValueType.LONG;
2516        }
2517
2518        public Object JavaDoc getOutputValue(Document document, Version version) {
2519            return evaluate(document, version);
2520        }
2521
2522        public String JavaDoc getName() {
2523            return NAME;
2524        }
2525    }
2526
2527    public class CustomFieldIdentifier extends AbstractNonAclIdentifier {
2528        private final String JavaDoc name;
2529        private String JavaDoc alias;
2530
2531        public CustomFieldIdentifier(String JavaDoc name) {
2532            this.name = name;
2533        }
2534
2535        public QValueType getValueType() {
2536            return QValueType.STRING;
2537        }
2538
2539        public Object JavaDoc evaluate(Document document, Version version) {
2540            return document.getCustomField(name);
2541        }
2542
2543        public String JavaDoc getSqlPreConditions(SqlGenerationContext context) throws QueryException {
2544            alias = context.getNewCustomFieldsTableAlias();
2545            return alias + '.' + SqlGenerationContext.CustomFieldsTable.NAME + " = ? ";
2546        }
2547
2548        public void generateSqlValueExpr(StringBuffer JavaDoc sql, SqlGenerationContext context) {
2549            sql.append(alias);
2550            sql.append('.');
2551            sql.append(SqlGenerationContext.CustomFieldsTable.VALUE);
2552        }
2553
2554        public int bindPreConditions(PreparedStatement JavaDoc stmt, int bindPos) throws SQLException JavaDoc, QueryException {
2555            stmt.setString(bindPos, name);
2556            bindPos++;
2557            return bindPos;
2558        }
2559
2560        public QValueType getOutputValueType() {
2561            return QValueType.STRING;
2562        }
2563
2564        public Object JavaDoc getOutputValue(Document document, Version version) {
2565            return evaluate(document, version);
2566        }
2567
2568        public String JavaDoc getName() {
2569            return '#' + name;
2570        }
2571
2572        public String JavaDoc getTitle(Locale JavaDoc locale) {
2573            return name;
2574        }
2575    }
2576
2577}
2578
Popular Tags