1 // Copyright 2010 Google Inc. All Rights Reserved.
3 package com
.google
.appengine
.api
.search
.checkers
;
5 import com
.google
.appengine
.api
.search
.Util
;
6 import com
.google
.apphosting
.api
.AppEngineInternal
;
7 import com
.google
.apphosting
.api
.search
.DocumentPb
;
8 import com
.google
.common
.collect
.Sets
;
13 * Checks values of a {@link com.google.appengine.api.search.Document}.
17 public final class DocumentChecker
{
19 private static final long MILLIS_UP_TO_1ST_JAN_2011
= 1293840000000L;
22 * The maximum length of a document id.
23 * @deprecated From 1.7.4, use {@link SearchApiLimits#MAXIMUM_DOCUMENT_ID_LENGTH}
25 @Deprecated public static final int MAXIMUM_DOCUMENT_ID_LENGTH
= 500;
28 * The maximum length of a document.
29 * @deprecated From 1.7.4, use {@link SearchApiLimits#MAXIMUM_DOCUMENT_LENGTH}
31 @Deprecated public static final int MAXIMUM_DOCUMENT_LENGTH
= 1 << 20;
34 * Checks whether a document id is valid. A document id is a
35 * non-null ASCII visible printable string of
36 * {@literal #MAXIMUM_DOCUMENT_ID_LENGTH} characters which does not start
37 * with '!' which is reserved for system documents.
39 * @param documentId the document id to check
40 * @return the checked document id
41 * @throws IllegalArgumentException if the document id is invalid
43 public static String
checkDocumentId(String documentId
) {
44 Preconditions
.checkArgument(!Util
.isNullOrEmpty(documentId
), "Document id is null or empty");
45 Preconditions
.checkArgument(
46 documentId
.length() <= SearchApiLimits
.MAXIMUM_DOCUMENT_ID_LENGTH
,
47 "Document id is longer than %d: %s",
48 SearchApiLimits
.MAXIMUM_DOCUMENT_ID_LENGTH
, documentId
);
49 Preconditions
.checkArgument(IndexChecker
.isAsciiVisiblePrintable(documentId
),
50 "documentId must be ASCII visible printable: %s", documentId
);
51 Preconditions
.checkArgument(!IndexChecker
.isReserved(documentId
),
52 "documentId must not start with !: %s", documentId
);
57 * Checks whether a document's field set is valid.
58 * A field set is valid if it does not contain any number or date fields with the same name.
60 * @param document the document to check
61 * @throws IllegalArgumentException if the document contains an invalid set of fields.
63 public static void checkFieldSet(DocumentPb
.Document document
) {
64 Set
<String
> noRepeatNames
= Sets
.newHashSet();
65 for (DocumentPb
.Field field
: document
.getFieldList()) {
66 if (field
.getValue().getType() == DocumentPb
.FieldValue
.ContentType
.NUMBER
||
67 field
.getValue().getType() == DocumentPb
.FieldValue
.ContentType
.DATE
) {
68 if (noRepeatNames
.contains(field
.getName())) {
69 throw new IllegalArgumentException(
70 "Invalid document " + document
.getId() + ": field " + field
.getName() +
71 "with type date or number may not be repeated.");
73 noRepeatNames
.add(field
.getName());
79 * Checks whether a {@link DocumentPb.Document} has a valid set
82 * @param pb the {@link DocumentPb.Document} protocol buffer to check
83 * @return the checked document
84 * @throws IllegalArgumentException if some field is invalid such as
85 * document id or fields
87 public static DocumentPb
.Document
checkValid(DocumentPb
.Document pb
) {
88 Preconditions
.checkArgument(pb
.getSerializedSize() <= SearchApiLimits
.MAXIMUM_DOCUMENT_LENGTH
,
89 "Document length %d is greater than the maximum %d bytes",
90 pb
.getSerializedSize(), SearchApiLimits
.MAXIMUM_DOCUMENT_LENGTH
);
92 checkDocumentId(pb
.getId());
94 Preconditions
.checkArgument(pb
.getFieldList() != null,
95 "Null list of fields in document for indexing");
101 * @return the number of seconds since 2011/1/1
103 public static int getNumberOfSecondsSince() {
104 long millisSince
= Math
.max(0L,
105 (System
.currentTimeMillis() - MILLIS_UP_TO_1ST_JAN_2011
) / 1000L);
106 Preconditions
.checkArgument(millisSince
<= Integer
.MAX_VALUE
,
107 "API failure due to date conversion overflow");
108 return (int) millisSince
;