~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to solr/core/src/java/org/apache/solr/handler/XMLLoader.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.solr.handler;
2
 
/**
3
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
4
 
 * contributor license agreements.  See the NOTICE file distributed with
5
 
 * this work for additional information regarding copyright ownership.
6
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
7
 
 * (the "License"); you may not use this file except in compliance with
8
 
 * the License.  You may obtain a copy of the License at
9
 
 *
10
 
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 
 *
12
 
 * Unless required by applicable law or agreed to in writing, software
13
 
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 
 * See the License for the specific language governing permissions and
16
 
 * limitations under the License.
17
 
 */
18
 
 
19
 
import org.apache.solr.update.processor.UpdateRequestProcessor;
20
 
import org.apache.solr.update.AddUpdateCommand;
21
 
import org.apache.solr.update.CommitUpdateCommand;
22
 
import org.apache.solr.update.RollbackUpdateCommand;
23
 
import org.apache.solr.update.DeleteUpdateCommand;
24
 
import org.apache.solr.request.SolrQueryRequest;
25
 
import org.apache.solr.response.SolrQueryResponse;
26
 
import org.apache.solr.common.util.ContentStream;
27
 
import org.apache.solr.common.util.ContentStreamBase;
28
 
import org.apache.solr.common.util.StrUtils;
29
 
import org.apache.solr.common.SolrException;
30
 
import org.apache.solr.common.SolrInputDocument;
31
 
import org.apache.solr.common.params.ModifiableSolrParams;
32
 
import org.apache.solr.common.params.SolrParams;
33
 
import org.apache.solr.common.params.UpdateParams;
34
 
import org.apache.commons.io.IOUtils;
35
 
 
36
 
import javax.xml.stream.XMLStreamReader;
37
 
import javax.xml.stream.XMLStreamException;
38
 
import javax.xml.stream.FactoryConfigurationError;
39
 
import javax.xml.stream.XMLStreamConstants;
40
 
import javax.xml.stream.XMLInputFactory;
41
 
import javax.xml.transform.TransformerConfigurationException;
42
 
import java.io.ByteArrayInputStream;
43
 
import java.io.InputStream;
44
 
import java.io.IOException;
45
 
 
46
 
 
47
 
/**
48
 
 *
49
 
 *
50
 
 **/
51
 
class XMLLoader extends ContentStreamLoader {
52
 
  protected UpdateRequestProcessor processor;
53
 
  protected XMLInputFactory inputFactory;
54
 
 
55
 
  public XMLLoader(UpdateRequestProcessor processor, XMLInputFactory inputFactory) {
56
 
    this.processor = processor;
57
 
    this.inputFactory = inputFactory;
58
 
  }
59
 
 
60
 
  @Override
61
 
  public void load(SolrQueryRequest req, SolrQueryResponse rsp, ContentStream stream) throws Exception {
62
 
    errHeader = "XMLLoader: " + stream.getSourceInfo();
63
 
    InputStream is = null;
64
 
    XMLStreamReader parser = null;
65
 
    try {
66
 
      is = stream.getStream();
67
 
      final String charset = ContentStreamBase.getCharsetFromContentType(stream.getContentType());
68
 
      if (XmlUpdateRequestHandler.log.isTraceEnabled()) {
69
 
        final byte[] body = IOUtils.toByteArray(is);
70
 
        // TODO: The charset may be wrong, as the real charset is later
71
 
        // determined by the XML parser, the content-type is only used as a hint!
72
 
        XmlUpdateRequestHandler.log.trace("body", new String(body, (charset == null) ?
73
 
          ContentStreamBase.DEFAULT_CHARSET : charset));
74
 
        IOUtils.closeQuietly(is);
75
 
        is = new ByteArrayInputStream(body);
76
 
      }
77
 
      parser = (charset == null) ?
78
 
        inputFactory.createXMLStreamReader(is) : inputFactory.createXMLStreamReader(is, charset);
79
 
        this.processUpdate(req, processor, parser);
80
 
    } catch (XMLStreamException e) {
81
 
      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e.getMessage(), e);
82
 
    } finally {
83
 
      if (parser != null) parser.close();
84
 
      IOUtils.closeQuietly(is);
85
 
    }
86
 
  }
87
 
 
88
 
  /* Support legacy Update signature */
89
 
  void processUpdate(UpdateRequestProcessor processor, XMLStreamReader parser) throws TransformerConfigurationException, XMLStreamException, IOException, FactoryConfigurationError, InstantiationException, IllegalAccessException {
90
 
    processUpdate(null, processor, parser);
91
 
  }
92
 
 
93
 
  /**
94
 
   * @since solr 1.2
95
 
   */
96
 
  void processUpdate(SolrQueryRequest req, UpdateRequestProcessor processor, XMLStreamReader parser)
97
 
          throws XMLStreamException, IOException, FactoryConfigurationError,
98
 
          InstantiationException, IllegalAccessException,
99
 
          TransformerConfigurationException {
100
 
    AddUpdateCommand addCmd = null;
101
 
    // Need to instansiate a SolrParams, even if req is null, for backward compat with legacyUpdate
102
 
    SolrParams params = (req != null) ? req.getParams() : new ModifiableSolrParams();
103
 
    while (true) {
104
 
      int event = parser.next();
105
 
      switch (event) {
106
 
        case XMLStreamConstants.END_DOCUMENT:
107
 
          parser.close();
108
 
          return;
109
 
 
110
 
        case XMLStreamConstants.START_ELEMENT:
111
 
          String currTag = parser.getLocalName();
112
 
          if (currTag.equals(XmlUpdateRequestHandler.ADD)) {
113
 
            XmlUpdateRequestHandler.log.trace("SolrCore.update(add)");
114
 
 
115
 
            addCmd = new AddUpdateCommand();
116
 
 
117
 
            // First look for commitWithin parameter on the request, will be overwritten for individual <add>'s
118
 
            addCmd.commitWithin = params.getInt(UpdateParams.COMMIT_WITHIN, -1);
119
 
            
120
 
            boolean overwrite = true;  // the default
121
 
 
122
 
            Boolean overwritePending = null;
123
 
            Boolean overwriteCommitted = null;
124
 
            for (int i = 0; i < parser.getAttributeCount(); i++) {
125
 
              String attrName = parser.getAttributeLocalName(i);
126
 
              String attrVal = parser.getAttributeValue(i);
127
 
              if (XmlUpdateRequestHandler.OVERWRITE.equals(attrName)) {
128
 
                overwrite = StrUtils.parseBoolean(attrVal);
129
 
              } else if (XmlUpdateRequestHandler.ALLOW_DUPS.equals(attrName)) {
130
 
                overwrite = !StrUtils.parseBoolean(attrVal);
131
 
              } else if (XmlUpdateRequestHandler.COMMIT_WITHIN.equals(attrName)) {
132
 
                addCmd.commitWithin = Integer.parseInt(attrVal);
133
 
              } else if (XmlUpdateRequestHandler.OVERWRITE_PENDING.equals(attrName)) {
134
 
                overwritePending = StrUtils.parseBoolean(attrVal);
135
 
              } else if (XmlUpdateRequestHandler.OVERWRITE_COMMITTED.equals(attrName)) {
136
 
                overwriteCommitted = StrUtils.parseBoolean(attrVal);
137
 
              } else {
138
 
                XmlUpdateRequestHandler.log.warn("Unknown attribute id in add:" + attrName);
139
 
              }
140
 
            }
141
 
 
142
 
            // check if these flags are set
143
 
            if (overwritePending != null && overwriteCommitted != null) {
144
 
              if (overwritePending != overwriteCommitted) {
145
 
                throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
146
 
                        "can't have different values for 'overwritePending' and 'overwriteCommitted'");
147
 
              }
148
 
              overwrite = overwritePending;
149
 
            }
150
 
            addCmd.overwriteCommitted = overwrite;
151
 
            addCmd.overwritePending = overwrite;
152
 
            addCmd.allowDups = !overwrite;
153
 
          } else if ("doc".equals(currTag)) {
154
 
//            if(addCmd != null) {
155
 
              XmlUpdateRequestHandler.log.trace("adding doc...");
156
 
              addCmd.clear();
157
 
              addCmd.solrDoc = readDoc(parser);
158
 
              processor.processAdd(addCmd);
159
 
//            } else {
160
 
//              throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unexpected <doc> tag without an <add> tag surrounding it.");
161
 
//            }
162
 
          } else if (XmlUpdateRequestHandler.COMMIT.equals(currTag) || XmlUpdateRequestHandler.OPTIMIZE.equals(currTag)) {
163
 
            XmlUpdateRequestHandler.log.trace("parsing " + currTag);
164
 
 
165
 
            CommitUpdateCommand cmd = new CommitUpdateCommand(XmlUpdateRequestHandler.OPTIMIZE.equals(currTag));
166
 
 
167
 
            boolean sawWaitSearcher = false, sawWaitFlush = false;
168
 
            for (int i = 0; i < parser.getAttributeCount(); i++) {
169
 
              String attrName = parser.getAttributeLocalName(i);
170
 
              String attrVal = parser.getAttributeValue(i);
171
 
              if (XmlUpdateRequestHandler.WAIT_FLUSH.equals(attrName)) {
172
 
                cmd.waitFlush = StrUtils.parseBoolean(attrVal);
173
 
                sawWaitFlush = true;
174
 
              } else if (XmlUpdateRequestHandler.WAIT_SEARCHER.equals(attrName)) {
175
 
                cmd.waitSearcher = StrUtils.parseBoolean(attrVal);
176
 
                sawWaitSearcher = true;
177
 
              } else if (UpdateParams.MAX_OPTIMIZE_SEGMENTS.equals(attrName)) {
178
 
                cmd.maxOptimizeSegments = Integer.parseInt(attrVal);
179
 
              } else if (UpdateParams.EXPUNGE_DELETES.equals(attrName)) {
180
 
                cmd.expungeDeletes = StrUtils.parseBoolean(attrVal);
181
 
              } else {
182
 
                XmlUpdateRequestHandler.log.warn("unexpected attribute commit/@" + attrName);
183
 
              }
184
 
            }
185
 
 
186
 
            // If waitFlush is specified and waitSearcher wasn't, then
187
 
            // clear waitSearcher.
188
 
            if (sawWaitFlush && !sawWaitSearcher) {
189
 
              cmd.waitSearcher = false;
190
 
            }
191
 
            processor.processCommit(cmd);
192
 
          } // end commit
193
 
          else if (XmlUpdateRequestHandler.ROLLBACK.equals(currTag)) {
194
 
            XmlUpdateRequestHandler.log.trace("parsing " + currTag);
195
 
 
196
 
            RollbackUpdateCommand cmd = new RollbackUpdateCommand();
197
 
 
198
 
            processor.processRollback(cmd);
199
 
          } // end rollback
200
 
          else if (XmlUpdateRequestHandler.DELETE.equals(currTag)) {
201
 
            XmlUpdateRequestHandler.log.trace("parsing delete");
202
 
            processDelete(processor, parser);
203
 
          } // end delete
204
 
          break;
205
 
      }
206
 
    }
207
 
  }
208
 
 
209
 
  /**
210
 
   * @since solr 1.3
211
 
   */
212
 
  void processDelete(UpdateRequestProcessor processor, XMLStreamReader parser) throws XMLStreamException, IOException {
213
 
    // Parse the command
214
 
    DeleteUpdateCommand deleteCmd = new DeleteUpdateCommand();
215
 
    deleteCmd.fromPending = true;
216
 
    deleteCmd.fromCommitted = true;
217
 
    for (int i = 0; i < parser.getAttributeCount(); i++) {
218
 
      String attrName = parser.getAttributeLocalName(i);
219
 
      String attrVal = parser.getAttributeValue(i);
220
 
      if ("fromPending".equals(attrName)) {
221
 
        deleteCmd.fromPending = StrUtils.parseBoolean(attrVal);
222
 
      } else if ("fromCommitted".equals(attrName)) {
223
 
        deleteCmd.fromCommitted = StrUtils.parseBoolean(attrVal);
224
 
      } else {
225
 
        XmlUpdateRequestHandler.log.warn("unexpected attribute delete/@" + attrName);
226
 
      }
227
 
    }
228
 
 
229
 
    StringBuilder text = new StringBuilder();
230
 
    while (true) {
231
 
      int event = parser.next();
232
 
      switch (event) {
233
 
        case XMLStreamConstants.START_ELEMENT:
234
 
          String mode = parser.getLocalName();
235
 
          if (!("id".equals(mode) || "query".equals(mode))) {
236
 
            XmlUpdateRequestHandler.log.warn("unexpected XML tag /delete/" + mode);
237
 
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
238
 
                    "unexpected XML tag /delete/" + mode);
239
 
          }
240
 
          text.setLength(0);
241
 
          break;
242
 
 
243
 
        case XMLStreamConstants.END_ELEMENT:
244
 
          String currTag = parser.getLocalName();
245
 
          if ("id".equals(currTag)) {
246
 
            deleteCmd.id = text.toString();
247
 
          } else if ("query".equals(currTag)) {
248
 
            deleteCmd.query = text.toString();
249
 
          } else if ("delete".equals(currTag)) {
250
 
            return;
251
 
          } else {
252
 
            XmlUpdateRequestHandler.log.warn("unexpected XML tag /delete/" + currTag);
253
 
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
254
 
                    "unexpected XML tag /delete/" + currTag);
255
 
          }
256
 
          processor.processDelete(deleteCmd);
257
 
          deleteCmd.id = null;
258
 
          deleteCmd.query = null;
259
 
          break;
260
 
 
261
 
          // Add everything to the text
262
 
        case XMLStreamConstants.SPACE:
263
 
        case XMLStreamConstants.CDATA:
264
 
        case XMLStreamConstants.CHARACTERS:
265
 
          text.append(parser.getText());
266
 
          break;
267
 
      }
268
 
    }
269
 
  }
270
 
 
271
 
 
272
 
  /**
273
 
   * Given the input stream, read a document
274
 
   *
275
 
   * @since solr 1.3
276
 
   */
277
 
  SolrInputDocument readDoc(XMLStreamReader parser) throws XMLStreamException {
278
 
    SolrInputDocument doc = new SolrInputDocument();
279
 
 
280
 
    String attrName = "";
281
 
    for (int i = 0; i < parser.getAttributeCount(); i++) {
282
 
      attrName = parser.getAttributeLocalName(i);
283
 
      if ("boost".equals(attrName)) {
284
 
        doc.setDocumentBoost(Float.parseFloat(parser.getAttributeValue(i)));
285
 
      } else {
286
 
        XmlUpdateRequestHandler.log.warn("Unknown attribute doc/@" + attrName);
287
 
      }
288
 
    }
289
 
 
290
 
    StringBuilder text = new StringBuilder();
291
 
    String name = null;
292
 
    float boost = 1.0f;
293
 
    boolean isNull = false;
294
 
    while (true) {
295
 
      int event = parser.next();
296
 
      switch (event) {
297
 
        // Add everything to the text
298
 
        case XMLStreamConstants.SPACE:
299
 
        case XMLStreamConstants.CDATA:
300
 
        case XMLStreamConstants.CHARACTERS:
301
 
          text.append(parser.getText());
302
 
          break;
303
 
 
304
 
        case XMLStreamConstants.END_ELEMENT:
305
 
          if ("doc".equals(parser.getLocalName())) {
306
 
            return doc;
307
 
          } else if ("field".equals(parser.getLocalName())) {
308
 
            if (!isNull) {
309
 
              doc.addField(name, text.toString(), boost);
310
 
              boost = 1.0f;
311
 
            }
312
 
          }
313
 
          break;
314
 
 
315
 
        case XMLStreamConstants.START_ELEMENT:
316
 
          text.setLength(0);
317
 
          String localName = parser.getLocalName();
318
 
          if (!"field".equals(localName)) {
319
 
            XmlUpdateRequestHandler.log.warn("unexpected XML tag doc/" + localName);
320
 
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
321
 
                    "unexpected XML tag doc/" + localName);
322
 
          }
323
 
          boost = 1.0f;
324
 
          String attrVal = "";
325
 
          for (int i = 0; i < parser.getAttributeCount(); i++) {
326
 
            attrName = parser.getAttributeLocalName(i);
327
 
            attrVal = parser.getAttributeValue(i);
328
 
            if ("name".equals(attrName)) {
329
 
              name = attrVal;
330
 
            } else if ("boost".equals(attrName)) {
331
 
              boost = Float.parseFloat(attrVal);
332
 
            } else if ("null".equals(attrName)) {
333
 
              isNull = StrUtils.parseBoolean(attrVal);
334
 
            } else {
335
 
              XmlUpdateRequestHandler.log.warn("Unknown attribute doc/field/@" + attrName);
336
 
            }
337
 
          }
338
 
          break;
339
 
      }
340
 
    }
341
 
  }
342
 
 
343
 
 
344
 
}