1 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 ; 34 import java.sql.SQLException ; 35 import java.util.Map ; 36 import java.util.HashMap ; 37 import java.util.Locale ; 38 import java.util.ResourceBundle ; 39 import java.lang.reflect.Constructor ; 40 import java.io.ByteArrayInputStream ; 41 42 public final class Identifier implements ValueExpr, Cloneable { 43 private final String id; 44 private DelegateIdentifier delegate; 45 private QueryContext queryContext; 46 private int line = -1; 47 private int column = -1; 48 private static final Map delegateClasses = new HashMap (); 49 static { 50 try { 51 delegateClasses.put(DocumentTypeIdentifier.NAME, DocumentTypeIdentifier.class.getConstructor(new Class [] { Identifier.class })); 52 delegateClasses.put(DocumentNameIdentifier.NAME, DocumentNameIdentifier.class.getConstructor(new Class [] { Identifier.class })); 53 delegateClasses.put(CreationTimeIdentifier.NAME, CreationTimeIdentifier.class.getConstructor(new Class [] { Identifier.class })); 54 delegateClasses.put(DocumentIdIdentifier.NAME, DocumentIdIdentifier.class.getConstructor(new Class [] { Identifier.class })); 55 delegateClasses.put(DocumentLinkIdentifier.NAME, DocumentLinkIdentifier.class.getConstructor(new Class [] { Identifier.class })); 56 delegateClasses.put(SummaryIdentifier.NAME, SummaryIdentifier.class.getConstructor(new Class [] { Identifier.class })); 57 delegateClasses.put(VersionCreationTimeIdentifier.NAME, VersionCreationTimeIdentifier.class.getConstructor(new Class [] { Identifier.class })); 58 delegateClasses.put(VersionCreatorIdIdentifier.NAME, VersionCreatorIdIdentifier.class.getConstructor(new Class [] { Identifier.class })); 59 delegateClasses.put(VersionCreatorNameIdentifier.NAME, VersionCreatorNameIdentifier.class.getConstructor(new Class [] { Identifier.class })); 60 delegateClasses.put(VersionCreatorLoginIdentifier.NAME, VersionCreatorLoginIdentifier.class.getConstructor(new Class [] { Identifier.class })); 61 delegateClasses.put(VersionStateIdentifier.NAME, VersionStateIdentifier.class.getConstructor(new Class [] { Identifier.class })); 62 delegateClasses.put(TotalSizeOfPartsIdentifier.NAME, TotalSizeOfPartsIdentifier.class.getConstructor(new Class [] { Identifier.class })); 63 delegateClasses.put(VersionStateLastModifiedIdentifier.NAME, VersionStateLastModifiedIdentifier.class.getConstructor(new Class [] { Identifier.class })); 64 delegateClasses.put(RetiredIdentifier.NAME, RetiredIdentifier.class.getConstructor(new Class [] { Identifier.class })); 65 delegateClasses.put(PrivateIdentifier.NAME, PrivateIdentifier.class.getConstructor(new Class [] { Identifier.class })); 66 delegateClasses.put(LockTypeIdentifier.NAME, LockTypeIdentifier.class.getConstructor(new Class [] { Identifier.class })); 67 delegateClasses.put(LockOwnerIdIdentifier.NAME, LockOwnerIdIdentifier.class.getConstructor(new Class [] { Identifier.class })); 68 delegateClasses.put(LockOwnerLoginIdentifier.NAME, LockOwnerLoginIdentifier.class.getConstructor(new Class [] { Identifier.class })); 69 delegateClasses.put(LockOwnerNameIdentifier.NAME, LockOwnerNameIdentifier.class.getConstructor(new Class [] { Identifier.class })); 70 delegateClasses.put(LockDurationIdentifier.NAME, LockDurationIdentifier.class.getConstructor(new Class [] { Identifier.class })); 71 delegateClasses.put(LockTimeAcquiredIdentifier.NAME, LockTimeAcquiredIdentifier.class.getConstructor(new Class [] { Identifier.class })); 72 delegateClasses.put(OwnerIdIdentifier.NAME, OwnerIdIdentifier.class.getConstructor(new Class [] { Identifier.class })); 73 delegateClasses.put(OwnerLoginIdentifier.NAME, OwnerLoginIdentifier.class.getConstructor(new Class [] { Identifier.class })); 74 delegateClasses.put(OwnerNameIdentifier.NAME, OwnerNameIdentifier.class.getConstructor(new Class [] { Identifier.class })); 75 delegateClasses.put(LastModifierIdIdentifier.NAME, LastModifierIdIdentifier.class.getConstructor(new Class [] { Identifier.class })); 76 delegateClasses.put(LastModifierLoginIdentifier.NAME, LastModifierLoginIdentifier.class.getConstructor(new Class [] { Identifier.class })); 77 delegateClasses.put(LastModifierNameIdentifier.NAME, LastModifierNameIdentifier.class.getConstructor(new Class [] { Identifier.class })); 78 delegateClasses.put(LastModifiedIdentifier.NAME, LastModifiedIdentifier.class.getConstructor(new Class [] { Identifier.class })); 79 delegateClasses.put(BranchIdIdentifier.NAME, BranchIdIdentifier.class.getConstructor(new Class [] { Identifier.class })); 80 delegateClasses.put(BranchNameIdentifier.NAME, BranchNameIdentifier.class.getConstructor(new Class [] { Identifier.class })); 81 delegateClasses.put(LanguageIdIdentifier.NAME, LanguageIdIdentifier.class.getConstructor(new Class [] { Identifier.class })); 82 delegateClasses.put(LanguageNameIdentifier.NAME, LanguageNameIdentifier.class.getConstructor(new Class [] { Identifier.class })); 83 delegateClasses.put(VariantLastModifiedIdentifier.NAME, VariantLastModifiedIdentifier.class.getConstructor(new Class [] { Identifier.class })); 84 delegateClasses.put(VariantLastModifierIdIdentifier.NAME, VariantLastModifierIdIdentifier.class.getConstructor(new Class [] { Identifier.class })); 85 delegateClasses.put(VariantLastModifierLoginIdentifier.NAME, VariantLastModifierLoginIdentifier.class.getConstructor(new Class [] { Identifier.class })); 86 delegateClasses.put(VariantLastModifierNameIdentifier.NAME, VariantLastModifierNameIdentifier.class.getConstructor(new Class [] { Identifier.class })); 87 delegateClasses.put(CollectionsIdentifier.NAME, CollectionsIdentifier.class.getConstructor(new Class [] { Identifier.class })); 88 delegateClasses.put(CollectionsValueCountIdentifier.NAME, CollectionsValueCountIdentifier.class.getConstructor(new Class [] { Identifier.class })); 89 delegateClasses.put(VersionIdIdentifier.NAME, VersionIdIdentifier.class.getConstructor(new Class [] { Identifier.class })); 90 } catch (Exception e) { 91 throw new RuntimeException ("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; 108 public Identifier(String id) { 109 this.id = id; 110 } 111 112 protected Identifier(String id, QueryContext context, DelegateIdentifier delegate) { 113 this.id = id; 114 this.queryContext = context; 115 this.delegate = delegate; 116 } 117 118 protected Object 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 ("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 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) == '$') { String fieldName = id.substring(1); 153 154 String 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) == '%') { String 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 subPartId = partId.substring(dotPos + 1); 202 String 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 customFieldName = id.substring(1); 222 this.delegate = new CustomFieldIdentifier(customFieldName); 223 } else { 224 Constructor constructor = (Constructor )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 [] { this }); 230 } catch (Exception e) { 231 throw new QueryException("Error instantiating identifier class.", e); 232 } 233 } 234 } 235 } 236 237 public Object evaluate(QValueType valueType, EvaluationContext evaluationContext) { 238 throw new RuntimeException ("Identifier \"" + getExpression() + "\"is used in a place where it cannot be evaluated."); 239 } 240 241 public Object evaluate(QValueType valueType, Document document, Version version, EvaluationContext evaluationContext) throws QueryException { 242 return delegate.evaluate(document, version); 243 } 244 245 public String getSqlPreConditions(SqlGenerationContext context) throws QueryException { 246 return delegate.getSqlPreConditions(context); 247 } 248 249 public void generateSqlValueExpr(StringBuffer sql, SqlGenerationContext context) throws QueryException { 250 delegate.generateSqlValueExpr(sql, context); 251 } 252 253 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException , QueryException { 254 return delegate.bindPreConditions(stmt, bindPos); 255 } 256 257 public int bindValueExpr(PreparedStatement stmt, int bindPos, QValueType valueType, 258 EvaluationContext evaluationContext) throws SQLException , 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 getOutputValue(Document document, Version version, EvaluationContext evaluationContext) { 279 return delegate.getOutputValue(document, version); 280 } 281 282 public String getTitle(Locale locale) { 283 return delegate.getTitle(locale); 284 } 285 286 public String getExpression() { 287 return id; 288 } 289 290 293 public AclConditionViolation isAclAllowed() { 294 return delegate.isAclAllowed(); 295 } 296 297 301 public boolean canTestAppliesTo() { 302 return delegate.canTestappliesTo(); 303 } 304 305 public boolean isSymbolicIdentifier() { 306 return delegate.isSymbolic(); 307 } 308 309 public Object translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 310 return delegate.translateSymbolic(valueExpr, evaluationContext); 311 } 312 313 317 public boolean isOutputOnly() { 318 return delegate.isOutputOnly(); 319 } 320 321 public DelegateIdentifier getDelegate() { 322 return delegate; 323 } 324 325 329 Identifier getValueCountIdentifier() { 330 return delegate.getValueCountIdentifier(); 331 } 332 333 interface DelegateIdentifier { 334 QValueType getValueType(); 335 boolean isMultiValue(); 336 Identifier getValueCountIdentifier(); 337 Object evaluate(Document document, Version version) throws QueryException; 338 AclConditionViolation isAclAllowed(); 339 String getSqlPreConditions(SqlGenerationContext context) throws QueryException; 340 void generateSqlValueExpr(StringBuffer sql, SqlGenerationContext context) throws QueryException; 341 int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException , QueryException; 342 public int bindValueExpr(PreparedStatement stmt, int bindPos, QValueType valueType) throws SQLException , QueryException; 343 boolean isSymbolic(); 344 Object translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException; 345 QValueType getOutputValueType(); 346 Object getOutputValue(Document document, Version version); 347 boolean canTestappliesTo(); 348 boolean isOutputOnly(); 349 String getName(); 350 String getTitle(Locale 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 getTitle(Locale locale) { 367 return getLocalizedString(getName(), locale); 368 } 369 370 public boolean isSymbolic() { 371 return false; 372 } 373 374 public Object 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 getSqlPreConditions(SqlGenerationContext context) throws QueryException { 383 return null; 384 } 385 386 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException , QueryException { 387 return bindPos; 388 } 389 390 public int bindValueExpr(PreparedStatement stmt, int bindPos, QValueType valueType) throws SQLException , 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 alias; 408 private QValueType valueType; 409 410 public FieldIdentifier(FieldType fieldType) { 411 this.fieldType = fieldType; 412 } 413 414 public String 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 ("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 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 processValue(Object value, Document document) { 465 if (fieldType.getValueType() == ValueType.LINK) { 466 if (fieldType.isMultiValue()) { 467 Object [] values = (Object [])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 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 getSqlPreConditions(SqlGenerationContext context) { 515 alias = context.getNewFieldsTableAlias(); 516 return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? "; 517 } 518 519 public void generateSqlValueExpr(StringBuffer sql, SqlGenerationContext context) { 520 String valueColumn = SqlGenerationContext.FieldsTable.getValueColumn(getValueType()); 521 sql.append(alias).append(".").append(valueColumn); 522 } 523 524 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException { 525 stmt.setLong(bindPos, fieldType.getId()); 526 return ++bindPos; 527 } 528 529 public String getTitle(Locale locale) { 530 return fieldType.getLabel(locale); 531 } 532 } 533 534 public final class FieldValueCountIdentifier extends AbstractNonAclIdentifier { 535 static final String NAME = "valueCount"; 536 private final FieldType fieldType; 537 private String alias; 538 539 public FieldValueCountIdentifier(FieldType fieldType) { 540 this.fieldType = fieldType; 541 } 542 543 public String getTitle(Locale locale) { 544 String fieldLabel = fieldType.getLabel(locale); 545 String valueCount = getLocalizedString("fieldValueCount", locale); 546 return fieldLabel + ": " + valueCount; 547 } 548 549 public QValueType getValueType() { 550 return QValueType.LONG; 551 } 552 553 public Object evaluate(Document document, Version version) { 554 if (version != null && version.hasField(fieldType.getId())) { 555 if (fieldType.isMultiValue()) { 556 return new Long (((Object [])version.getField(fieldType.getId()).getValue()).length); 557 } else { 558 return new Long (1); 559 } 560 } else if (version == null && document.hasField(fieldType.getId())) { 561 if (fieldType.isMultiValue()) { 562 return new Long (((Object [])document.getField(fieldType.getId()).getValue()).length); 563 } else { 564 return new Long (1); 565 } 566 } else { 567 return new Long (0); 568 } 569 } 570 571 public String getSqlPreConditions(SqlGenerationContext context) { 572 alias = context.getNewFieldsTableAlias(); 573 return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? "; 574 } 575 576 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 585 return evaluate(document, version); 586 } 587 588 public String getName() { 589 return "$" + fieldType.getName() + "." + NAME; 590 } 591 592 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException { 593 stmt.setLong(bindPos, fieldType.getId()); 594 return ++bindPos; 595 } 596 } 597 598 public final class LinkFieldDocumentIdIdentifier extends AbstractIdentifier { 599 public static final String NAME = "documentId"; 600 private final FieldType fieldType; 601 private String alias; 602 603 public LinkFieldDocumentIdIdentifier(FieldType fieldType) { 604 this.fieldType = fieldType; 605 } 606 607 public String 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 evaluate(Document document, Version version) { 620 if (version != null && version.hasField(fieldType.getId())) { 621 Object 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 extractDocIds(Object value) { 632 if (fieldType.isMultiValue()) { 633 Object [] values = (Object [])value; 634 Long [] ids = new Long [values.length]; 635 for (int i = 0; i < values.length; i++) 636 ids[i] = new Long (((VariantKey)values[i]).getDocumentId()); 637 return ids; 638 } else { 639 return new Long (((VariantKey)value).getDocumentId()); 640 } 641 } 642 643 public String getSqlPreConditions(SqlGenerationContext context) { 644 alias = context.getNewFieldsTableAlias(); 645 return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? "; 646 } 647 648 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException { 649 stmt.setLong(bindPos, fieldType.getId()); 650 return ++bindPos; 651 } 652 653 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 662 return evaluate(document, version); 663 } 664 665 public String getTitle(Locale locale) { 666 String fieldLabel = fieldType.getLabel(locale); 667 String branchId = getLocalizedString("id", locale); 668 return fieldLabel + ": " + branchId; 669 } 670 } 671 672 public class LinkFieldBranchIdIdentifier extends AbstractIdentifier { 673 public static final String NAME = "branchId"; 674 protected final FieldType fieldType; 675 private String alias; 676 677 public LinkFieldBranchIdIdentifier(FieldType fieldType) { 678 this.fieldType = fieldType; 679 } 680 681 public String 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 evaluate(Document document, Version version) { 694 if (version != null && version.hasField(fieldType.getId())) { 695 Object value = version.getField(fieldType.getId()).getValue(); 696 return extractBranchIds(value, document.getBranchId()); 697 } else if (version == null && document.hasField(fieldType.getId())) { 698 Object value = document.getField(fieldType.getId()).getValue(); 699 return extractBranchIds(value, document.getBranchId()); 700 } else { 701 return null; 702 } 703 } 704 705 private Object extractBranchIds(Object value, long documentBranchId) { 706 if (fieldType.isMultiValue()) { 707 Object [] values = (Object [])value; 708 Long [] ids = new Long [values.length]; 709 for (int i = 0; i < values.length; i++) { 710 VariantKey key = (VariantKey)values[i]; 711 ids[i] = new Long (key.getBranchId() != -1 ? key.getBranchId() : documentBranchId); 712 } 713 return ids; 714 } else { 715 VariantKey key = (VariantKey)value; 716 return new Long (key.getBranchId() != -1 ? key.getBranchId() : documentBranchId); 717 } 718 } 719 720 public String getSqlPreConditions(SqlGenerationContext context) { 721 alias = context.getNewFieldsTableAlias(); 722 return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? "; 723 } 724 725 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException { 726 stmt.setLong(bindPos, fieldType.getId()); 727 return ++bindPos; 728 } 729 730 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 739 return evaluate(document, version); 740 } 741 742 public String getTitle(Locale locale) { 743 String fieldLabel = fieldType.getLabel(locale); 744 String branchId = getLocalizedString("branchId", locale); 745 return fieldLabel + ": " + branchId; 746 } 747 } 748 749 public class LinkFieldLanguageIdIdentifier extends AbstractIdentifier { 750 public static final String NAME = "languageId"; 751 protected final FieldType fieldType; 752 private String alias; 753 754 public LinkFieldLanguageIdIdentifier(FieldType fieldType) { 755 this.fieldType = fieldType; 756 } 757 758 public String 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 evaluate(Document document, Version version) { 771 if (version != null && version.hasField(fieldType.getId())) { 772 Object value = version.getField(fieldType.getId()).getValue(); 773 return extractLanguageIds(value, document.getLanguageId()); 774 } else if (version == null && document.hasField(fieldType.getId())) { 775 Object value = document.getField(fieldType.getId()).getValue(); 776 return extractLanguageIds(value, document.getLanguageId()); 777 } else { 778 return null; 779 } 780 } 781 782 private Object extractLanguageIds(Object value, long documentLanguageId) { 783 if (fieldType.isMultiValue()) { 784 Object [] values = (Object [])value; 785 Long [] ids = new Long [values.length]; 786 for (int i = 0; i < values.length; i++) { 787 VariantKey key = (VariantKey)values[i]; 788 ids[i] = new Long (key.getLanguageId() != -1 ? key.getLanguageId() : documentLanguageId); 789 } 790 return ids; 791 } else { 792 VariantKey key = (VariantKey)value; 793 return new Long (key.getLanguageId() != -1 ? key.getLanguageId() : documentLanguageId); 794 } 795 } 796 797 public String getSqlPreConditions(SqlGenerationContext context) { 798 alias = context.getNewFieldsTableAlias(); 799 return alias + '.' + SqlGenerationContext.FieldsTable.FIELDTYPE_ID + " = ? "; 800 } 801 802 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException { 803 stmt.setLong(bindPos, fieldType.getId()); 804 return ++bindPos; 805 } 806 807 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 816 return evaluate(document, version); 817 } 818 819 public String getTitle(Locale locale) { 820 String fieldLabel = fieldType.getLabel(locale); 821 String languageId = getLocalizedString("languageId", locale); 822 return fieldLabel + ": " + languageId; 823 } 824 } 825 826 public final class LinkFieldBranchIdentifier extends LinkFieldBranchIdIdentifier { 827 public static final String NAME = "branch"; 828 829 public LinkFieldBranchIdentifier(FieldType fieldType) { 830 super(fieldType); 831 } 832 833 public String getName() { 834 return "$" + fieldType.getName() + "." + NAME; 835 } 836 837 public QValueType getOutputValueType() { 838 return QValueType.STRING; 839 } 840 841 public Object getOutputValue(Document document, Version version) { 842 try { 843 Object result = evaluate(document, version); 844 if (result == null) 845 return null; 846 if (fieldType.isMultiValue()) { 847 Object [] results = (Object [])result; 848 String [] names = new String [results.length]; 849 for (int i = 0; i < results.length; i++) { 850 names[i] = queryContext.getBranch(((Long )results[i]).longValue()).getName(); 851 } 852 return names; 853 } else { 854 return queryContext.getBranch(((Long )result).longValue()).getName(); 855 } 856 } catch (RepositoryException e) { 857 throw new RuntimeException (e); 858 } 859 } 860 861 public boolean isSymbolic() { 862 return true; 863 } 864 865 public Object translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 866 String branchName = (String )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 (branch.getId()); 874 } 875 876 public String getTitle(Locale locale) { 877 String fieldLabel = fieldType.getLabel(locale); 878 String branch = getLocalizedString("branch", locale); 879 return fieldLabel + ": " + branch; 880 } 881 } 882 883 public final class LinkFieldLanguageIdentifier extends LinkFieldLanguageIdIdentifier { 884 public static final String NAME = "language"; 885 886 public LinkFieldLanguageIdentifier(FieldType fieldType) { 887 super(fieldType); 888 } 889 890 public String getName() { 891 return "$" + fieldType.getName() + "." + NAME; 892 } 893 894 public QValueType getOutputValueType() { 895 return QValueType.STRING; 896 } 897 898 public Object getOutputValue(Document document, Version version) { 899 try { 900 Object result = evaluate(document, version); 901 if (result == null) 902 return null; 903 if (fieldType.isMultiValue()) { 904 Object [] results = (Object [])result; 905 String [] names = new String [results.length]; 906 for (int i = 0; i < results.length; i++) 907 names[i] = queryContext.getLanguage(((Long )results[i]).longValue()).getName(); 908 return names; 909 } else { 910 return queryContext.getLanguage(((Long )result).longValue()).getName(); 911 } 912 } catch (RepositoryException e) { 913 throw new RuntimeException (e); 914 } 915 } 916 917 public boolean isSymbolic() { 918 return true; 919 } 920 921 public Object translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 922 String languageName = (String )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 (language.getId()); 930 } 931 932 public String getTitle(Locale locale) { 933 String fieldLabel = fieldType.getLabel(locale); 934 String language = getLocalizedString("language", locale); 935 return fieldLabel + ": " + language; 936 } 937 } 938 939 public final class CollectionsIdentifier extends AbstractIdentifier { 940 public static final String NAME = "collections"; 941 942 public CollectionsIdentifier() { 943 } 944 945 public String 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 evaluate(Document document, Version version) { 962 DocumentCollection[] collections = document.getCollections().getArray(); 963 if (collections.length == 0) 964 return null; 965 Long [] collectionIds = new Long [collections.length]; 966 for (int i = 0; i < collectionIds.length; i++) 967 collectionIds[i] = new Long (collections[i].getId()); 968 return collectionIds; 969 } 970 971 public QValueType getOutputValueType() { 972 return QValueType.STRING; 973 } 974 975 public Object getOutputValue(Document document, Version version) { 976 DocumentCollection[] collections = document.getCollections().getArray(); 977 if (collections.length == 0) 978 return null; 979 String [] collectionNames = new String [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 sql, SqlGenerationContext context) { 990 String alias = context.getNewCollectionsTableAlias(); 991 sql.append(alias).append(".collection_id"); 992 } 993 994 public boolean isSymbolic() { 995 return true; 996 } 997 998 public Object translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 999 String collectionName = (String )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 (collection.getId()); 1009 } 1010 } 1011 1012 public final class CollectionsValueCountIdentifier extends AbstractNonAclIdentifier { 1013 public static final String NAME = "collections.valueCount"; 1014 1015 public String getName() { 1016 return NAME; 1017 } 1018 1019 public QValueType getValueType() { 1020 return QValueType.LONG; 1021 } 1022 1023 public Object evaluate(Document document, Version version) { 1024 return new Long (document.getCollections().getArray().length); 1025 } 1026 1027 public QValueType getOutputValueType() { 1028 return QValueType.LONG; 1029 } 1030 1031 public Object getOutputValue(Document document, Version version) { 1032 return evaluate(document, version); 1033 } 1034 1035 public void generateSqlValueExpr(StringBuffer 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 getTitle(Locale 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 ("Error getting last version of document " + document.getId(), e); 1057 } 1058 } 1059 1060 private String getUserDisplayName(long userId) { 1061 try { 1062 return queryContext.getUserDisplayName(userId); 1063 } catch (RepositoryException e) { 1064 throw new RuntimeException ("Error getting display name for user " + userId, e); 1065 } 1066 } 1067 1068 private String getUserLogin(long userId) { 1069 try { 1070 return queryContext.getUserLogin(userId); 1071 } catch (RepositoryException e) { 1072 throw new RuntimeException ("Error getting login for user " + userId, e); 1073 } 1074 } 1075 1076 private static String getLocalizedString(String name, Locale locale) { 1077 ResourceBundle 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 NAME = "documentType"; 1083 1084 public String getName() { 1085 return NAME; 1086 } 1087 1088 public QValueType getValueType() { 1089 return QValueType.LONG; 1090 } 1091 1092 public Object evaluate(Document document, Version version) { 1093 return new Long (document.getDocumentTypeId()); 1094 } 1095 1096 public QValueType getOutputValueType() { 1097 return QValueType.STRING; 1098 } 1099 1100 public Object 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 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 translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 1123 String documentTypeName = (String )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 (documentType.getId()); 1133 } 1134 } 1135 1136 public final class DocumentNameIdentifier extends AbstractNonAclIdentifier { 1137 public static final String NAME = "name"; 1138 1139 public String getName() { 1140 return NAME; 1141 } 1142 1143 public QValueType getValueType() { 1144 return QValueType.STRING; 1145 } 1146 1147 public Object evaluate(Document document, Version version) { 1148 return version != null ? version.getDocumentName() : null; 1149 } 1150 1151 public void generateSqlValueExpr(StringBuffer 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 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 NAME = "creationTime"; 1170 1171 public String getName() { 1172 return NAME; 1173 } 1174 1175 public QValueType getValueType() { 1176 return QValueType.DATETIME; 1177 } 1178 1179 public Object evaluate(Document document, Version version) { 1180 return document.getCreated(); 1181 } 1182 1183 public void generateSqlValueExpr(StringBuffer 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 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 NAME = "id"; 1200 1201 public String getName() { 1202 return NAME; 1203 } 1204 1205 public QValueType getValueType() { 1206 return QValueType.LONG; 1207 } 1208 1209 public Object evaluate(Document document, Version version) { 1210 return new Long (document.getId()); 1211 } 1212 1213 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 1224 return new Long (document.getId()); 1225 } 1226 } 1227 1228 public final class DocumentLinkIdentifier extends AbstractIdentifier { 1229 public static final String NAME = "link"; 1230 1231 public String getName() { 1232 return NAME; 1233 } 1234 1235 public QValueType getValueType() { 1236 return QValueType.LINK; 1237 } 1238 1239 public Object evaluate(Document document, Version version) { 1240 return document.getVariantKey(); 1241 } 1242 1243 public void generateSqlValueExpr(StringBuffer 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 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 NAME = "branchId"; 1264 1265 public String getName() { 1266 return NAME; 1267 } 1268 1269 public QValueType getValueType() { 1270 return QValueType.LONG; 1271 } 1272 1273 public Object evaluate(Document document, Version version) { 1274 return new Long (document.getBranchId()); 1275 } 1276 1277 public void generateSqlValueExpr(StringBuffer 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 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 NAME = "branch"; 1294 1295 public String getName() { 1296 return NAME; 1297 } 1298 1299 public QValueType getValueType() { 1300 return QValueType.LONG; 1301 } 1302 1303 public Object evaluate(Document document, Version version) { 1304 return new Long (document.getBranchId()); 1305 } 1306 1307 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 1318 try { 1319 return queryContext.getBranch(document.getBranchId()).getName(); 1320 } catch (RepositoryException e) { 1321 throw new RuntimeException (e); 1322 } 1323 } 1324 1325 public boolean isSymbolic() { 1326 return true; 1327 } 1328 1329 public Object translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 1330 String branchName = (String )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 (branch.getId()); 1338 } 1339 } 1340 1341 public final class LanguageIdIdentifier extends AbstractIdentifier { 1342 public static final String NAME = "languageId"; 1343 1344 public String getName() { 1345 return NAME; 1346 } 1347 1348 public QValueType getValueType() { 1349 return QValueType.LONG; 1350 } 1351 1352 public Object evaluate(Document document, Version version) { 1353 return new Long (document.getLanguageId()); 1354 } 1355 1356 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 1367 return new Long (document.getLanguageId()); 1368 } 1369 } 1370 1371 public final class LanguageNameIdentifier extends AbstractIdentifier { 1372 public static final String NAME = "language"; 1373 1374 public String getName() { 1375 return NAME; 1376 } 1377 1378 public QValueType getValueType() { 1379 return QValueType.LONG; 1380 } 1381 1382 public Object evaluate(Document document, Version version) { 1383 return new Long (document.getLanguageId()); 1384 } 1385 1386 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 1397 try { 1398 return queryContext.getLanguage(document.getLanguageId()).getName(); 1399 } catch (RepositoryException e) { 1400 throw new RuntimeException (e); 1401 } 1402 } 1403 1404 public boolean isSymbolic() { 1405 return true; 1406 } 1407 1408 public Object translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 1409 String languageName = (String )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 (language.getId()); 1417 } 1418 } 1419 1420 public final class VersionCreationTimeIdentifier extends AbstractNonAclIdentifier { 1421 public static final String NAME = "versionCreationTime"; 1422 1423 public String getName() { 1424 return NAME; 1425 } 1426 1427 public QValueType getValueType() { 1428 return QValueType.DATETIME; 1429 } 1430 1431 public Object 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 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 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 NAME = "totalSizeOfParts"; 1459 1460 public String getName() { 1461 return NAME; 1462 } 1463 1464 public QValueType getValueType() { 1465 return QValueType.LONG; 1466 } 1467 1468 public Object evaluate(Document document, Version version) { 1469 if (version != null) { 1470 return new Long (version.getTotalSizeOfParts()); 1471 } else { 1472 version = getLastVersion(document); 1473 return version != null ? new Long (version.getTotalSizeOfParts()) : null; 1474 } 1475 } 1476 1477 public void generateSqlValueExpr(StringBuffer 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 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 NAME = "versionStateLastModified"; 1496 1497 public String getName() { 1498 return NAME; 1499 } 1500 1501 public QValueType getValueType() { 1502 return QValueType.DATETIME; 1503 } 1504 1505 public Object 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 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 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 NAME = "versionCreatorId"; 1533 1534 public String getName() { 1535 return NAME; 1536 } 1537 1538 public QValueType getValueType() { 1539 return QValueType.LONG; 1540 } 1541 1542 public Object evaluate(Document document, Version version) { 1543 if (version != null) { 1544 return new Long (version.getCreator()); 1545 } else { 1546 version = getLastVersion(document); 1547 return version != null ? new Long (version.getCreator()) : null; 1548 } 1549 } 1550 1551 public void generateSqlValueExpr(StringBuffer 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 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 translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 1582 String login = (String )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 (userId); 1590 } 1591 } 1592 1593 public final class VersionCreatorLoginIdentifier extends AbstractLoginIdentifier { 1594 public static final String NAME = "versionCreatorLogin"; 1595 1596 public String getName() { 1597 return NAME; 1598 } 1599 1600 public Object evaluate(Document document, Version version) { 1601 if (version != null) { 1602 return new Long (version.getCreator()); 1603 } else { 1604 version = getLastVersion(document); 1605 return version != null ? new Long (version.getCreator()) : null; 1606 } 1607 } 1608 1609 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 1618 Long creatorId = (Long )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 NAME = "private"; 1625 1626 public String getName() { 1627 return NAME; 1628 } 1629 1630 public QValueType getValueType() { 1631 return QValueType.BOOLEAN; 1632 } 1633 1634 public Object evaluate(Document document, Version version) { 1635 return document.isPrivate() ? Boolean.TRUE : Boolean.FALSE; 1636 } 1637 1638 public void generateSqlValueExpr(StringBuffer 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 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 NAME = "retired"; 1655 1656 public String getName() { 1657 return NAME; 1658 } 1659 1660 public QValueType getValueType() { 1661 return QValueType.BOOLEAN; 1662 } 1663 1664 public Object evaluate(Document document, Version version) { 1665 return document.isRetired() ? Boolean.TRUE : Boolean.FALSE; 1666 } 1667 1668 public void generateSqlValueExpr(StringBuffer 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 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 NAME = "versionCreatorName"; 1685 1686 public QValueType getValueType() { 1687 return QValueType.STRING; 1688 } 1689 1690 public String getName() { 1691 return NAME; 1692 } 1693 1694 public QValueType getOutputValueType() { 1695 return QValueType.STRING; 1696 } 1697 1698 public Object 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 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 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 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 stmt, int bindPos) throws SQLException , QueryException { 1733 throw new IllegalStateException (); 1735 } 1736 1737 public int bindValueExpr(PreparedStatement stmt, int bindPos, QValueType valueType) throws SQLException , QueryException { 1738 throw new IllegalStateException (); 1740 } 1741 } 1742 1743 public final class SummaryIdentifier extends AbstractOutputIdentifier { 1744 public static final String NAME = "summary"; 1745 1746 public String getName() { 1747 return NAME; 1748 } 1749 1750 public QValueType getOutputValueType() { 1751 return QValueType.STRING; 1752 } 1753 1754 public Object getOutputValue(Document document, Version version) { 1755 return document.getSummary(); 1756 } 1757 } 1758 1759 public final class VersionStateIdentifier extends AbstractNonAclIdentifier { 1760 public static final String NAME = "versionState"; 1761 1762 public String getName() { 1763 return NAME; 1764 } 1765 1766 public QValueType getOutputValueType() { 1767 return QValueType.VERSION_STATE; 1768 } 1769 1770 public Object 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 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 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 translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 1805 String versionStateName = (String )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 name; 1813 private final PartType partType; 1814 1815 public PartContentIdentifier(String 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 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 (part.getData()), xmlOptions); 1831 } 1832 } catch (Exception 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 getName() { 1847 return name; 1848 } 1849 1850 public String getTitle(Locale locale) { 1851 return partType.getLabel(locale); 1852 } 1853 } 1854 1855 public final class PartMimeTypeIdentifier extends AbstractNonAclIdentifier { 1856 private final String name; 1857 private final PartType partType; 1858 private String alias; 1859 1860 public PartMimeTypeIdentifier(String 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 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 getSqlPreConditions(SqlGenerationContext context) { 1880 alias = context.getNewPartsTableAlias(); 1881 return alias + '.' + SqlGenerationContext.PartsTable.PARTTYPE_ID + " = ? "; 1882 } 1883 1884 public void generateSqlValueExpr(StringBuffer sql, SqlGenerationContext context) { 1885 sql.append(alias).append('.').append(SqlGenerationContext.PartsTable.MIMETYPE); 1886 } 1887 1888 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException { 1889 stmt.setLong(bindPos, partType.getId()); 1890 return ++bindPos; 1891 } 1892 1893 public QValueType getOutputValueType() { 1894 return QValueType.STRING; 1895 } 1896 1897 public Object getOutputValue(Document document, Version version) { 1898 return evaluate(document, version); 1899 } 1900 1901 public String getName() { 1902 return name; 1903 } 1904 1905 public String getTitle(Locale locale) { 1906 return partType.getLabel(locale) + " (" + getLocalizedString("part.mimetype", locale) + ")"; 1907 } 1908 } 1909 1910 public final class PartSizeIdentifier extends AbstractNonAclIdentifier { 1911 private final String name; 1912 private final PartType partType; 1913 private String alias; 1914 1915 public PartSizeIdentifier(String 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 evaluate(Document document, Version version) { 1925 if (version != null && version.hasPart(partType.getId())) { 1926 return new Long (version.getPart(partType.getId()).getSize()); 1927 } else if (version == null && document.hasPart(partType.getId())) { 1928 return new Long (document.getPart(partType.getId()).getSize()); 1929 } else { 1930 return null; 1931 } 1932 } 1933 1934 public String getSqlPreConditions(SqlGenerationContext context) { 1935 alias = context.getNewPartsTableAlias(); 1936 return alias + '.' + SqlGenerationContext.PartsTable.PARTTYPE_ID + " = ? "; 1937 } 1938 1939 public void generateSqlValueExpr(StringBuffer sql, SqlGenerationContext context) { 1940 sql.append(alias).append('.').append(SqlGenerationContext.PartsTable.SIZE); 1941 } 1942 1943 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException { 1944 stmt.setLong(bindPos, partType.getId()); 1945 return ++bindPos; 1946 } 1947 1948 public QValueType getOutputValueType() { 1949 return QValueType.LONG; 1950 } 1951 1952 public Object getOutputValue(Document document, Version version) { 1953 return evaluate(document, version); 1954 } 1955 1956 public String getName() { 1957 return name; 1958 } 1959 1960 public String getTitle(Locale 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 NAME = "lockType"; 1967 1968 public QValueType getValueType() { 1969 return QValueType.STRING; 1970 } 1971 1972 public Object evaluate(Document document, Version version) { 1973 LockInfo lockInfo; 1974 try { 1975 lockInfo = document.getLockInfo(false); 1976 } catch (RepositoryException e) { 1977 throw new RuntimeException (e); 1978 } 1979 if (lockInfo.hasLock()) { 1980 return lockInfo.getType().getCode(); 1981 } else { 1982 return null; 1983 } 1984 } 1985 1986 public void generateSqlValueExpr(StringBuffer 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 translateSymbolic(ValueExpr valueExpr, EvaluationContext evaluationContext) throws QueryException { 1999 String lockTypeName = (String )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 getOutputValue(Document document, Version version) { 2009 LockInfo lockInfo; 2010 try { 2011 lockInfo = document.getLockInfo(false); 2012 } catch (RepositoryException e) { 2013 throw new RuntimeException (e); 2014 } 2015 if (lockInfo.hasLock()) { 2016 return lockInfo.getType().toString(); 2017 } else { 2018 return null; 2019 } 2020 } 2021 2022 public String getName() { 2023 return NAME; 2024 } 2025 } 2026 2027 public final class LockOwnerIdIdentifier extends AbstractNonAclIdentifier { 2028 public static final String NAME = "lockOwnerId"; 2029 2030 public QValueType getValueType() { 2031 return QValueType.LONG; 2032 } 2033 2034 public Object evaluate(Document document, Version version) { 2035 LockInfo lockInfo; 2036 try { 2037 lockInfo = document.getLockInfo(false); 2038 } catch (RepositoryException e) { 2039 throw new RuntimeException (e); 2040 } 2041 if (lockInfo.hasLock()) { 2042 return new Long (lockInfo.getUserId()); 2043 } else { 2044 return null; 2045 } 2046 } 2047 2048 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2061 return evaluate(document, version); 2062 } 2063 2064 public String getName() { 2065 return NAME; 2066 } 2067 } 2068 2069 public final class LockOwnerLoginIdentifier extends AbstractLoginIdentifier { 2070 public static final String NAME = "lockOwnerLogin"; 2071 2072 public Object evaluate(Document document, Version version) { 2073 LockInfo lockInfo; 2074 try { 2075 lockInfo = document.getLockInfo(false); 2076 } catch (RepositoryException e) { 2077 throw new RuntimeException (e); 2078 } 2079 if (lockInfo.hasLock()) { 2080 return new Long (lockInfo.getUserId()); 2081 } else { 2082 return null; 2083 } 2084 } 2085 2086 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2095 LockInfo lockInfo; 2096 try { 2097 lockInfo = document.getLockInfo(false); 2098 } catch (RepositoryException e) { 2099 throw new RuntimeException (e); 2100 } 2101 if (lockInfo.hasLock()) { 2102 return getUserLogin(lockInfo.getUserId()); 2103 } else { 2104 return null; 2105 } 2106 } 2107 2108 public String getName() { 2109 return NAME; 2110 } 2111 } 2112 2113 public final class LockOwnerNameIdentifier extends AbstractOutputIdentifier { 2114 public static final String NAME = "lockOwnerName"; 2115 2116 public QValueType getOutputValueType() { 2117 return QValueType.STRING; 2118 } 2119 2120 public Object getOutputValue(Document document, Version version) { 2121 LockInfo lockInfo; 2122 try { 2123 lockInfo = document.getLockInfo(false); 2124 } catch (RepositoryException e) { 2125 throw new RuntimeException (e); 2126 } 2127 if (lockInfo.hasLock()) { 2128 return getUserDisplayName(lockInfo.getUserId()); 2129 } else { 2130 return null; 2131 } 2132 } 2133 2134 public String getName() { 2135 return NAME; 2136 } 2137 } 2138 2139 public final class LockTimeAcquiredIdentifier extends AbstractNonAclIdentifier { 2140 public static final String NAME = "lockTimeAcquired"; 2141 2142 public QValueType getValueType() { 2143 return QValueType.DATETIME; 2144 } 2145 2146 public Object evaluate(Document document, Version version) { 2147 LockInfo lockInfo; 2148 try { 2149 lockInfo = document.getLockInfo(false); 2150 } catch (RepositoryException e) { 2151 throw new RuntimeException (e); 2152 } 2153 if (lockInfo.hasLock()) { 2154 return lockInfo.getTimeAcquired(); 2155 } else { 2156 return null; 2157 } 2158 } 2159 2160 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2173 return evaluate(document, version); 2174 } 2175 2176 public String getName() { 2177 return NAME; 2178 } 2179 } 2180 2181 public final class LockDurationIdentifier extends AbstractNonAclIdentifier { 2182 public static final String NAME = "lockDuration"; 2183 2184 public QValueType getValueType() { 2185 return QValueType.LONG; 2186 } 2187 2188 public Object evaluate(Document document, Version version) { 2189 LockInfo lockInfo; 2190 try { 2191 lockInfo = document.getLockInfo(false); 2192 } catch (RepositoryException e) { 2193 throw new RuntimeException (e); 2194 } 2195 if (lockInfo.hasLock()) { 2196 return new Long (lockInfo.getDuration()); 2197 } else { 2198 return null; 2199 } 2200 } 2201 2202 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2215 return evaluate(document, version); 2216 } 2217 2218 public String getName() { 2219 return NAME; 2220 } 2221 } 2222 2223 public final class OwnerIdIdentifier extends AbstractNonAclIdentifier { 2224 public static final String NAME = "ownerId"; 2225 2226 public QValueType getValueType() { 2227 return QValueType.LONG; 2228 } 2229 2230 public Object evaluate(Document document, Version version) { 2231 return new Long (document.getOwner()); 2232 } 2233 2234 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2245 return evaluate(document, version); 2246 } 2247 2248 public String getName() { 2249 return NAME; 2250 } 2251 } 2252 2253 public final class OwnerLoginIdentifier extends AbstractLoginIdentifier { 2254 public static final String NAME = "ownerLogin"; 2255 2256 public Object evaluate(Document document, Version version) { 2257 return new Long (document.getOwner()); 2258 } 2259 2260 public void generateSqlValueExpr(StringBuffer sql, SqlGenerationContext context) { 2261 sql.append(SqlGenerationContext.DocumentsTable.TABLE_NAME); 2262 sql.append('.'); 2263 sql.append(SqlGenerationContext.DocumentsTable.OWNER); 2264 } 2265 2266 public Object getOutputValue(Document document, Version version) { 2267 return getUserLogin(document.getOwner()); 2268 } 2269 2270 public String getName() { 2271 return NAME; 2272 } 2273 } 2274 2275 public final class OwnerNameIdentifier extends AbstractOutputIdentifier { 2276 public static final String NAME = "ownerName"; 2277 2278 public QValueType getOutputValueType() { 2279 return QValueType.STRING; 2280 } 2281 2282 public Object getOutputValue(Document document, Version version) { 2283 return getUserDisplayName(document.getOwner()); 2284 } 2285 2286 public String getName() { 2287 return NAME; 2288 } 2289 } 2290 2291 public final class LastModifierIdIdentifier extends AbstractNonAclIdentifier { 2292 public static final String NAME = "lastModifierId"; 2293 2294 public QValueType getValueType() { 2295 return QValueType.LONG; 2296 } 2297 2298 public Object evaluate(Document document, Version version) { 2299 return new Long (document.getLastModifier()); 2300 } 2301 2302 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2313 return evaluate(document, version); 2314 } 2315 2316 public String getName() { 2317 return NAME; 2318 } 2319 } 2320 2321 public final class LastModifierLoginIdentifier extends AbstractLoginIdentifier { 2322 public static final String NAME = "lastModifierLogin"; 2323 2324 public Object evaluate(Document document, Version version) { 2325 return new Long (document.getLastModifier()); 2326 } 2327 2328 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2335 long lastModifier = document.getLastModifier(); 2336 return lastModifier != -1 ? getUserLogin(lastModifier) : null; 2337 } 2338 2339 public String getName() { 2340 return NAME; 2341 } 2342 } 2343 2344 public final class LastModifierNameIdentifier extends AbstractOutputIdentifier { 2345 public static final String NAME = "lastModifierName"; 2346 2347 public QValueType getOutputValueType() { 2348 return QValueType.STRING; 2349 } 2350 2351 public Object getOutputValue(Document document, Version version) { 2352 long lastModifier = document.getLastModifier(); 2353 return lastModifier != -1 ? getUserDisplayName(lastModifier) : null; 2354 } 2355 2356 public String getName() { 2357 return NAME; 2358 } 2359 } 2360 2361 public final class VariantLastModifierIdIdentifier extends AbstractNonAclIdentifier { 2362 public static final String NAME = "variantLastModifierId"; 2363 2364 public QValueType getValueType() { 2365 return QValueType.LONG; 2366 } 2367 2368 public Object evaluate(Document document, Version version) { 2369 return new Long (document.getVariantLastModifier()); 2370 } 2371 2372 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2383 return evaluate(document, version); 2384 } 2385 2386 public String getName() { 2387 return NAME; 2388 } 2389 } 2390 2391 public final class VariantLastModifierLoginIdentifier extends AbstractLoginIdentifier { 2392 public static final String NAME = "variantLastModifierLogin"; 2393 2394 public Object evaluate(Document document, Version version) { 2395 return new Long (document.getLastModifier()); 2396 } 2397 2398 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2405 long lastModifier = document.getVariantLastModifier(); 2406 return lastModifier != -1 ? getUserLogin(lastModifier) : null; 2407 } 2408 2409 public String getName() { 2410 return NAME; 2411 } 2412 } 2413 2414 public final class VariantLastModifierNameIdentifier extends AbstractOutputIdentifier { 2415 public static final String NAME = "variantLastModifierName"; 2416 2417 public QValueType getOutputValueType() { 2418 return QValueType.STRING; 2419 } 2420 2421 public Object getOutputValue(Document document, Version version) { 2422 long lastModifier = document.getVariantLastModifier(); 2423 return lastModifier != -1 ? getUserDisplayName(lastModifier) : null; 2424 } 2425 2426 public String getName() { 2427 return NAME; 2428 } 2429 } 2430 2431 public final class LastModifiedIdentifier extends AbstractNonAclIdentifier { 2432 public static final String NAME = "lastModified"; 2433 2434 public QValueType getValueType() { 2435 return QValueType.DATETIME; 2436 } 2437 2438 public Object evaluate(Document document, Version version) { 2439 return document.getLastModified(); 2440 } 2441 2442 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2453 return evaluate(document, version); 2454 } 2455 2456 public String getName() { 2457 return NAME; 2458 } 2459 } 2460 2461 public final class VariantLastModifiedIdentifier extends AbstractNonAclIdentifier { 2462 public static final String NAME = "variantLastModified"; 2463 2464 public QValueType getValueType() { 2465 return QValueType.DATETIME; 2466 } 2467 2468 public Object evaluate(Document document, Version version) { 2469 return document.getVariantLastModified(); 2470 } 2471 2472 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2483 return evaluate(document, version); 2484 } 2485 2486 public String getName() { 2487 return NAME; 2488 } 2489 } 2490 2491 public final class VersionIdIdentifier extends AbstractNonAclIdentifier { 2492 public static final String NAME = "versionId"; 2493 2494 public QValueType getValueType() { 2495 return QValueType.LONG; 2496 } 2497 2498 public Object evaluate(Document document, Version version) { 2499 if (version != null) { 2500 return new Long (version.getId()); 2501 } else { 2502 return new Long (document.getLastVersionId()); 2503 } 2504 } 2505 2506 public void generateSqlValueExpr(StringBuffer 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 getOutputValue(Document document, Version version) { 2519 return evaluate(document, version); 2520 } 2521 2522 public String getName() { 2523 return NAME; 2524 } 2525 } 2526 2527 public class CustomFieldIdentifier extends AbstractNonAclIdentifier { 2528 private final String name; 2529 private String alias; 2530 2531 public CustomFieldIdentifier(String name) { 2532 this.name = name; 2533 } 2534 2535 public QValueType getValueType() { 2536 return QValueType.STRING; 2537 } 2538 2539 public Object evaluate(Document document, Version version) { 2540 return document.getCustomField(name); 2541 } 2542 2543 public String getSqlPreConditions(SqlGenerationContext context) throws QueryException { 2544 alias = context.getNewCustomFieldsTableAlias(); 2545 return alias + '.' + SqlGenerationContext.CustomFieldsTable.NAME + " = ? "; 2546 } 2547 2548 public void generateSqlValueExpr(StringBuffer sql, SqlGenerationContext context) { 2549 sql.append(alias); 2550 sql.append('.'); 2551 sql.append(SqlGenerationContext.CustomFieldsTable.VALUE); 2552 } 2553 2554 public int bindPreConditions(PreparedStatement stmt, int bindPos) throws SQLException , 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 getOutputValue(Document document, Version version) { 2565 return evaluate(document, version); 2566 } 2567 2568 public String getName() { 2569 return '#' + name; 2570 } 2571 2572 public String getTitle(Locale locale) { 2573 return name; 2574 } 2575 } 2576 2577} 2578 | Popular Tags |