1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.solr.update;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23
24 import org.apache.lucene.document.Document;
25 import org.apache.lucene.document.Field;
26 import org.apache.solr.core.SolrException;
27 import org.apache.solr.schema.IndexSchema;
28 import org.apache.solr.schema.SchemaField;
29
30 /**
31 * @author yonik
32 * @version $Id: DocumentBuilder.java 542679 2007-05-29 22:28:21Z ryan $
33 */
34
35
36 // Not thread safe - by design. Create a new builder for each thread.
37 public class DocumentBuilder {
38 private final IndexSchema schema;
39 private Document doc;
40 private HashMap<String,String> map = new HashMap<String,String>();
41
42 public DocumentBuilder(IndexSchema schema) {
43 this.schema = schema;
44 }
45
46 public void startDoc() {
47 doc = new Document();
48 map.clear();
49 }
50
51 protected void addSingleField(SchemaField sfield, String val, float boost) {
52 //System.out.println("###################ADDING FIELD "+sfield+"="+val);
53
54 // we don't check for a null val ourselves because a solr.FieldType
55 // might actually want to map it to something. If createField()
56 // returns null, then we don't store the field.
57 Field field = sfield.createField(val, boost);
58 if (field != null) {
59 if (!sfield.multiValued()) {
60 String oldValue = map.put(sfield.getName(), val);
61 if (oldValue != null) {
62 throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,"ERROR: multiple values encountered for non multiValued field " + sfield.getName()
63 + ": first='" + oldValue + "' second='" + val + "'");
64 }
65 }
66 // field.setBoost(boost);
67 doc.add(field);
68 }
69 }
70
71
72 public void addField(SchemaField sfield, String val, float boost) {
73 addSingleField(sfield,val,boost);
74 }
75
76 public void addField(String name, String val) {
77 addField(name, val, 1.0f);
78 }
79
80 public void addField(String name, String val, float boost) {
81 SchemaField sfield = schema.getFieldOrNull(name);
82 if (sfield != null) {
83 addField(sfield,val,boost);
84 }
85
86 // Check if we should copy this field to any other fields.
87 // This could happen whether it is explicit or not.
88 SchemaField[] destArr = schema.getCopyFields(name);
89 if (destArr != null) {
90 for (SchemaField destField : destArr) {
91 addSingleField(destField,val,boost);
92 }
93 }
94
95 // error if this field name doesn't match anything
96 if (sfield==null && (destArr==null || destArr.length==0)) {
97 throw new SolrException( SolrException.ErrorCode.BAD_REQUEST,"ERROR:unknown field '" + name + "'");
98 }
99 }
100
101 public void setBoost(float boost) {
102 doc.setBoost(boost);
103 }
104
105 public void endDoc() {
106 }
107
108 // specific to this type of document builder
109 public Document getDoc() throws IllegalArgumentException {
110
111 // Check for all required fields -- Note, all fields with a
112 // default value are defacto 'required' fields.
113 List<String> missingFields = new ArrayList<String>( schema.getRequiredFields().size() );
114 for (SchemaField field : schema.getRequiredFields()) {
115 if (doc.getField(field.getName() ) == null) {
116 if (field.getDefaultValue() != null) {
117 doc.add( field.createField( field.getDefaultValue(), 1.0f ) );
118 } else {
119 missingFields.add(field.getName());
120 }
121 }
122 }
123
124 if (missingFields.size() > 0) {
125 StringBuilder builder = new StringBuilder();
126 // add the uniqueKey if possible
127 if( schema.getUniqueKeyField() != null ) {
128 String n = schema.getUniqueKeyField().getName();
129 String v = doc.get( n );
130 builder.append( "Document ["+n+"="+v+"] " );
131 }
132 builder.append("missing required fields: " );
133 for (String field : missingFields) {
134 builder.append(field);
135 builder.append(" ");
136 }
137 throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, builder.toString());
138 }
139
140 Document ret = doc; doc=null;
141 return ret;
142 }
143 }