App Engine Python SDK version 1.9.8
[gae.git] / java / src / main / com / google / appengine / api / search / Schema.java
bloba28f1197c2ee69fb41ae35ec9288ffa6ddcc3eba
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 * // Get the first page of indexes available and retrieve schemas
24 * GetResponse<Index> response = searchService.getIndexes(
25 * GetIndexesRequest.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. The returned list will be empty if the schema has no field with the given name.
105 public List<Field.FieldType> getFieldTypes(String fieldName) {
106 List<Field.FieldType> fieldTypes = fieldMap.get(fieldName);
107 if (fieldTypes != null) {
108 return Collections.unmodifiableList(fieldTypes);
110 return Collections.emptyList();
113 @Override
114 public String toString() {
115 return String.format("Schema{fieldMap: %s}", fieldMap);
119 * Maps between DocumentPb.FieldValue.ContentType enums and the public
120 * Field.FieldType.
122 static Field.FieldType mapPBFieldTypeToPublic(DocumentPb.FieldValue.ContentType type) {
123 switch (type) {
124 case TEXT:
125 return Field.FieldType.TEXT;
126 case HTML:
127 return Field.FieldType.HTML;
128 case ATOM:
129 return Field.FieldType.ATOM;
130 case DATE:
131 return Field.FieldType.DATE;
132 case NUMBER:
133 return Field.FieldType.NUMBER;
134 case GEO:
135 return Field.FieldType.GEO_POINT;
136 default:
137 throw new IllegalArgumentException("Unsupported field type " + type);
142 * Maps between public Field.Field enums and the protocol buffer
143 * TypeDocumentPb.FieldValue.ContentType enums.
145 static DocumentPb.FieldValue.ContentType mapPublicFieldTypeToPB(Field.FieldType type) {
146 switch (type) {
147 case TEXT:
148 return DocumentPb.FieldValue.ContentType.TEXT;
149 case HTML:
150 return DocumentPb.FieldValue.ContentType.HTML;
151 case ATOM:
152 return DocumentPb.FieldValue.ContentType.ATOM;
153 case DATE:
154 return DocumentPb.FieldValue.ContentType.DATE;
155 case NUMBER:
156 return DocumentPb.FieldValue.ContentType.NUMBER;
157 case GEO_POINT:
158 return DocumentPb.FieldValue.ContentType.GEO;
159 default:
160 throw new IllegalArgumentException("Unsupported field type " + type);
165 * Creates a {@link Schema} from a {@link SearchServicePb.IndexMetadata}.
167 * @param metadata the proto buffer containing supported field names
168 * and types.
169 * @return a {@link Schema} containing supported field names and field
170 * types for those names
172 static Schema createSchema(SearchServicePb.IndexMetadata metadata) {
173 if (metadata.getFieldCount() == 0) {
174 return null;
176 Map<String, List<Field.FieldType>> fieldMap = new HashMap<String, List<Field.FieldType>>();
177 Builder builder = newBuilder();
178 for (DocumentPb.FieldTypes fieldTypes : metadata.getFieldList()) {
179 String fieldName = fieldTypes.getName();
180 for (DocumentPb.FieldValue.ContentType type : fieldTypes.getTypeList()) {
181 builder.addTypedField(fieldName, mapPBFieldTypeToPublic(type));
184 return builder.build();
187 @Override
188 public int hashCode() {
189 return fieldMap.hashCode();
192 @Override
193 public boolean equals(Object obj) {
194 if (this == obj) {
195 return true;
197 if (obj == null) {
198 return false;
200 if (getClass() != obj.getClass()) {
201 return false;
203 return fieldMap.equals(((Schema) obj).fieldMap);
207 * Creates a schema builder.
209 * @return a new builder for creating a schema
211 public static Builder newBuilder() {
212 return new Builder();