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

« back to all changes in this revision

Viewing changes to solr/core/src/java/org/apache/solr/handler/XsltXMLLoader.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.util.xslt.TransformerProvider;
21
 
import org.apache.solr.request.SolrQueryRequest;
22
 
import org.apache.solr.response.SolrQueryResponse;
23
 
import org.apache.solr.common.SolrException;
24
 
import org.apache.solr.common.util.ContentStream;
25
 
import org.apache.solr.common.util.ContentStreamBase;
26
 
import org.apache.solr.common.util.XMLErrorLogger;
27
 
import org.apache.solr.core.SolrConfig;
28
 
import org.slf4j.Logger;
29
 
import org.slf4j.LoggerFactory;
30
 
import org.apache.commons.io.IOUtils;
31
 
 
32
 
import javax.xml.stream.XMLStreamReader;
33
 
import javax.xml.stream.XMLStreamException;
34
 
import javax.xml.stream.XMLInputFactory;
35
 
import javax.xml.transform.Transformer;
36
 
import javax.xml.transform.TransformerException;
37
 
import javax.xml.transform.dom.DOMSource;
38
 
import javax.xml.transform.dom.DOMResult;
39
 
import javax.xml.transform.sax.SAXSource;
40
 
import org.xml.sax.InputSource;
41
 
 
42
 
import java.io.InputStream;
43
 
import java.io.IOException;
44
 
import java.util.Map;
45
 
 
46
 
 
47
 
/**
48
 
 * Extends the XMLLoader by applying an XSLT transform before the
49
 
 * XMLLoader actually loads the XML
50
 
 *
51
 
 **/
52
 
class XsltXMLLoader extends XMLLoader {
53
 
 
54
 
  public static final String TRANSFORM_PARAM = "tr";
55
 
  public static final String CONTEXT_TRANSFORMER_KEY = "xsltupdater.transformer";
56
 
  
57
 
  private final Integer xsltCacheLifetimeSeconds; 
58
 
 
59
 
  public XsltXMLLoader(UpdateRequestProcessor processor, XMLInputFactory inputFactory, Integer xsltCacheLifetimeSeconds) {
60
 
    super(processor, inputFactory);
61
 
    this.xsltCacheLifetimeSeconds = xsltCacheLifetimeSeconds;
62
 
  }
63
 
 
64
 
  @Override
65
 
  public void load(SolrQueryRequest req, SolrQueryResponse rsp, ContentStream stream) throws Exception {
66
 
    final DOMResult result = new DOMResult();
67
 
    final Transformer t = getTransformer(req);
68
 
    InputStream is = null;
69
 
    XMLStreamReader parser = null;
70
 
    // first step: read XML and build DOM using Transformer (this is no overhead, as XSL always produces
71
 
    // an internal result DOM tree, we just access it directly as input for StAX):
72
 
    try {
73
 
      is = stream.getStream();
74
 
      final String charset = ContentStreamBase.getCharsetFromContentType(stream.getContentType());
75
 
      final InputSource isrc = new InputSource(is);
76
 
      isrc.setEncoding(charset);
77
 
      final SAXSource source = new SAXSource(isrc);
78
 
      t.transform(source, result);
79
 
    } catch(TransformerException te) {
80
 
      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, te.getMessage(), te);
81
 
    } finally {
82
 
      IOUtils.closeQuietly(is);
83
 
    }
84
 
    // second step feed the intermediate DOM tree into StAX parser:
85
 
    try {
86
 
      parser = inputFactory.createXMLStreamReader(new DOMSource(result.getNode()));
87
 
      this.processUpdate(processor, parser);
88
 
    } catch (XMLStreamException e) {
89
 
      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e.getMessage(), e);
90
 
    } finally {
91
 
      if (parser != null) parser.close();
92
 
    }
93
 
  }
94
 
 
95
 
 
96
 
  /** Get Transformer from request context, or from TransformerProvider.
97
 
   *  This allows either getContentType(...) or write(...) to instantiate the Transformer,
98
 
   *  depending on which one is called first, then the other one reuses the same Transformer
99
 
   */
100
 
  protected Transformer getTransformer(SolrQueryRequest request) throws IOException {
101
 
    final String xslt = request.getParams().get(TRANSFORM_PARAM,null);
102
 
    if(xslt==null) {
103
 
      throw new IOException("'" + TRANSFORM_PARAM + "' request parameter is required to use the XSLTResponseWriter");
104
 
    }
105
 
    // not the cleanest way to achieve this
106
 
    SolrConfig solrConfig = request.getCore().getSolrConfig();
107
 
    // no need to synchronize access to context, right? 
108
 
    // Nothing else happens with it at the same time
109
 
    final Map<Object,Object> ctx = request.getContext();
110
 
    Transformer result = (Transformer)ctx.get(CONTEXT_TRANSFORMER_KEY);
111
 
    if(result==null) {
112
 
      result = TransformerProvider.instance.getTransformer(solrConfig, xslt,xsltCacheLifetimeSeconds.intValue());
113
 
      result.setErrorListener(XsltUpdateRequestHandler.xmllog);
114
 
      ctx.put(CONTEXT_TRANSFORMER_KEY,result);
115
 
    }
116
 
    return result;
117
 
  }
118
 
 
119
 
}