Project

General

Profile

1 7542 tao
/**
2 8138 tao
 *  Copyright: 2013 Regents of the University of California and the
3 7542 tao
 *             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.index;
20
21 7555 tao
import java.io.ByteArrayInputStream;
22 8343 tao
import java.io.FileInputStream;
23 7786 tao
import java.io.FileNotFoundException;
24 7546 tao
import java.io.IOException;
25
import java.io.InputStream;
26 8893 tao
import java.net.MalformedURLException;
27 7546 tao
import java.util.ArrayList;
28 7800 tao
import java.util.Calendar;
29 8893 tao
import java.util.Collection;
30 8464 leinfelder
import java.util.Date;
31 7546 tao
import java.util.HashMap;
32
import java.util.Iterator;
33 7542 tao
import java.util.List;
34 7546 tao
import java.util.Map;
35
import java.util.Set;
36 7542 tao
37
import javax.xml.parsers.DocumentBuilder;
38
import javax.xml.parsers.DocumentBuilderFactory;
39 7546 tao
import javax.xml.parsers.ParserConfigurationException;
40 7542 tao
import javax.xml.xpath.XPath;
41 7546 tao
import javax.xml.xpath.XPathExpressionException;
42 7542 tao
import javax.xml.xpath.XPathFactory;
43
44 7546 tao
import org.apache.commons.codec.EncoderException;
45 8893 tao
import org.apache.commons.collections.CollectionUtils;
46 7546 tao
import org.apache.commons.io.output.ByteArrayOutputStream;
47 7786 tao
import org.apache.commons.lang.StringUtils;
48 7546 tao
import org.apache.commons.logging.Log;
49
import org.apache.commons.logging.LogFactory;
50 7604 tao
import org.apache.solr.client.solrj.SolrQuery;
51 7542 tao
import org.apache.solr.client.solrj.SolrServer;
52 7546 tao
import org.apache.solr.client.solrj.SolrServerException;
53 7604 tao
import org.apache.solr.client.solrj.response.QueryResponse;
54 7547 tao
import org.apache.solr.client.solrj.response.UpdateResponse;
55 7604 tao
import org.apache.solr.common.SolrDocument;
56
import org.apache.solr.common.SolrDocumentList;
57 7546 tao
import org.apache.solr.common.SolrInputDocument;
58 8464 leinfelder
import org.apache.solr.schema.IndexSchema;
59 7542 tao
import org.dataone.cn.indexer.XMLNamespaceConfig;
60 8464 leinfelder
import org.dataone.cn.indexer.convert.SolrDateConverter;
61 9028 leinfelder
import org.dataone.cn.indexer.parser.BaseXPathDocumentSubprocessor;
62 9060 leinfelder
import org.dataone.cn.indexer.parser.IDocumentDeleteSubprocessor;
63 7542 tao
import org.dataone.cn.indexer.parser.IDocumentSubprocessor;
64 7546 tao
import org.dataone.cn.indexer.parser.SolrField;
65
import org.dataone.cn.indexer.solrhttp.SolrDoc;
66
import org.dataone.cn.indexer.solrhttp.SolrElementField;
67 7733 tao
import org.dataone.service.exceptions.NotFound;
68
import org.dataone.service.exceptions.NotImplemented;
69 7786 tao
import org.dataone.service.exceptions.ServiceFailure;
70 7733 tao
import org.dataone.service.exceptions.UnsupportedType;
71 7815 leinfelder
import org.dataone.service.types.v1.Event;
72 7577 tao
import org.dataone.service.types.v1.Identifier;
73 8826 leinfelder
import org.dataone.service.types.v2.SystemMetadata;
74 8464 leinfelder
import org.dataone.service.util.DateTimeMarshaller;
75 7555 tao
import org.dataone.service.util.TypeMarshaller;
76 8023 tao
import org.dspace.foresite.OREParserException;
77 7555 tao
import org.jibx.runtime.JiBXException;
78 7546 tao
import org.w3c.dom.Document;
79
import org.xml.sax.SAXException;
80 7542 tao
81 7828 leinfelder
import edu.ucsb.nceas.metacat.common.index.event.IndexEvent;
82 8464 leinfelder
import edu.ucsb.nceas.metacat.common.query.SolrQueryServiceController;
83 7800 tao
import edu.ucsb.nceas.metacat.index.event.EventlogFactory;
84 7711 tao
import edu.ucsb.nceas.metacat.index.resourcemap.ResourceMapSubprocessor;
85
86 7542 tao
/**
87
 * A class does insert, update and remove indexes to a SOLR server
88
 * @author tao
89
 *
90
 */
91
public class SolrIndex {
92 7591 leinfelder
93 7604 tao
    public static final String ID = "id";
94
    private static final String IDQUERY = ID+":*";
95 7542 tao
    private List<IDocumentSubprocessor> subprocessors = null;
96 9060 leinfelder
    private List<IDocumentDeleteSubprocessor> deleteSubprocessors = null;
97
98 7542 tao
    private SolrServer solrServer = null;
99
    private XMLNamespaceConfig xmlNamespaceConfig = null;
100 7546 tao
    private List<SolrField> sysmetaSolrFields = null;
101 7542 tao
102
    private static DocumentBuilderFactory documentBuilderFactory = null;
103
    private static DocumentBuilder builder = null;
104
105
    private static XPathFactory xpathFactory = null;
106
    private static XPath xpath = null;
107 7546 tao
    Log log = LogFactory.getLog(SolrIndex.class);
108 7542 tao
109 7546 tao
    static {
110
        documentBuilderFactory = DocumentBuilderFactory.newInstance();
111
        documentBuilderFactory.setNamespaceAware(true);
112
        try {
113
            builder = documentBuilderFactory.newDocumentBuilder();
114
        } catch (ParserConfigurationException e) {
115
            e.printStackTrace();
116
        }
117
        xpathFactory = XPathFactory.newInstance();
118
        xpath = xpathFactory.newXPath();
119
    }
120
121 7542 tao
    /**
122
     * Constructor
123 7548 tao
     * @throws SAXException
124
     * @throws IOException
125 7542 tao
     */
126 8161 tao
    public SolrIndex(XMLNamespaceConfig xmlNamespaceConfig, List<SolrField> sysmetaSolrFields)
127 7548 tao
                    throws XPathExpressionException, ParserConfigurationException, IOException, SAXException {
128
         this.xmlNamespaceConfig = xmlNamespaceConfig;
129
         this.sysmetaSolrFields = sysmetaSolrFields;
130
         init();
131 8125 tao
    }
132 7542 tao
133 7546 tao
    private void init() throws ParserConfigurationException, XPathExpressionException {
134
        xpath.setNamespaceContext(xmlNamespaceConfig);
135
        initExpressions();
136
    }
137
138
    private void initExpressions() throws XPathExpressionException {
139
        for (SolrField field : sysmetaSolrFields) {
140
            field.initExpression(xpath);
141
        }
142
143
    }
144 7542 tao
145 7546 tao
146 7542 tao
    /**
147
     * Get the list of the Subprocessors in this index.
148
     * @return the list of the Subprocessors.
149
     */
150
    public List<IDocumentSubprocessor> getSubprocessors() {
151
        return subprocessors;
152
    }
153
154
    /**
155
     * Set the list of Subprocessors.
156
     * @param subprocessorList  the list will be set.
157
     */
158
    public void setSubprocessors(List<IDocumentSubprocessor> subprocessorList) {
159 7546 tao
        for (IDocumentSubprocessor subprocessor : subprocessorList) {
160 9028 leinfelder
        	if (subprocessor instanceof BaseXPathDocumentSubprocessor) {
161
        		((BaseXPathDocumentSubprocessor)subprocessor).initExpression(xpath);
162 9018 leinfelder
        	}
163 7546 tao
        }
164 7542 tao
        this.subprocessors = subprocessorList;
165
    }
166 7546 tao
167 9060 leinfelder
    public List<IDocumentDeleteSubprocessor> getDeleteSubprocessors() {
168
		return deleteSubprocessors;
169
	}
170
171
	public void setDeleteSubprocessors(
172
			List<IDocumentDeleteSubprocessor> deleteSubprocessors) {
173
		this.deleteSubprocessors = deleteSubprocessors;
174
	}
175
176
	/**
177 7546 tao
     * Generate the index for the given information
178
     * @param id
179 7555 tao
     * @param systemMetadata
180 7546 tao
     * @param dataStream
181
     * @return
182
     * @throws IOException
183
     * @throws SAXException
184
     * @throws ParserConfigurationException
185
     * @throws XPathExpressionException
186 7555 tao
     * @throws JiBXException
187 7711 tao
     * @throws SolrServerException
188 7546 tao
     * @throws EncoderException
189 7733 tao
     * @throws UnsupportedType
190
     * @throws NotFound
191
     * @throws NotImplemented
192 7546 tao
     */
193 8766 leinfelder
    private Map<String, SolrDoc> process(String id, SystemMetadata systemMetadata, String objectPath)
194 7546 tao
                    throws IOException, SAXException, ParserConfigurationException,
195 7733 tao
                    XPathExpressionException, JiBXException, EncoderException, SolrServerException, NotImplemented, NotFound, UnsupportedType{
196 7546 tao
197
        // Load the System Metadata document
198 7555 tao
        ByteArrayOutputStream systemMetadataOutputStream = new ByteArrayOutputStream();
199
        TypeMarshaller.marshalTypeToOutputStream(systemMetadata, systemMetadataOutputStream);
200
        ByteArrayInputStream systemMetadataStream = new ByteArrayInputStream(systemMetadataOutputStream.toByteArray());
201
        Document sysMetaDoc = generateXmlDocument(systemMetadataStream);
202 7546 tao
        if (sysMetaDoc == null) {
203
            log.error("Could not load System metadata for ID: " + id);
204
            return null;
205
        }
206
207
        // Extract the field values from the System Metadata
208
        List<SolrElementField> sysSolrFields = processSysmetaFields(sysMetaDoc, id);
209
        SolrDoc indexDocument = new SolrDoc(sysSolrFields);
210
        Map<String, SolrDoc> docs = new HashMap<String, SolrDoc>();
211
        docs.put(id, indexDocument);
212 9018 leinfelder
213
        // get the format id for this object
214
        String formatId = indexDocument.getFirstFieldValue(SolrElementField.FIELD_OBJECTFORMAT);
215 7546 tao
216
        // Determine if subprocessors are available for this ID
217
        if (subprocessors != null) {
218 9018 leinfelder
	        // for each subprocessor loaded from the spring config
219
	        for (IDocumentSubprocessor subprocessor : subprocessors) {
220
	            // Does this subprocessor apply?
221
	            if (subprocessor.canProcess(formatId)) {
222
	                // if so, then extract the additional information from the
223
	                // document.
224
	                try {
225
	                    // docObject = the resource map document or science
226
	                    // metadata document.
227
	                    // note that resource map processing touches all objects
228
	                    // referenced by the resource map.
229
	                	FileInputStream dataStream = new FileInputStream(objectPath);
230
	                    if (!dataStream.getFD().valid()) {
231
	                    	log.error("Could not load OBJECT file for ID,Path=" + id + ", "
232
                                    + objectPath);
233
	                        //throw new Exception("Could not load OBJECT for ID " + id );
234
	                    } else {
235
	                        docs = subprocessor.processDocument(id, docs, dataStream);
236
	                    }
237
	                } catch (Exception e) {
238 9368 tao
	                    e.printStackTrace();
239 9018 leinfelder
	                    log.error(e.getMessage(), e);
240
	                    throw new SolrServerException(e.getMessage());
241
	                }
242
	            }
243
	        }
244 7546 tao
       }
245
246
       // TODO: in the XPathDocumentParser class in d1_cn_index_process module,
247
       // merge is only for resource map. We need more work here.
248
       for (SolrDoc mergeDoc : docs.values()) {
249
           if (!mergeDoc.isMerged()) {
250 7711 tao
                 mergeWithIndexedDocument(mergeDoc);
251 7546 tao
           }
252
       }
253
254
       //SolrElementAdd addCommand = getAddCommand(new ArrayList<SolrDoc>(docs.values()));
255
256
       return docs;
257
    }
258
259 7711 tao
    /**
260
     * Merge updates with existing solr documents
261
     *
262
     * This method appears to re-set the data package field data into the
263
     * document about to be updated in the solr index. Since packaging
264
     * information is derived from the package document (resource map), this
265
     * information is not present when processing a document contained in a data
266
     * package. This method replaces those values from the existing solr index
267
     * record for the document being processed. -- sroseboo, 1-18-12
268
     *
269
     * @param indexDocument
270
     * @return
271
     * @throws IOException
272
     * @throws EncoderException
273
     * @throws XPathExpressionException
274
     * @throws SAXException
275
     * @throws ParserConfigurationException
276
     * @throws SolrServerException
277 7733 tao
     * @throws UnsupportedType
278
     * @throws NotFound
279
     * @throws NotImplemented
280 7711 tao
     */
281
    // TODO:combine merge function with resourcemap merge function
282
283
    private SolrDoc mergeWithIndexedDocument(SolrDoc indexDocument) throws IOException,
284 7733 tao
            EncoderException, XPathExpressionException, SolrServerException, ParserConfigurationException, SAXException, NotImplemented, NotFound, UnsupportedType {
285 7711 tao
        List<String> ids = new ArrayList<String>();
286
        ids.add(indexDocument.getIdentifier());
287
        List<SolrDoc> indexedDocuments = ResourceMapSubprocessor.getSolrDocs(ids);
288
        SolrDoc indexedDocument = indexedDocuments == null || indexedDocuments.size() <= 0 ? null
289
                : indexedDocuments.get(0);
290 8464 leinfelder
291
        IndexSchema indexSchema = SolrQueryServiceController.getInstance().getSchema();
292
293 7711 tao
        if (indexedDocument == null || indexedDocument.getFieldList().size() <= 0) {
294
            return indexDocument;
295
        } else {
296
            for (SolrElementField field : indexedDocument.getFieldList()) {
297
                if ((field.getName().equals(SolrElementField.FIELD_ISDOCUMENTEDBY)
298
                        || field.getName().equals(SolrElementField.FIELD_DOCUMENTS) || field
299
                        .getName().equals(SolrElementField.FIELD_RESOURCEMAP))
300
                        && !indexDocument.hasFieldWithValue(field.getName(), field.getValue())) {
301
                    indexDocument.addField(field);
302 8464 leinfelder
                } else if (!indexSchema.isCopyFieldTarget(indexSchema.getField(field.getName())) && !indexDocument.hasField(field.getName())) {
303
                    indexDocument.addField(field);
304 7711 tao
                }
305
            }
306
307
            indexDocument.setMerged(true);
308
            return indexDocument;
309
        }
310
    }
311
312 7546 tao
    /*
313
     * Generate a Document from the InputStream
314
     */
315
    private Document generateXmlDocument(InputStream smdStream) throws SAXException {
316
        Document doc = null;
317
318
        try {
319
            doc = builder.parse(smdStream);
320
        } catch (IOException e) {
321
            log.error(e.getMessage(), e);
322
        }
323
324
        return doc;
325
    }
326
327
    /*
328
     * Index the fields of the system metadata
329
     */
330
    private List<SolrElementField> processSysmetaFields(Document doc, String identifier) {
331
332
        List<SolrElementField> fieldList = new ArrayList<SolrElementField>();
333
        // solrFields is the list of fields defined in the application context
334
335
        for (SolrField field : sysmetaSolrFields) {
336
            try {
337
                // the field.getFields method can return a single value or
338
                // multiple values for multi-valued fields
339
                // or can return multiple SOLR document fields.
340
                fieldList.addAll(field.getFields(doc, identifier));
341
            } catch (Exception e) {
342
                e.printStackTrace();
343
            }
344
        }
345
        return fieldList;
346
347
    }
348
349
    /**
350 7577 tao
     * Check the parameters of the insert or update methods.
351
     * @param pid
352
     * @param systemMetadata
353
     * @param data
354
     * @throws SolrServerException
355
     */
356 8766 leinfelder
    private void checkParams(Identifier pid, SystemMetadata systemMetadata, String objectPath) throws SolrServerException {
357 8343 tao
        if(pid == null || pid.getValue() == null || pid.getValue().trim().equals("")) {
358 7577 tao
            throw new SolrServerException("The identifier of the indexed document should not be null or blank.");
359
        }
360
        if(systemMetadata == null) {
361 8343 tao
            throw new SolrServerException("The system metadata of the indexed document "+pid.getValue()+ " should not be null.");
362 7577 tao
        }
363 8766 leinfelder
        if(objectPath == null) {
364 8343 tao
            throw new SolrServerException("The indexed document itself for pid "+pid.getValue()+" should not be null.");
365 7577 tao
        }
366
    }
367
368
    /**
369 7627 tao
     * Insert the indexes for a document.
370 7546 tao
     * @param pid  the id of this document
371
     * @param systemMetadata  the system metadata associated with the data object
372 8766 leinfelder
     * @param data  the path to the object file itself
373 7546 tao
     * @throws SolrServerException
374 7555 tao
     * @throws JiBXException
375 7711 tao
     * @throws EncoderException
376 7733 tao
     * @throws UnsupportedType
377
     * @throws NotFound
378
     * @throws NotImplemented
379 7546 tao
     */
380 8766 leinfelder
    private synchronized void insert(Identifier pid, SystemMetadata systemMetadata, String objectPath)
381 7546 tao
                    throws IOException, SAXException, ParserConfigurationException,
382 7733 tao
                    XPathExpressionException, SolrServerException, JiBXException, EncoderException, NotImplemented, NotFound, UnsupportedType {
383 8766 leinfelder
        checkParams(pid, systemMetadata, objectPath);
384
        Map<String, SolrDoc> docs = process(pid.getValue(), systemMetadata, objectPath);
385 7546 tao
386
        //transform the Map to the SolrInputDocument which can be used by the solr server
387
        if(docs != null) {
388
            Set<String> ids = docs.keySet();
389
            for(String id : ids) {
390
                if(id != null) {
391
                    SolrDoc doc = docs.get(id);
392 7786 tao
                    insertToIndex(doc);
393
                }
394
395
            }
396
        }
397
    }
398
399 8464 leinfelder
    /**
400
     * Adds the given fields to the solr index for the given pid, preserving the index values
401
     * that previously existed
402
     * @param pid
403
     * @param fields
404
     */
405
    public void insertFields(Identifier pid, Map<String, List<Object>> fields) {
406
407
    	try {
408
			// copy the original values already indexed for this document
409
	    	SolrQuery query = new SolrQuery("id:\"" + pid.getValue() + "\"");
410
	    	QueryResponse res = solrServer.query(query);
411
	    	SolrDoc doc = new SolrDoc();
412 8503 leinfelder
413
	    	// include existing values if they exist
414 8761 leinfelder
	        IndexSchema indexSchema = SolrQueryServiceController.getInstance().getSchema();
415
416 8503 leinfelder
	        if (res.getResults().size() > 0) {
417
		        SolrDocument orig = res.getResults().get(0);
418
		    	for (String fieldName: orig.getFieldNames()) {
419
		        	//  don't transfer the copyTo fields, otherwise there are errors
420
		        	if (indexSchema.isCopyFieldTarget(indexSchema.getField(fieldName))) {
421
		        		continue;
422
		        	}
423
		        	for (Object value: orig.getFieldValues(fieldName)) {
424
		        		String stringValue = value.toString();
425
		        		// special handling for dates in ISO 8601
426
		        		if (value instanceof Date) {
427
		        			stringValue = DateTimeMarshaller.serializeDateToUTC((Date)value);
428
		        			SolrDateConverter converter = new SolrDateConverter();
429
		        			stringValue = converter.convert(stringValue);
430
		        		}
431
						SolrElementField field = new SolrElementField(fieldName, stringValue);
432
						log.debug("Adding field: " + fieldName);
433
						doc.addField(field);
434
		        	}
435
		        }
436 8464 leinfelder
	        }
437
438
	        // add the additional fields we are trying to include in the index
439
	        for (String fieldName: fields.keySet()) {
440
	    		List<Object> values = fields.get(fieldName);
441
	    		for (Object value: values) {
442 8756 leinfelder
	    			if (!doc.hasFieldWithValue(fieldName, value.toString())) {
443 8761 leinfelder
	    				if (indexSchema.getField(fieldName).multiValued()) {
444
	    					doc.addField(new SolrElementField(fieldName, value.toString()));
445
	    				} else {
446
	    	    	    	doc.updateOrAddField(fieldName, value.toString());
447
	    				}
448 8756 leinfelder
	    			}
449 8464 leinfelder
	    		}
450
	    	}
451
452 8580 leinfelder
	        // make sure there is an id in the solrdoc so it is added to the index
453
	        if (!doc.hasField(ID)) {
454
	        	doc.updateOrAddField(ID, pid.getValue());
455
	        }
456
457 8464 leinfelder
	        // insert the whole thing
458
	        insertToIndex(doc);
459
    	} catch (Exception e) {
460
    		String error = "SolrIndex.insetFields - could not update the solr index: " + e.getMessage();
461
            writeEventLog(null, pid, error);
462
            log.error(error, e);
463
    	}
464
465
    }
466
467 7786 tao
    /*
468
     * Insert a SolrDoc to the solr server.
469
     */
470
    private synchronized void insertToIndex(SolrDoc doc) throws SolrServerException, IOException {
471
        if(doc != null ) {
472
            SolrInputDocument solrDoc = new SolrInputDocument();
473
            List<SolrElementField> list = doc.getFieldList();
474
            if(list != null) {
475
                //solrDoc.addField(METACATPIDFIELD, pid);
476
                Iterator<SolrElementField> iterator = list.iterator();
477
                while (iterator.hasNext()) {
478
                    SolrElementField field = iterator.next();
479
                    if(field != null) {
480
                        String value = field.getValue();
481
                        String name = field.getName();
482
                        //System.out.println("add name/value pair - "+name+"/"+value);
483
                        solrDoc.addField(name, value);
484 7546 tao
                    }
485
                }
486
            }
487 7786 tao
            if(!solrDoc.isEmpty()) {
488 7856 tao
                /*IndexEvent event = new IndexEvent();
489 7800 tao
                event.setDate(Calendar.getInstance().getTime());
490
                Identifier pid = new Identifier();
491
                pid.setValue(doc.getIdentifier());
492 7856 tao
                event.setIdentifier(pid);*/
493 7800 tao
                try {
494 7801 tao
                    UpdateResponse response = solrServer.add(solrDoc);
495
                    solrServer.commit();
496 7805 tao
                    /*event.setType(IndexEvent.SUCCESSINSERT);
497 7801 tao
                    event.setDescription("Successfully insert the solr index for the id "+pid.getValue());
498
                    try {
499
                        EventlogFactory.createIndexEventLog().write(event);
500
                    } catch (Exception e) {
501 7802 tao
                        log.error("SolrIndex.insertToIndex - IndexEventLog can't log the index inserting event :"+e.getMessage());
502 7805 tao
                    }*/
503 7801 tao
                } catch (SolrServerException e) {
504 7856 tao
                    /*event.setAction(Event.CREATE);
505 7801 tao
                    event.setDescription("Failed to insert the solr index for the id "+pid.getValue()+" since "+e.getMessage());
506
                    try {
507
                        EventlogFactory.createIndexEventLog().write(event);
508
                    } catch (Exception ee) {
509 7802 tao
                        log.error("SolrIndex.insertToIndex - IndexEventLog can't log the index inserting event :"+ee.getMessage());
510 7856 tao
                    }*/
511 7801 tao
                    throw e;
512
                } catch (IOException e) {
513 7856 tao
                    /*event.setAction(Event.CREATE);
514 7801 tao
                    event.setDescription("Failed to insert the solr index for the id "+pid.getValue()+" since "+e.getMessage());
515
                    try {
516
                        EventlogFactory.createIndexEventLog().write(event);
517
                    } catch (Exception ee) {
518 7802 tao
                        log.error("SolrIndex.insertToIndex - IndexEventLog can't log the index inserting event :"+ee.getMessage());
519 7856 tao
                    }*/
520 7801 tao
                    throw e;
521
522 7800 tao
                }
523 7786 tao
                //System.out.println("=================the response is:\n"+response.toString());
524
            }
525 7546 tao
        }
526
    }
527 7577 tao
528
    /**
529 7627 tao
     * Update the solr index. This method handles the three scenarios:
530 8343 tao
     * 1. Remove an existing doc - if the the system metadata shows the value of the archive is true,
531 7627 tao
     *    remove the index for the previous version(s) and generate new index for the doc.
532 8343 tao
     * 2. Add a new doc - if the system metadata shows the value of the archive is false, generate the
533 7627 tao
     *    index for the doc.
534 7577 tao
     */
535 8343 tao
    public void update(Identifier pid, SystemMetadata systemMetadata) {
536 8893 tao
        if(systemMetadata==null || pid==null) {
537
            log.error("SolrIndex.update - the systemMetadata or pid is null. So nothing will be indexed.");
538
            return;
539
        }
540 8343 tao
        String objectPath = null;
541
        try {
542 8893 tao
            if(!systemMetadata.getArchived()) {
543
                objectPath = DistributedMapsFactory.getObjectPathMap().get(pid);
544
            }
545 8766 leinfelder
            update(pid, systemMetadata, objectPath);
546 8343 tao
            EventlogFactory.createIndexEventLog().remove(pid);
547
        } catch (Exception e) {
548
            String error = "SolrIndex.update - could not update the solr index since " + e.getMessage();
549
            writeEventLog(systemMetadata, pid, error);
550
            log.error(error, e);
551
        }
552 7577 tao
    }
553 8893 tao
554 7603 tao
555 8343 tao
    /**
556
     * Update the solr index. This method handles the three scenarios:
557
     * 1. Remove an existing doc - if the the system metadata shows the value of the archive is true,
558
     *    remove the index for the previous version(s) and generate new index for the doc.
559
     * 2. Add a new doc - if the system metadata shows the value of the archive is false, generate the
560
     *    index for the doc.
561
     * @param pid
562
     * @param systemMetadata
563
     * @param data
564
     * @throws SolrServerException
565
     * @throws ServiceFailure
566
     * @throws XPathExpressionException
567
     * @throws NotImplemented
568
     * @throws NotFound
569
     * @throws UnsupportedType
570
     * @throws IOException
571
     * @throws SAXException
572
     * @throws ParserConfigurationException
573
     * @throws OREParserException
574
     * @throws JiBXException
575
     * @throws EncoderException
576
     */
577 9060 leinfelder
    void update(Identifier pid, SystemMetadata systemMetadata, String objectPath) throws Exception {
578 8893 tao
        //checkParams(pid, systemMetadata, objectPath);
579
        if(systemMetadata==null || pid==null) {
580
            log.error("SolrIndex.update - the systemMetadata or pid is null. So nothing will be indexed.");
581
            return;
582
        }
583 8722 leinfelder
        boolean isArchive = systemMetadata.getArchived() != null && systemMetadata.getArchived();
584 8343 tao
        if(isArchive ) {
585
            //delete the index for the archived objects
586
            remove(pid.getValue(), systemMetadata);
587
            log.info("SolrIndex.update============================= archive the idex for the identifier "+pid);
588
        } else {
589
            //generate index for either add or update.
590 8766 leinfelder
            insert(pid, systemMetadata, objectPath);
591 8343 tao
            log.info("SolrIndex.update============================= insert index for the identifier "+pid);
592
        }
593
    }
594 7627 tao
595 7786 tao
596
597
    /*
598
     * Is the pid a resource map
599
     */
600 8343 tao
    private boolean isDataPackage(String pid, SystemMetadata sysmeta) throws FileNotFoundException, ServiceFailure {
601 7786 tao
        boolean isDataPackage = false;
602 8343 tao
        //SystemMetadata sysmeta = DistributedMapsFactory.getSystemMetadata(pid);
603 7786 tao
        if(sysmeta != null) {
604 8352 tao
            isDataPackage = IndexGeneratorTimerTask.isResourceMap(sysmeta.getFormatId());
605 7786 tao
        }
606
        return isDataPackage;
607
    }
608
609
    private boolean isPartOfDataPackage(String pid) throws XPathExpressionException, NotImplemented, NotFound, UnsupportedType, SolrServerException, IOException, ParserConfigurationException, SAXException {
610
        SolrDoc dataPackageIndexDoc = ResourceMapSubprocessor.getSolrDoc(pid);
611
        if (dataPackageIndexDoc != null) {
612
            String resourceMapId = dataPackageIndexDoc
613
                    .getFirstFieldValue(SolrElementField.FIELD_RESOURCEMAP);
614
            return StringUtils.isNotEmpty(resourceMapId);
615
        } else {
616
            return false;
617
        }
618
    }
619 8343 tao
    /**
620
     * Remove the indexed associated with specified pid.
621
     * @param pid  the pid which the indexes are associated with
622
     * @throws IOException
623
     * @throws SolrServerException
624
     * @throws ParserConfigurationException
625
     * @throws SAXException
626
     * @throws UnsupportedType
627
     * @throws NotFound
628
     * @throws NotImplemented
629
     * @throws XPathExpressionException
630
     * @throws ServiceFailure
631
     * @throws OREParserException
632
     */
633 9060 leinfelder
    private void remove(String pid, SystemMetadata sysmeta) throws Exception {
634 8343 tao
        if (isDataPackage(pid, sysmeta)) {
635
            removeDataPackage(pid);
636
        } else if (isPartOfDataPackage(pid)) {
637
            removeFromDataPackage(pid);
638
        } else {
639
            removeFromIndex(pid);
640
        }
641
    }
642
643
    /*
644 8893 tao
     * Remove the resource map from the solr index. It doesn't only remove the index for itself and also
645
     * remove the relationship for the related metadata and data objects.
646 8864 tao
     */
647 9060 leinfelder
    private void removeDataPackage(String pid) throws Exception {
648 8893 tao
        removeFromIndex(pid);
649
        List<SolrDoc> docsToUpdate = getUpdatedSolrDocsByRemovingResourceMap(pid);
650
        if (docsToUpdate != null && !docsToUpdate.isEmpty()) {
651
            //SolrElementAdd addCommand = new SolrElementAdd(docsToUpdate);
652
            //httpService.sendUpdate(solrIndexUri, addCommand);
653
            for(SolrDoc doc : docsToUpdate) {
654
                removeFromIndex(doc.getIdentifier());
655
                insertToIndex(doc);
656
            }
657
        }
658
659 8864 tao
    }
660 8893 tao
661 8864 tao
    /*
662 8893 tao
     * Get the list of the solr doc which need to be updated because the removal of the resource map
663 8864 tao
     */
664 8893 tao
    private List<SolrDoc> getUpdatedSolrDocsByRemovingResourceMap(String resourceMapId)
665
            throws UnsupportedType, NotFound, SolrServerException, ParserConfigurationException, SAXException, MalformedURLException, IOException, XPathExpressionException {
666
        List<SolrDoc> updatedSolrDocs = null;
667
        if (resourceMapId != null && !resourceMapId.trim().equals("")) {
668
            /*List<SolrDoc> docsContainResourceMap = httpService.getDocumentsByResourceMap(
669
                    solrQueryUri, resourceMapId);*/
670
            List<SolrDoc> docsContainResourceMap = ResourceMapSubprocessor.getDocumentsByResourceMap(resourceMapId);
671
            updatedSolrDocs = removeResourceMapRelationship(docsContainResourceMap,
672
                    resourceMapId);
673
        }
674
        return updatedSolrDocs;
675 8864 tao
    }
676 8893 tao
677
    /*
678
     * Get the list of the solr doc which need to be updated because the removal of the resource map
679
     */
680
    private List<SolrDoc> removeResourceMapRelationship(List<SolrDoc> docsContainResourceMap,
681
            String resourceMapId) throws XPathExpressionException, IOException {
682
        List<SolrDoc> totalUpdatedSolrDocs = new ArrayList<SolrDoc>();
683
        if (docsContainResourceMap != null && !docsContainResourceMap.isEmpty()) {
684
            for (SolrDoc doc : docsContainResourceMap) {
685
                List<SolrDoc> updatedSolrDocs = new ArrayList<SolrDoc>();
686
                List<String> resourceMapIdStrs = doc
687
                        .getAllFieldValues(SolrElementField.FIELD_RESOURCEMAP);
688
                List<String> dataIdStrs = doc
689
                        .getAllFieldValues(SolrElementField.FIELD_DOCUMENTS);
690
                List<String> metadataIdStrs = doc
691
                        .getAllFieldValues(SolrElementField.FIELD_ISDOCUMENTEDBY);
692
                if ((dataIdStrs == null || dataIdStrs.isEmpty())
693
                        && (metadataIdStrs == null || metadataIdStrs.isEmpty())) {
694
                    // only has resourceMap field, doesn't have either documentBy or documents fields.
695
                    // so we only remove the resource map field.
696
                    doc.removeFieldsWithValue(SolrElementField.FIELD_RESOURCEMAP, resourceMapId);
697
                    updatedSolrDocs.add(doc);
698
                } else if ((dataIdStrs != null && !dataIdStrs.isEmpty())
699
                        && (metadataIdStrs == null || metadataIdStrs.isEmpty())) {
700
                    //The solr doc is for a metadata object since the solr doc documents data files
701
                    updatedSolrDocs = removeAggregatedItems(resourceMapId, doc, resourceMapIdStrs,
702
                            dataIdStrs, SolrElementField.FIELD_DOCUMENTS);
703
                } else if ((dataIdStrs == null || dataIdStrs.isEmpty())
704
                        && (metadataIdStrs != null && !metadataIdStrs.isEmpty())) {
705
                    //The solr doc is for a data object since it documentedBy elements.
706
                    updatedSolrDocs = removeAggregatedItems(resourceMapId, doc, resourceMapIdStrs,
707
                            metadataIdStrs, SolrElementField.FIELD_ISDOCUMENTEDBY);
708
                } else if ((dataIdStrs != null && !dataIdStrs.isEmpty())
709
                        && (metadataIdStrs != null && !metadataIdStrs.isEmpty())){
710
                    // both metadata and data for one object
711
                    List<SolrDoc> solrDocsRemovedDocuments = removeAggregatedItems(resourceMapId, doc, resourceMapIdStrs,
712
                            dataIdStrs, SolrElementField.FIELD_DOCUMENTS);
713
                    List<SolrDoc> solrDocsRemovedDocumentBy = removeAggregatedItems(resourceMapId, doc, resourceMapIdStrs,
714
                            metadataIdStrs, SolrElementField.FIELD_ISDOCUMENTEDBY);
715
                    updatedSolrDocs = mergeUpdatedSolrDocs(solrDocsRemovedDocumentBy, solrDocsRemovedDocuments);
716
                }
717
                //move them to the final result
718
                if(updatedSolrDocs != null) {
719
                    for(SolrDoc updatedDoc: updatedSolrDocs) {
720
                        totalUpdatedSolrDocs.add(updatedDoc);
721
                    }
722
                }
723
724
            }
725
726
        }
727
        return totalUpdatedSolrDocs;
728
    }
729 8864 tao
730
    /*
731 8893 tao
     * Process the list of ids of the documentBy/documents in a slor doc.
732 8343 tao
     */
733 8893 tao
    private List<SolrDoc> removeAggregatedItems(String targetResourceMapId, SolrDoc doc,
734
            List<String> resourceMapIdsInDoc, List<String> aggregatedItemsInDoc, String fieldNameRemoved) {
735
        List<SolrDoc> updatedSolrDocs = new ArrayList<SolrDoc>();
736
        if (doc != null && resourceMapIdsInDoc != null && aggregatedItemsInDoc != null
737
                && fieldNameRemoved != null) {
738
            if (resourceMapIdsInDoc.size() == 1) {
739
                //only has one resource map. remove the resource map. also remove the documentBy
740
                doc.removeFieldsWithValue(SolrElementField.FIELD_RESOURCEMAP, targetResourceMapId);
741
                doc.removeAllFields(fieldNameRemoved);
742
                updatedSolrDocs.add(doc);
743
            } else if (resourceMapIdsInDoc.size() > 1) {
744
                //we have multiple resource maps. We should match them.
745
                Map<String, String> ids = matchResourceMapsAndItems(doc.getIdentifier(),
746
                        targetResourceMapId, resourceMapIdsInDoc, aggregatedItemsInDoc, fieldNameRemoved);
747
                if (ids != null) {
748
                    for (String id : ids.keySet()) {
749
                        doc.removeFieldsWithValue(fieldNameRemoved, id);
750
                    }
751
                }
752
                doc.removeFieldsWithValue(SolrElementField.FIELD_RESOURCEMAP,
753
                        targetResourceMapId);
754
                updatedSolrDocs.add(doc);
755
                /*if (aggregatedItemsInDoc.size() > 1) {
756
757 7786 tao
758 8893 tao
                } else {
759
                    //multiple resource map aggregate same metadata and data. Just remove the resource map
760
                    doc.removeFieldsWithValue(SolrElementField.FIELD_RESOURCEMAP,
761
                            targetResourceMapId);
762
                    updatedSolrDocs.add(doc);
763
                }*/
764 8343 tao
            }
765 8893 tao
        }
766
        return updatedSolrDocs;
767
    }
768 8343 tao
769 8893 tao
    /*
770
     * Return a map of mapping aggregation id map the target resourceMapId.
771
     * This will look the aggregation information in another side - If the targetId
772
     * is a metadata object, we will look the data objects which it describes; If
773
     * the targetId is a data object, we will look the metadata object which documents it.
774
     */
775
    private Map<String, String> matchResourceMapsAndItems(String targetId,
776
            String targetResourceMapId, List<String> originalResourceMaps, List<String> aggregatedItems, String fieldName) {
777
        Map<String, String> map = new HashMap<String, String>();
778
        if (targetId != null && targetResourceMapId != null && aggregatedItems != null
779
                && fieldName != null) {
780
            String newFieldName = null;
781
            if (fieldName.equals(SolrElementField.FIELD_ISDOCUMENTEDBY)) {
782
                newFieldName = SolrElementField.FIELD_DOCUMENTS;
783
            } else if (fieldName.equals(SolrElementField.FIELD_DOCUMENTS)) {
784
                newFieldName = SolrElementField.FIELD_ISDOCUMENTEDBY;
785
            }
786
            if (newFieldName != null) {
787
                for (String item : aggregatedItems) {
788
                    SolrDoc doc = null;
789
                    try {
790
                        doc = getDocumentById(item);
791
                        List<String> fieldValues = doc.getAllFieldValues(newFieldName);
792
                        List<String> resourceMapIds = doc
793
                                .getAllFieldValues(SolrElementField.FIELD_RESOURCEMAP);
794
                        if ((fieldValues != null && fieldValues.contains(targetId))
795
                                && (resourceMapIds != null && resourceMapIds
796
                                        .contains(targetResourceMapId))) {
797
                            //okay, we found the target aggregation item id and the resource map id
798
                            //in this solr doc. However, we need check if another resource map with different
799
                            //id but specify the same relationship. If we have the id(s), we should not
800
                            // remove the documents( or documentBy) element since we need to preserve the
801
                            // relationship for the remain resource map.
802
                            boolean hasDuplicateIds = false;
803
                            if(originalResourceMaps != null) {
804
                               for(String id :resourceMapIds) {
805
                                    if (originalResourceMaps.contains(id) && !id.equals(targetResourceMapId)) {
806
                                        hasDuplicateIds = true;
807
                                        break;
808
                                    }
809
                                }
810
                            }
811
                            if(!hasDuplicateIds) {
812
                                map.put(item, targetResourceMapId);
813
                            }
814
815
                        }
816
                    } catch (Exception e) {
817
                        log.warn("SolrIndex.matchResourceMapsAndItems - can't get the solrdoc for the id "
818
                                + item + " since " + e.getMessage());
819
                    }
820
                }
821
            }
822
        }
823
        return map;
824
    }
825 8343 tao
826 8893 tao
    /*
827
     * Get the solr index doc from the index server for the given id.
828
     */
829
    private SolrDoc getDocumentById(String id) throws NotImplemented, NotFound, UnsupportedType,
830
                SolrServerException, ParserConfigurationException, SAXException, XPathExpressionException, IOException {
831
        SolrDoc doc = ResourceMapSubprocessor.getSolrDoc(id);
832
        return doc;
833
    }
834
835
    /*
836
     * Merge two list of updated solr docs. removedDocumentBy has the correct information about documentBy element.
837
     * removedDocuments has the correct information about the documents element.
838
     * So we go through the two list and found the two docs having the same identifier.
839
     * Get the list of the documents value from the one in the removedDoucments (1).
840
     * Remove all values of documents from the one in the removedDocumentBy.
841
     * Then copy the list of documents value from (1) to to the one in the removedDocumentBy.
842
     */
843
    private List<SolrDoc> mergeUpdatedSolrDocs(List<SolrDoc>removedDocumentBy, List<SolrDoc>removedDocuments) {
844
        List<SolrDoc> mergedDocuments = new ArrayList<SolrDoc>();
845
        if(removedDocumentBy == null || removedDocumentBy.isEmpty()) {
846
            mergedDocuments = removedDocuments;
847
        } else if (removedDocuments == null || removedDocuments.isEmpty()) {
848
            mergedDocuments = removedDocumentBy;
849
        } else {
850
            int sizeOfDocBy = removedDocumentBy.size();
851
            int sizeOfDocs = removedDocuments.size();
852
            for(int i=sizeOfDocBy-1; i>= 0; i--) {
853
                SolrDoc docInRemovedDocBy = removedDocumentBy.get(i);
854
                for(int j= sizeOfDocs-1; j>=0; j--) {
855
                    SolrDoc docInRemovedDocs = removedDocuments.get(j);
856
                    if(docInRemovedDocBy.getIdentifier().equals(docInRemovedDocs.getIdentifier())) {
857
                        //find the same doc in both list. let's merge them.
858
                        //first get all the documents element from the docWithDocs(it has the correct information about the documents element)
859
                        List<String> idsInDocuments = docInRemovedDocs.getAllFieldValues(SolrElementField.FIELD_DOCUMENTS);
860
                        docInRemovedDocBy.removeAllFields(SolrElementField.FIELD_DOCUMENTS);//clear out any documents element in docInRemovedDocBy
861
                        //add the Documents element from the docInRemovedDocs if it has any.
862
                        // The docInRemovedDocs has the correct information about the documentBy. Now it copied the correct information of the documents element.
863
                        // So docInRemovedDocs has both correct information about the documentBy and documents elements.
864
                        if(idsInDocuments != null) {
865
                            for(String id : idsInDocuments) {
866
                                if(id != null && !id.trim().equals("")) {
867
                                    docInRemovedDocBy.addField(new SolrElementField(SolrElementField.FIELD_DOCUMENTS, id));
868
                                }
869
870
                            }
871
                        }
872
                        //intersect the resource map ids.
873
                        List<String> resourceMapIdsInWithDocs = docInRemovedDocs.getAllFieldValues(SolrElementField.FIELD_RESOURCEMAP);
874
                        List<String> resourceMapIdsInWithDocBy = docInRemovedDocBy.getAllFieldValues(SolrElementField.FIELD_RESOURCEMAP);
875
                        docInRemovedDocBy.removeAllFields(SolrElementField.FIELD_RESOURCEMAP);
876
                        Collection resourceMapIds = CollectionUtils.union(resourceMapIdsInWithDocs, resourceMapIdsInWithDocBy);
877
                        if(resourceMapIds != null) {
878
                            for(Object idObj : resourceMapIds) {
879
                                String id = (String)idObj;
880
                                docInRemovedDocBy.addField(new SolrElementField(SolrElementField.FIELD_RESOURCEMAP, id));
881
                            }
882
                        }
883
                        //we don't need do anything about the documentBy elements since the docInRemovedDocBy has the correct information.
884
                        mergedDocuments.add(docInRemovedDocBy);
885
                        //delete the two documents from the list
886
                        removedDocumentBy.remove(i);
887
                        removedDocuments.remove(j);
888
                        break;
889 8343 tao
                    }
890 8893 tao
891 8343 tao
                }
892
            }
893 8893 tao
            // when we get there, if the two lists are empty, this will be a perfect merge. However, if something are left. we
894
            //just put them in.
895
            for(SolrDoc doc: removedDocumentBy) {
896
                mergedDocuments.add(doc);
897
            }
898
            for(SolrDoc doc: removedDocuments) {
899
                mergedDocuments.add(doc);
900
            }
901 8343 tao
        }
902 8893 tao
        return mergedDocuments;
903 8343 tao
    }
904 8893 tao
905 8343 tao
906 8344 tao
    /*
907
     * Remove a pid which is part of resource map.
908
     */
909 9060 leinfelder
    private void removeFromDataPackage(String pid) throws Exception  {
910 8343 tao
        SolrDoc indexedDoc = ResourceMapSubprocessor.getSolrDoc(pid);
911
        removeFromIndex(pid);
912
        List<SolrDoc> docsToUpdate = new ArrayList<SolrDoc>();
913
914
        List<String> documents = indexedDoc.getAllFieldValues(SolrElementField.FIELD_DOCUMENTS);
915
        for (String documentsValue : documents) {
916
            SolrDoc solrDoc = ResourceMapSubprocessor.getSolrDoc(documentsValue);
917
            solrDoc.removeFieldsWithValue(SolrElementField.FIELD_ISDOCUMENTEDBY, pid);
918
            removeFromIndex(documentsValue);
919
            insertToIndex(solrDoc);
920
        }
921
922
        List<String> documentedBy = indexedDoc
923
                .getAllFieldValues(SolrElementField.FIELD_ISDOCUMENTEDBY);
924
        for (String documentedByValue : documentedBy) {
925
            SolrDoc solrDoc = ResourceMapSubprocessor.getSolrDoc(documentedByValue);
926 8345 tao
            solrDoc.removeFieldsWithValue(SolrElementField.FIELD_DOCUMENTS, pid);
927 8343 tao
            //docsToUpdate.add(solrDoc);
928
            removeFromIndex(documentedByValue);
929
            insertToIndex(solrDoc);
930
        }
931
932
        //SolrElementAdd addCommand = new SolrElementAdd(docsToUpdate);
933
        //httpService.sendUpdate(solrIndexUri, addCommand);
934
    }
935
936
    /*
937
     * Remove a pid from the solr index
938
     */
939 9060 leinfelder
    private synchronized void removeFromIndex(String identifier) throws Exception {
940
941
942
    	Map<String, SolrDoc> docs = new HashMap<String, SolrDoc>();
943
944
        for (IDocumentDeleteSubprocessor deleteSubprocessor : deleteSubprocessors) {
945
            docs.putAll(deleteSubprocessor.processDocForDelete(identifier, docs));
946
        }
947
        List<SolrDoc> docsToUpdate = new ArrayList<SolrDoc>();
948
        List<String> idsToIndex = new ArrayList<String>();
949
        for (String idToUpdate : docs.keySet()) {
950
            if (docs.get(idToUpdate) != null) {
951
                docsToUpdate.add(docs.get(idToUpdate));
952
            } else {
953
                idsToIndex.add(idToUpdate);
954
            }
955
        }
956
957
        // update the docs we have
958
        for (SolrDoc docToUpdate : docsToUpdate) {
959
        	insertToIndex(docToUpdate);
960
        }
961
962
        // delete this one
963
        deleteDocFromIndex(identifier);
964
965
        // index the rest
966
        for (String idToIndex : idsToIndex) {
967
        	Identifier pid = new Identifier();
968
        	pid.setValue(idToIndex);
969
            SystemMetadata sysMeta = DistributedMapsFactory.getSystemMetadata(idToIndex);
970
            if (SolrDoc.visibleInIndex(sysMeta)) {
971
                String objectPath = DistributedMapsFactory.getObjectPathMap().get(pid);
972
                insert(pid, sysMeta, objectPath);
973
            }
974
        }
975
976
    }
977
978
    private void deleteDocFromIndex(String pid) throws Exception {
979
    	if (pid != null && !pid.trim().equals("")) {
980 8343 tao
            /*IndexEvent event = new IndexEvent();
981
            event.setDate(Calendar.getInstance().getTime());
982
            Identifier identifier = new Identifier();
983
            identifier.setValue(pid);
984
            event.setIdentifier(identifier);*/
985
            try {
986
                solrServer.deleteById(pid);
987
                solrServer.commit();
988
                /*event.setType(IndexEvent.SUCCESSDELETE);
989
                event.setDescription("Successfully remove the solr index for the id "+identifier.getValue());
990
                try {
991
                    EventlogFactory.createIndexEventLog().write(event);
992
                } catch (Exception e) {
993
                    log.error("SolrIndex.removeFromIndex - IndexEventLog can't log the index deleting event :"+e.getMessage());
994
                }*/
995
            } catch (SolrServerException e) {
996
                /*event.setAction(Event.DELETE);
997
                event.setDescription("Failurely remove the solr index for the id "+identifier.getValue()+" since "+e.getMessage());
998
                try {
999
                    EventlogFactory.createIndexEventLog().write(event);
1000
                } catch (Exception ee) {
1001
                    log.error("SolrIndex.removeFromIndex - IndexEventLog can't log the index deleting event :"+ee.getMessage());
1002
                }*/
1003
                throw e;
1004
1005
            } catch (IOException e) {
1006
                /*event.setAction(Event.DELETE);
1007
                event.setDescription("Failurely remove the solr index for the id "+identifier.getValue()+" since "+e.getMessage());
1008
                try {
1009
                    EventlogFactory.createIndexEventLog().write(event);
1010
                } catch (Exception ee) {
1011
                    log.error("SolrIndex.removeFromIndex - IndexEventLog can't log the index deleting event :"+ee.getMessage());
1012
                }*/
1013
                throw e;
1014
            }
1015
1016
        }
1017 9060 leinfelder
1018 8343 tao
    }
1019
1020 7569 tao
    /**
1021
     * Get the solrServer
1022
     * @return
1023
     */
1024 7604 tao
    public SolrServer getSolrServer() {
1025 7569 tao
        return solrServer;
1026
    }
1027
1028
    /**
1029 7604 tao
     * Set the solrServer.
1030 7569 tao
     * @param solrServer
1031
     */
1032 7604 tao
    public void setSolrServer(SolrServer solrServer) {
1033 7569 tao
        this.solrServer = solrServer;
1034
    }
1035 7604 tao
1036
    /**
1037 7606 tao
     * Get all indexed ids in the solr server.
1038
     * @return an empty list if there is no index.
1039 7604 tao
     * @throws SolrServerException
1040
     */
1041
    public List<String> getSolrIds() throws SolrServerException {
1042
        List<String> list = new ArrayList<String>();
1043
        SolrQuery query = new SolrQuery(IDQUERY);
1044
        query.setRows(Integer.MAX_VALUE);
1045
        query.setFields(ID);
1046
        QueryResponse response = solrServer.query(query);
1047
        SolrDocumentList docs = response.getResults();
1048
        if(docs != null) {
1049
            for(SolrDocument doc :docs) {
1050
                String identifier = (String)doc.getFieldValue(ID);
1051
                //System.out.println("======================== "+identifier);
1052
                list.add(identifier);
1053
            }
1054
        }
1055
        return list;
1056
    }
1057 8343 tao
1058
    private void writeEventLog(SystemMetadata systemMetadata, Identifier pid, String error) {
1059
        IndexEvent event = new IndexEvent();
1060
        event.setIdentifier(pid);
1061
        event.setDate(Calendar.getInstance().getTime());
1062
        String action = null;
1063
        if (systemMetadata == null ) {
1064
            action = Event.CREATE.xmlValue();
1065
            event.setAction(Event.CREATE);
1066
        }
1067
        else if(systemMetadata.getArchived()) {
1068
            action = Event.DELETE.xmlValue();
1069
            event.setAction(Event.DELETE);
1070
        } else {
1071
            action = Event.CREATE.xmlValue();
1072
            event.setAction(Event.CREATE);
1073
        }
1074
        event.setDescription("Failed to "+action+"the solr index for the id "+pid.getValue()+" since "+error);
1075
        try {
1076
            EventlogFactory.createIndexEventLog().write(event);
1077
        } catch (Exception ee) {
1078
            log.error("SolrIndex.insertToIndex - IndexEventLog can't log the index inserting event :"+ee.getMessage());
1079
        }
1080
    }
1081 7542 tao
}