Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / api / search / Schema.java
blobd86f73eb8a5d030d7b87bc507bbe28dab9e490c2
1 // Copyright 2011 Google Inc. All Rights Reserved.
3 package com.google.appengine.api.search;
5 import com.google.appengine.api.search.checkers.FieldChecker;
6 import com.google.apphosting.api.search.DocumentPb;
8 import java.util.ArrayList;
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
15 /**
16 * Contains information about the kinds of document {@link Field Fields}
17 * which are supported by the {@link Index}.
18 * <p>
19 * <pre>
20 * // Get the searchService for the default namespace
21 * SearchService searchService = SearchServiceFactory.getSearchService();
23 * // List the first page of indexes available and retrieve schemas
24 * ListIndexesResponse response = searchService.listIndexes(
25 * ListIndexesRequest.newBuilder().setSchemaFetched(true).build());
27 * // List out elements of Schema
28 * for (Index index : response) {
29 * Schema schema = index.getSchema();
30 * for (String fieldName : schema.getFieldNames()) {
31 * List<FieldType> typesForField = schema.getFieldTypes(fieldName);
32 * }
33 * }
34 * </pre>
37 public final class Schema {
39 /**
40 * A builder which constructs Schema objects.
42 public static final class Builder {
43 private final Map<String, List<Field.FieldType>> fieldMap =
44 new HashMap<String, List<Field.FieldType>>();
46 /**
47 * Constructs a builder for a schema.
49 protected Builder() {
52 /**
53 * Adds typed field name to the schema builder. Allows multiple
54 * field types with the same name.
56 * @param fieldName the field name to add to the schema
57 * @return this document builder
59 public Builder addTypedField(String fieldName, Field.FieldType fieldType) {
60 FieldChecker.checkFieldName(fieldName);
61 List<Field.FieldType> types = fieldMap.get(fieldName);
62 if (types == null) {
63 types = new ArrayList<Field.FieldType>();
64 fieldMap.put(fieldName, types);
66 types.add(fieldType);
67 return this;
70 /**
71 * Builds a valid document. The builder must have set a valid document
72 * id, and have a non-empty set of valid fields.
74 * @return the schema built by this builder
75 * @throws IllegalArgumentException if the document built is not valid
77 public Schema build() {
78 return new Schema(this);
82 private final Map<String, List<Field.FieldType>> fieldMap;
84 /**
85 * Creates a {@link Schema} from a {@link Builder}.
87 * @param builder the builder
89 private Schema(Builder builder) {
90 this.fieldMap = Collections.unmodifiableMap(builder.fieldMap);
93 /**
94 * @return the set of field names supported in the schema
96 public Set<String> getFieldNames() {
97 return fieldMap.keySet();
101 * @param fieldName the name of the field to return supported types
102 * @return a list of {@link Field.FieldType} supported for the given field
103 * name
105 public List<Field.FieldType> getFieldTypes(String fieldName) {
106 return Collections.unmodifiableList(fieldMap.get(fieldName));
109 @Override
110 public String toString() {
111 return String.format("Schema{fieldMap: %s}", fieldMap);
115 * Maps between DocumentPb.FieldValue.ContentType enums and the public
116 * Field.FieldType.
118 static Field.FieldType mapPBFieldTypeToPublic(DocumentPb.FieldValue.ContentType type) {
119 switch (type) {
120 case TEXT:
121 return Field.FieldType.TEXT;
122 case HTML:
123 return Field.FieldType.HTML;
124 case ATOM:
125 return Field.FieldType.ATOM;
126 case DATE:
127 return Field.FieldType.DATE;
128 case NUMBER:
129 return Field.FieldType.NUMBER;
130 case GEO:
131 return Field.FieldType.GEO_POINT;
132 default:
133 throw new IllegalArgumentException("Unsupported field type " + type);
138 * Maps between public Field.Field enums and the protocol buffer
139 * TypeDocumentPb.FieldValue.ContentType enums.
141 static DocumentPb.FieldValue.ContentType mapPublicFieldTypeToPB(Field.FieldType type) {
142 switch (type) {
143 case TEXT:
144 return DocumentPb.FieldValue.ContentType.TEXT;
145 case HTML:
146 return DocumentPb.FieldValue.ContentType.HTML;
147 case ATOM:
148 return DocumentPb.FieldValue.ContentType.ATOM;
149 case DATE:
150 return DocumentPb.FieldValue.ContentType.DATE;
151 case NUMBER:
152 return DocumentPb.FieldValue.ContentType.NUMBER;
153 case GEO_POINT:
154 return DocumentPb.FieldValue.ContentType.GEO;
155 default:
156 throw new IllegalArgumentException("Unsupported field type " + type);
161 * Creates a {@link Schema} from a {@link SearchServicePb.IndexMetadata}.
163 * @param metadata the proto buffer containing supported field names
164 * and types.
165 * @return a {@link Schema} containing supported field names and field
166 * types for those names
168 static Schema createSchema(SearchServicePb.IndexMetadata metadata) {
169 if (metadata.getFieldCount() == 0) {
170 return null;
172 Map<String, List<Field.FieldType>> fieldMap = new HashMap<String, List<Field.FieldType>>();
173 Builder builder = newBuilder();
174 for (DocumentPb.FieldTypes fieldTypes : metadata.getFieldList()) {
175 String fieldName = fieldTypes.getName();
176 for (DocumentPb.FieldValue.ContentType type : fieldTypes.getTypeList()) {
177 builder.addTypedField(fieldName, mapPBFieldTypeToPublic(type));
180 return builder.build();
183 @Override
184 public int hashCode() {
185 return fieldMap.hashCode();
188 @Override
189 public boolean equals(Object obj) {
190 if (this == obj) {
191 return true;
193 if (obj == null) {
194 return false;
196 if (getClass() != obj.getClass()) {
197 return false;
199 return fieldMap.equals(((Schema) obj).fieldMap);
203 * Creates a schema builder.
205 * @return a new builder for creating a schema
207 public static Builder newBuilder() {
208 return new Builder();