Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / api / search / checkers / DocumentChecker.java
blob8c1db5cf088e658872343cff264f9cc9128163ac
1 // Copyright 2010 Google Inc. All Rights Reserved.
3 package com.google.appengine.api.search.checkers;
5 import com.google.apphosting.api.AppEngineInternal;
6 import com.google.apphosting.api.search.DocumentPb;
7 import com.google.common.base.Strings;
8 import com.google.common.collect.Sets;
10 import java.util.Set;
12 /**
13 * Checks values of a {@link com.google.appengine.api.search.Document}.
16 @AppEngineInternal
17 public final class DocumentChecker {
19 private static final long MILLIS_UP_TO_1ST_JAN_2011 = 1293840000000L;
21 /**
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;
27 /**
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;
33 /**
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(!Strings.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 "Document id must be ASCII visible printable: %s", documentId);
51 Preconditions.checkArgument(!IndexChecker.isReserved(documentId),
52 "Document id must not start with !: %s", documentId);
53 return documentId;
56 /**
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());
78 /**
79 * Checks whether a {@link DocumentPb.Document} has a valid set
80 * of fields.
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);
91 if (pb.hasId()) {
92 checkDocumentId(pb.getId());
94 mandatoryCheckValid(pb);
95 return pb;
98 /**
99 * Does only the {@link DocumentPb.Document} validity checks that must be satisfied for all
100 * customer types that use the search API.
102 * @param pb the {@link DocumentPb.Document} protocol buffer to check
103 * @throws IllegalArgumentException if the document is invalid.
105 static void mandatoryCheckValid(DocumentPb.Document pb) {
106 Preconditions.checkArgument(pb.getFieldList() != null,
107 "Null list of fields in document for indexing");
108 checkFieldSet(pb);
112 * @return the number of seconds since 2011/1/1
114 public static int getNumberOfSecondsSince() {
115 long millisSince = Math.max(0L,
116 (System.currentTimeMillis() - MILLIS_UP_TO_1ST_JAN_2011) / 1000L);
117 Preconditions.checkArgument(millisSince <= Integer.MAX_VALUE,
118 "API failure due to date conversion overflow");
119 return (int) millisSince;