Project

General

Profile

1
/**
2
 *  Copyright: 2013 Regents of the University of California and the
3
 *             National Center for Ecological Analysis and Synthesis
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19
package edu.ucsb.nceas.metacat.common.query;
20

    
21
import java.io.IOException;
22
import java.io.InputStream;
23
import java.io.StringWriter;
24
import java.util.ArrayList;
25
import java.util.List;
26
import java.util.Map;
27
import java.util.Set;
28

    
29
import javax.xml.parsers.ParserConfigurationException;
30

    
31
import org.apache.solr.client.solrj.SolrServerException;
32
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
33
import org.apache.solr.client.solrj.response.QueryResponse;
34
import org.apache.solr.common.SolrDocumentList;
35
import org.apache.solr.common.params.SolrParams;
36
import org.apache.solr.common.util.XML;
37
import org.apache.solr.core.CoreContainer;
38
import org.apache.solr.core.SolrCore;
39
import org.apache.solr.schema.IndexSchema;
40
import org.apache.solr.schema.SchemaField;
41
import org.apache.solr.servlet.SolrRequestParsers;
42
import org.dataone.service.exceptions.NotFound;
43
import org.dataone.service.exceptions.NotImplemented;
44
import org.dataone.service.exceptions.UnsupportedType;
45
import org.dataone.service.types.v1.Identifier;
46
import org.dataone.service.types.v1.Subject;
47
import org.xml.sax.SAXException;
48

    
49
import edu.ucsb.nceas.metacat.common.query.SolrQueryResponseTransformer;
50

    
51

    
52
/**
53
 *The query service of the embedded solr server.
54
 * @author tao
55
 *
56
 */
57
public class EmbeddedSolrQueryService extends SolrQueryService {
58
    private EmbeddedSolrServer solrServer = null;
59
    private CoreContainer coreContainer = null;
60
    private String collectionName = null;
61
    private SolrCore solrCore = null;
62
    
63
  
64
    /**
65
     * Constructor.
66
     * @param solrServer
67
     * @param solrCore
68
     * @throws NotFound 
69
     */
70
    public EmbeddedSolrQueryService(EmbeddedSolrServer solrServer, CoreContainer coreContainer, String collectionName) throws NotFound {
71
        if(solrServer == null) {
72
            throw new NullPointerException("EmbeddedSolrQueryService.constructor - the EmbeddedSolrServer parameter can't be null.");
73
        }
74
        if(coreContainer == null) {
75
            throw new NullPointerException("EmbeddedSolrQueryService.constructor - the CoreContainer parameter can't be null.");
76
        }
77
        if(collectionName == null || collectionName.trim().equals("")) {
78
            throw new NullPointerException("EmbeddedSolrQueryService.constructor - the name of Collection parameter can't be null or empty.");
79
        }
80
        this.solrServer = solrServer;
81
        this.coreContainer = coreContainer;
82
        this.collectionName = collectionName;
83
        this.solrCore = this.coreContainer.getCore(collectionName);
84
        if(solrCore == null) {
85
            throw new NotFound("0000","EmbeddedSolrQueryService.constructor - There is no SolrCore named "+collectionName+".");
86
        }
87
        schema = solrCore.getSchema();
88
        fieldMap = schema.getFields();
89
    }
90
    /**
91
     * Query the Solr server with specified query and user's identity. If the Subjects
92
     * is null, there will be no access rules for the query. This is the for the http solr server.
93
     * @param query the query string
94
     * @param subjects the user's identity which sent the query
95
     * @return the response
96
     * @throws Exception
97
     */
98
    /*public InputStream query(String query, Set<Subject>subjects) throws Exception {
99
        throw new NotImplemented("0000", "EmbeddSolrQueryService - the method of  query(String query, Set<Subject>subjects) is not for the EmbeddedSolrServer. We donot need to implemente it");
100
    }*/
101
    
102
    /**
103
     * Query the Solr server with specified query and user's identity. If the Subjects
104
     * is null, there will be no access rules for the query. This is for the embedded solr server.
105
     * @param query the query params. 
106
     * @param subjects the user's identity which sent the query
107
     * @return the response
108
     * @throws SAXException 
109
     * @throws IOException 
110
     * @throws ParserConfigurationException 
111
     * @throws SolrServerException 
112
     * @throws UnsupportedType 
113
     * @throws Exception
114
     */
115
    public  InputStream query(SolrParams query, Set<Subject>subjects) throws ParserConfigurationException, IOException, SAXException, SolrServerException, UnsupportedType {
116
        InputStream inputStream = null;
117
        String wt = query.get(WT);
118
        query = appendAccessFilterParams(query, subjects);
119
        SolrQueryResponseTransformer solrTransformer = new SolrQueryResponseTransformer(solrCore);
120
        // handle normal and skin-based queries
121
        if (isSupportedWT(wt)) {
122
            // just handle as normal solr query
123
            //reload the core before query. Only after reloading the core, the query result can reflect the change made in metacat-index module.
124
            coreContainer.reload(collectionName);
125
            QueryResponse response = solrServer.query(query);
126
            inputStream = solrTransformer.transformResults(query, response, wt);
127
        } else {
128
            throw new UnsupportedType("0000","EmbeddSolrQueryService.query - the wt type "+wt+" in the solr query is not supported");
129
        }
130
        return inputStream;
131
    }
132
    
133
    
134
    
135
    
136
    /**
137
     * Get the fields map of the index schema
138
     * @return the fields map (the field name is the key and the SchemaField is the value).
139
     */
140
    public  Map<String, SchemaField> getIndexSchemaFields() {
141
        return fieldMap;
142
    }
143
    
144
    /**
145
     * Get the list of the valid field name (moved the fields names of the CopyFieldTarget).
146
     * @return
147
     */
148
    public List<String> getValidSchemaField() {
149
        return super.getValidSchemaFields();
150
    }
151
    
152
    /**
153
     * Get the version of the solr server.
154
     * @return
155
     */
156
    public String getSolrServerVersion() {
157
        if( solrSpecVersion !=null ) {
158
            return solrSpecVersion;
159
        } else {
160
            Package p = SolrCore.class.getPackage();
161
            StringWriter tmp = new StringWriter();
162
            solrSpecVersion = p.getSpecificationVersion();
163
            if (null != solrSpecVersion) {
164
                try {
165
                    XML.escapeCharData(solrSpecVersion, tmp);
166
                    solrSpecVersion = tmp.toString();
167
                } catch (IOException e) {
168
                    e.printStackTrace();
169
                }
170
            }
171
            if (solrSpecVersion == null || solrSpecVersion.trim().equals("")) {
172
                solrSpecVersion = UNKNOWN;
173
            } 
174
            return solrSpecVersion;
175
        }
176
    }
177
    
178
    /**
179
     * If there is a solr doc for the given id.
180
     * @param id - the specified id.
181
     * @return true if there is a solr doc for this id.
182
     */
183
    public boolean hasSolrDoc(Identifier id) throws ParserConfigurationException, SolrServerException, IOException, SAXException{
184
    	boolean hasIt = false;
185
    	if(id != null && id.getValue() != null && !id.getValue().trim().equals("") ) {
186
    		SolrParams query = buildIdQuery(id.getValue());
187
    		coreContainer.reload(collectionName);
188
            QueryResponse response = solrServer.query(query);
189
            hasIt = hasResult(response);
190
    	}
191
    	return hasIt;
192
    }
193
    
194
    /**
195
     * Build a query for decide if the solr server has the id.
196
     * @param id
197
     * @return the query
198
     */
199
    public static SolrParams buildIdQuery(String id) {
200
    	    String query = "select?q=id:"+id;
201
    		query = query.replaceAll("\\+", "%2B");
202
            SolrParams solrParams = SolrRequestParsers.parseQueryString(query);
203
            return solrParams;
204
    }
205
    
206
    /**
207
     * Determine if the response has any solr documents.
208
     * @param response
209
     * @return true if it has at least one solr document;
210
     */
211
    public static boolean hasResult(QueryResponse response) {
212
    	boolean hasResult = false;
213
    	if(response != null) {
214
    		SolrDocumentList list = response.getResults();
215
    		if(list != null && list.getNumFound() >0) {
216
    			hasResult = true;
217
    		}
218
    	}
219
    	return hasResult;
220
    }
221
}
(1-1/7)