Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class that gets Accession Number, check for uniqueness
4
 *             and register it into db
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Jivka Bojilova, Matt Jones
8
 *
9
 *   '$Author: leinfelder $'
10
 *     '$Date: 2011-11-02 20:40:12 -0700 (Wed, 02 Nov 2011) $'
11
 * '$Revision: 6595 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27
package edu.ucsb.nceas.metacat.index;
28

    
29
import java.io.FileInputStream;
30
import java.io.FileNotFoundException;
31
import java.io.IOException;
32
import java.io.InputStream;
33
import java.util.ArrayList;
34
import java.util.Calendar;
35
import java.util.Collections;
36
import java.util.Date;
37
import java.util.List;
38
import java.util.TimerTask;
39

    
40
import javax.xml.parsers.ParserConfigurationException;
41
import javax.xml.xpath.XPathExpressionException;
42

    
43
import org.apache.commons.logging.Log;
44
import org.apache.commons.logging.LogFactory;
45
import org.apache.solr.client.solrj.SolrServerException;
46
import org.dataone.configuration.Settings;
47
import org.dataone.service.exceptions.InvalidRequest;
48
import org.dataone.service.exceptions.InvalidToken;
49
import org.dataone.service.exceptions.NotAuthorized;
50
import org.dataone.service.exceptions.NotFound;
51
import org.dataone.service.exceptions.NotImplemented;
52
import org.dataone.service.exceptions.ServiceFailure;
53
import org.dataone.service.exceptions.UnsupportedType;
54
import org.dataone.service.types.v1.Event;
55
import org.dataone.service.types.v1.Identifier;
56
import org.dataone.service.types.v1.ObjectFormatIdentifier;
57
import org.dataone.service.types.v1.SystemMetadata;
58
import org.xml.sax.SAXException;
59

    
60
import com.hazelcast.core.IMap;
61
import com.hazelcast.core.ISet;
62

    
63
import edu.ucsb.nceas.metacat.common.index.event.IndexEvent;
64
import edu.ucsb.nceas.metacat.index.event.EventlogFactory;
65
import edu.ucsb.nceas.metacat.index.event.IndexEventLogException;
66

    
67

    
68
/**
69
 * A class represents the object to generate massive solr indexes.
70
 * This can happen during an update of Metacat (generating index for all existing documents)
71
 * or regenerate index for those documents
72
 * failing to build index during the insert or update.
73
 * 
74
 * @author tao
75
 *
76
 */
77
public class IndexGenerator extends TimerTask {
78
    
79
    private static final int FIRST =0;
80
    private static final int SECOND =1;
81
    private static final int THIRD = 2;
82
    private static final int FOURTH = 3;
83
    public static final int WAITTIME = 10000;
84
    public static final int MAXWAITNUMBER = 180;
85
    private static final String HTTP = "http://";
86
    private static final String MNAPPENDIX = "/d1/mn";
87
    private static final String RESOURCEMAPPROPERYNAME = "index.resourcemap.namespace";
88
    public static final String WAITIMEPOPERTYNAME = "index.regenerate.start.waitingtime";
89
    public static final String MAXATTEMPTSPROPERTYNAME = "index.regenerate.start.maxattempts";
90
    
91
    private static int waitingTime = WAITTIME;
92
    private static int maxAttempts = MAXWAITNUMBER;
93
    
94
    private SolrIndex solrIndex = null;
95
    //private SystemMetadataEventListener systemMetadataListener = null;
96
    private IMap<Identifier, SystemMetadata> systemMetadataMap;
97
    private IMap<Identifier, String> objectPathMap;
98
    private Log log = LogFactory.getLog(IndexGenerator.class);
99
    //private MNode mNode = null;
100
    private static List<String> resourceMapNamespaces = null;
101
    
102
    /**
103
     * Constructor
104
     * @param solrIndex
105
     * @param systemMetadataListener
106
     */
107
    public IndexGenerator(SolrIndex solrIndex) {
108
        this.solrIndex = solrIndex;
109
        resourceMapNamespaces = Settings.getConfiguration().getList(RESOURCEMAPPROPERYNAME);
110
        //this.systemMetadataListener = systemMetadataListener;
111
        //this.mNode = new MNode(buildMNBaseURL());
112
        try {
113
            waitingTime = Settings.getConfiguration().getInt(WAITIMEPOPERTYNAME);
114
            maxAttempts = Settings.getConfiguration().getInt(MAXATTEMPTSPROPERTYNAME);
115
        } catch (Exception e) {
116
            log.warn("IndexGenerator.constructor - couldn't read the waiting time or maxattempts from the metacat.properties file since : "+e.getMessage()+". Default values will be used");
117
            waitingTime = WAITTIME;
118
            maxAttempts = MAXWAITNUMBER;
119
        }
120
    }
121
    
122
    /**
123
     * Build the index for all documents in Metacat without overwriting.
124
     * @throws SolrServerException 
125
     * @throws ServiceFailure 
126
     * @throws NotImplemented 
127
     * @throws NotAuthorized 
128
     * @throws InvalidToken 
129
     * @throws InvalidRequest 
130
     * @throws IndexEventLogException 
131
     * @throws IllegalAccessException 
132
     * @throws InstantiationException 
133
     * @throws ClassNotFoundException 
134
     */
135
    /*public void indexAll() throws InvalidRequest, InvalidToken, NotAuthorized, 
136
                            NotImplemented, ServiceFailure, SolrServerException, FileNotFoundException, ClassNotFoundException, InstantiationException, IllegalAccessException, IndexEventLogException {
137
        boolean force = false;
138
        indexAll(force);
139
    }*/
140
    
141
    /**
142
     * Build the index for all documents.
143
     * @throws SolrServerException 
144
     * @throws ServiceFailure 
145
     * @throws NotImplemented 
146
     * @throws NotAuthorized 
147
     * @throws InvalidToken 
148
     * @throws InvalidRequest 
149
     * @throws IndexEventLogException 
150
     * @throws IllegalAccessException 
151
     * @throws InstantiationException 
152
     * @throws ClassNotFoundException 
153
     * @throws ParserConfigurationException 
154
     * @throws SAXException 
155
     * @throws IOException 
156
     * @throws UnsupportedType 
157
     * @throws NotFound 
158
     * @throws XPathExpressionException 
159
     */
160
    public void indexAll() throws InvalidRequest, InvalidToken,
161
                NotAuthorized, NotImplemented, ServiceFailure, SolrServerException, ClassNotFoundException, InstantiationException, IllegalAccessException, IndexEventLogException, XPathExpressionException, NotFound, UnsupportedType, IOException, SAXException, ParserConfigurationException {
162
        Date since = null;
163
        Date until = null;
164
        index(since, until);
165
    }
166
    
167
    /**
168
     * Build the index for the docs which have been modified since the specified date.
169
     * @param since
170
     * @throws SolrServerException 
171
     * @throws ServiceFailure 
172
     * @throws NotImplemented 
173
     * @throws NotAuthorized 
174
     * @throws InvalidToken 
175
     * @throws InvalidRequest 
176
     * @throws IndexEventLogException 
177
     * @throws IllegalAccessException 
178
     * @throws InstantiationException 
179
     * @throws ClassNotFoundException 
180
     * @throws ParserConfigurationException 
181
     * @throws SAXException 
182
     * @throws IOException 
183
     * @throws UnsupportedType 
184
     * @throws NotFound 
185
     * @throws XPathExpressionException 
186
     */
187
    public void index(Date since) throws InvalidRequest, InvalidToken, 
188
                    NotAuthorized, NotImplemented, ServiceFailure, SolrServerException, ClassNotFoundException, InstantiationException, IllegalAccessException, IndexEventLogException, XPathExpressionException, NotFound, UnsupportedType, IOException, SAXException, ParserConfigurationException {
189
        Date until = null;
190
        index(since, until);
191
    }
192
    
193
    /**
194
     *  Build the index for the docs which have been modified between the specified date.s
195
     * @param since
196
     * @param until
197
     * @throws SolrServerException 
198
     * @throws ServiceFailure 
199
     * @throws NotImplemented 
200
     * @throws NotAuthorized 
201
     * @throws InvalidToken 
202
     * @throws InvalidRequest 
203
     * @throws IndexEventLogException 
204
     * @throws IllegalAccessException 
205
     * @throws InstantiationException 
206
     * @throws ClassNotFoundException 
207
     * @throws ParserConfigurationException 
208
     * @throws SAXException 
209
     * @throws IOException 
210
     * @throws UnsupportedType 
211
     * @throws NotFound 
212
     * @throws XPathExpressionException 
213
     */
214
    public void index(Date since, Date until) throws SolrServerException, InvalidRequest, 
215
                                                InvalidToken, NotAuthorized, NotImplemented, ServiceFailure, ClassNotFoundException, InstantiationException, IllegalAccessException, IndexEventLogException, XPathExpressionException, NotFound, UnsupportedType, IOException, SAXException, ParserConfigurationException {
216
        Date processedDate = null;
217
        List<String> solrIds = null;
218
        initSystemMetadataMap();
219
        initObjectPathMap();
220
        List[] metacatIds = getMetacatIds(since, until);
221
        List<String> otherMetacatIds = metacatIds[FIRST];
222
        List<String> resourceMapIds =  metacatIds[SECOND];
223
        List<String> otherDeletedMetacatIds = metacatIds[THIRD];
224
        List<String> resourceMapDeletedIds = metacatIds[FOURTH];
225
        
226
        //figure out the procesedDate by comparing the last element of otherMetacatIds and resourceMapIds.
227
        List<Long> maxCollection = new ArrayList<Long>();
228
        Date latestOtherId = null;
229
        if (otherMetacatIds != null && !otherMetacatIds.isEmpty()) {
230
            int size = otherMetacatIds.size();
231
            String id = otherMetacatIds.get(size-1);
232
            SystemMetadata sysmeta = getSystemMetadata(id);
233
            latestOtherId = sysmeta.getDateSysMetadataModified();
234
            maxCollection.add(new Long(latestOtherId.getTime()));
235
        }
236
        
237
        Date latestDeletedOtherIds = null;
238
        if (otherDeletedMetacatIds != null && !otherDeletedMetacatIds.isEmpty()) {
239
            int size = otherDeletedMetacatIds.size();
240
            String id = otherDeletedMetacatIds.get(size-1);
241
            SystemMetadata sysmeta = getSystemMetadata(id);
242
            latestDeletedOtherIds = sysmeta.getDateSysMetadataModified();
243
            maxCollection.add(new Long(latestDeletedOtherIds.getTime()));
244
        }
245
        
246
        Date latestResourceId = null;
247
        if (resourceMapIds != null && !resourceMapIds.isEmpty()) {
248
            int size = resourceMapIds.size();
249
            String id = resourceMapIds.get(size-1);
250
            SystemMetadata sysmeta = getSystemMetadata(id);
251
            latestResourceId = sysmeta.getDateSysMetadataModified();
252
            maxCollection.add(new Long(latestResourceId.getTime()));
253
        }
254
        
255
        Date latestDeletedResourceId = null;
256
        if(resourceMapDeletedIds != null && !resourceMapDeletedIds.isEmpty()) {
257
            int size = resourceMapDeletedIds.size();
258
            String id = resourceMapDeletedIds.get(size-1);
259
            SystemMetadata sysmeta = getSystemMetadata(id);
260
            latestDeletedResourceId = sysmeta.getDateSysMetadataModified();
261
            maxCollection.add(new Long(latestDeletedResourceId.getTime()));
262
        }
263
        
264
        if(!maxCollection.isEmpty()) {
265
            Long max = Collections.max(maxCollection);
266
            processedDate = new Date(max.longValue());
267
        }
268
        /*if(latestOtherId != null && latestResourceId != null && latestOtherId.getTime() > latestResourceId.getTime()) {
269
            processedDate = latestOtherId;
270
        } else if (latestOtherId != null && latestResourceId != null && latestOtherId.getTime()  <= latestResourceId.getTime()) {
271
            processedDate = latestResourceId;
272
        } else if (latestOtherId == null && latestResourceId != null) {
273
            processedDate = latestResourceId;
274
        } else if (latestOtherId != null && latestResourceId == null) {
275
            processedDate = latestOtherId;
276
        }*/
277
        
278
        
279
        //add the failedPids 
280
        List<IndexEvent> failedEvents = EventlogFactory.createIndexEventLog().getEvents(null, null, null, null);
281
        List<IndexEvent> failedOtherIds = new ArrayList<IndexEvent>();
282
        List<IndexEvent> failedResourceMapIds = new ArrayList<IndexEvent>();
283
        if(failedEvents != null) {
284
            for(IndexEvent event : failedEvents) {
285
            	String id = event.getIdentifier().getValue();
286
                SystemMetadata sysmeta = getSystemMetadata(id);
287
                if(sysmeta != null) {
288
                    ObjectFormatIdentifier formatId =sysmeta.getFormatId();
289
                    if(formatId != null && formatId.getValue() != null && resourceMapNamespaces != null && isResourceMap(formatId)) {
290
                        failedResourceMapIds.add(event);
291
                    } else {
292
                        failedOtherIds.add(event);
293
                    }
294
                }
295
            }
296
        }
297
        indexFailedIds(failedOtherIds);
298
        indexFailedIds(failedResourceMapIds);
299
        
300
        /*if(!failedOtherIds.isEmpty()) {
301
            failedOtherIds.addAll(otherMetacatIds);
302
        } else {
303
            failedOtherIds = otherMetacatIds;
304
        }
305
        
306
        if(!failedResourceMapIds.isEmpty()) {
307
            failedResourceMapIds.addAll(resourceMapIds);
308
        } else {
309
            failedResourceMapIds = resourceMapIds;
310
        }*/
311
        
312
        log.info("the metacat ids (except the resource map ids)-----------------------------"+otherMetacatIds);
313
        log.info("the deleted metacat ids (except the resource map ids)-----------------------------"+otherDeletedMetacatIds);
314
        log.info("the metacat resroucemap ids -----------------------------"+resourceMapIds);
315
        log.info("the deleted metacat resroucemap ids -----------------------------"+resourceMapDeletedIds);
316
        index(otherMetacatIds);
317
        removeIndex(otherDeletedMetacatIds);
318
        index(resourceMapIds);
319
        removeIndex(resourceMapDeletedIds);
320
       
321
        //record the timed index.
322
        if(processedDate != null) {
323
            EventlogFactory.createIndexEventLog().setLastProcessDate(processedDate);
324
        }
325
        
326
    }
327
    
328
    /*
329
     * Doing index
330
     */
331
    private void index(List<String> metacatIds) {
332
        if(metacatIds != null) {
333
            for(String metacatId : metacatIds) {
334
                if(metacatId != null) {
335
                        try {
336
                            generateIndex(metacatId);
337
                        } catch (Exception e) {
338
                            IndexEvent event = new IndexEvent();
339
                            Identifier pid = new Identifier();
340
                            pid.setValue(metacatId);
341
                            event.setIdentifier(pid);
342
                            event.setDate(Calendar.getInstance().getTime());
343
                            event.setAction(Event.CREATE);
344
                            String error = "IndexGenerator.index - Metacat Index couldn't generate the index for the id - "+metacatId+" because "+e.getMessage();
345
                            event.setDescription(error);
346
                            try {
347
                                EventlogFactory.createIndexEventLog().write(event);
348
                            } catch (Exception ee) {
349
                                log.error("SolrIndex.insertToIndex - IndexEventLog can't log the index inserting event :"+ee.getMessage());
350
                            }
351
                            log.error(error);
352
                        }
353
                        
354
                   
355
                }
356
            }
357
        }
358
    }
359
    
360
    /*
361
     * Index those ids which failed in the process (We got them from the EventLog)
362
     */
363
    private void indexFailedIds(List<IndexEvent> events) {
364
        if(events != null) {
365
            for(IndexEvent event : events) {
366
                if(event != null) {
367
                    Identifier identifier = event.getIdentifier();
368
                    if(identifier != null) {
369
                        String id = identifier.getValue();
370
                        if(id != null) {
371
                            Event action = event.getAction();
372
                            if (action != null && action.equals(Event.CREATE)) {
373
                                try {
374
                                    generateIndex(id);
375
                                    EventlogFactory.createIndexEventLog().remove(identifier);
376
                                } catch (Exception e) {
377
                                    log.error("IndexGenerator.indexFailedIds - Metacat Index couldn't generate the index for the id - "+id+" because "+e.getMessage());
378
                                }
379
                            } else if (action != null && action.equals(Event.DELETE)) {
380
                                try {
381
                                    removeIndex(id);
382
                                    EventlogFactory.createIndexEventLog().remove(identifier);
383
                                } catch (Exception e) {
384
                                    log.error("IndexGenerator.indexFailedIds - Metacat Index couldn't remove the index for the id - "+id+" because "+e.getMessage());
385
                                }
386
                            }
387
                        }
388
                    }
389
                }
390
            }
391
        }
392
    }
393
    
394
    public void run() {
395
        /*IndexEvent event = new IndexEvent();
396
        event.setDate(Calendar.getInstance().getTime());
397
        event.setType(IndexEvent.STARTTIMEDINDEX);
398
        event.setDescription("Start the timed index job");
399
        try {
400
            EventlogFactory.createIndexEventLog().write(event);
401
        } catch (Exception e) {
402
            log.error("IndexGenerator.run - IndexEventLog can't log the timed indexing start event :"+e.getMessage());
403
        }*/
404
        try {
405
            Date since = EventlogFactory.createIndexEventLog().getLastProcessDate();
406
            index(since);
407
        } catch (InvalidRequest e) {
408
            // TODO Auto-generated catch block
409
            //e.printStackTrace();
410
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
411
        } catch (InvalidToken e) {
412
            // TODO Auto-generated catch block
413
            //e.printStackTrace();
414
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
415
        } catch (NotAuthorized e) {
416
            // TODO Auto-generated catch block
417
            //e.printStackTrace();
418
        } catch (NotImplemented e) {
419
            // TODO Auto-generated catch block
420
            //e.printStackTrace();
421
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
422
        } catch (ServiceFailure e) {
423
            // TODO Auto-generated catch block
424
            //e.printStackTrace();
425
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
426
        } catch (SolrServerException e) {
427
            // TODO Auto-generated catch block
428
            //e.printStackTrace();
429
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
430
        } catch (FileNotFoundException e) {
431
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
432
        }
433
        /*event.setDate(Calendar.getInstance().getTime());
434
        event.setType(IndexEvent.FINISHTIMEDINDEX);
435
        event.setDescription("Finish the timed index job");
436
        try {
437
            EventlogFactory.createIndexEventLog().write(event);
438
        } catch (Exception e) {
439
            log.error("IndexGenerator.run - IndexEventLog can't log the timed indexing finish event :"+e.getMessage());
440
        }*/ catch (ClassNotFoundException e) {
441
            // TODO Auto-generated catch block
442
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
443
        } catch (InstantiationException e) {
444
            // TODO Auto-generated catch block
445
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
446
        } catch (IllegalAccessException e) {
447
            // TODO Auto-generated catch block
448
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
449
        } catch (IndexEventLogException e) {
450
            // TODO Auto-generated catch block
451
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
452
        } catch (XPathExpressionException e) {
453
            // TODO Auto-generated catch block
454
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
455
        } catch (NotFound e) {
456
            // TODO Auto-generated catch block
457
            e.printStackTrace();
458
        } catch (UnsupportedType e) {
459
            // TODO Auto-generated catch block
460
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
461
        } catch (IOException e) {
462
            // TODO Auto-generated catch block
463
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
464
        } catch (SAXException e) {
465
            // TODO Auto-generated catch block
466
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
467
        } catch (ParserConfigurationException e) {
468
            // TODO Auto-generated catch block
469
            log.error("IndexGenerator.run - Metadata-Index couldn't generate indexes for those documents which haven't been indexed : "+e.getMessage());
470
        }
471
    }
472
    
473
    /*
474
     * Get the indexed ids list from the solr server.
475
     * An empty list will be returned if there is no ids.
476
     */
477
    private List<String> getSolrDocIds() throws SolrServerException {
478
        List<String> ids = solrIndex.getSolrIds();
479
        return ids;
480
    }
481
    
482
    /*
483
     * Get an array of the list of ids of the metacat which has the systemmetadata modification in the range.
484
     * 
485
     * If since and util are null, it will return all of them.
486
     * The first element of the list is the ids except the resource map. The second elements of the list is the ids of the resource map.
487
     * The reason to split them is when we index the resource map, we need the index of the documents in the resource map ready.
488
     * The last element in the each list has the latest SystemMetadata modification date. But they are not sorted.
489
     */
490
    private List[] getMetacatIds(Date since, Date until) throws InvalidRequest, 
491
                        InvalidToken, NotAuthorized, NotImplemented, ServiceFailure, FileNotFoundException {
492
        
493
        List<String> resourceMapIds = new ArrayList();
494
        List<String> resourceMapDeletedIds = new ArrayList();
495
        List<String> otherIds = new ArrayList();
496
        List<String> otherDeletedIds = new ArrayList();
497
        List[] ids = new List[4];
498
        ids[FIRST]= otherIds;
499
        ids[SECOND] = resourceMapIds;
500
        ids[THIRD]  = otherDeletedIds;
501
        ids[FOURTH] = resourceMapDeletedIds;
502
        ISet<Identifier> metacatIds = DistributedMapsFactory.getIdentifiersSet();
503
        Date otherPreviousDate = null;
504
        Date otherDeletedPreviousDate = null;
505
        Date resourceMapPreviousDate = null;
506
        Date resourceMapDeletedPreviousDate = null;
507
        if(metacatIds != null) {
508
            for(Identifier identifier : metacatIds) {
509
                if(identifier != null && identifier.getValue() != null && !identifier.getValue().equals("")) {
510
                    SystemMetadata sysmeta = getSystemMetadata(identifier.getValue());
511
                    if(sysmeta != null) {
512
                        ObjectFormatIdentifier formatId =sysmeta.getFormatId();
513
                        //System.out.println("the object format id is "+formatId.getValue());
514
                        //System.out.println("the ============ resourcMapNamespaces"+resourceMapNamespaces);
515
                        boolean correctTimeRange = false;
516
                        Date sysDate = sysmeta.getDateSysMetadataModified();
517
                        if(since == null && until == null) {
518
                            correctTimeRange = true;
519
                        } else if (since != null && until == null) {
520
                            if(sysDate.getTime() > since.getTime()) {
521
                                correctTimeRange = true;
522
                            }
523
                        } else if (since == null && until != null) {
524
                            if(sysDate.getTime() < until.getTime()) {
525
                                correctTimeRange = true;
526
                            }
527
                        } else if (since != null && until != null) {
528
                            if(sysDate.getTime() > since.getTime() && sysDate.getTime() < until.getTime()) {
529
                                correctTimeRange = true;
530
                            }
531
                        }
532
                        if(correctTimeRange && formatId != null && formatId.getValue() != null && resourceMapNamespaces != null && isResourceMap(formatId)) {
533
                            //for the resource map
534
                            if(sysmeta.getArchived() || sysmeta.getObsoletedBy() != null) {
535
                                //archived ids
536
                                if(!resourceMapDeletedIds.isEmpty()) {
537
                                    if(sysDate.getTime() > resourceMapDeletedPreviousDate.getTime()) {
538
                                        resourceMapDeletedIds.add(identifier.getValue());//append to the end of the list if current is later than the previous one
539
                                        resourceMapDeletedPreviousDate = sysDate;//reset resourceMapPreviousDate to the bigger one
540
                                    } else {
541
                                        int size = resourceMapDeletedIds.size();//
542
                                        resourceMapDeletedIds.add(size -1, identifier.getValue());//keep the previous one at the end of the list.
543
                                    }
544
                                } else {
545
                                    resourceMapDeletedIds.add(identifier.getValue());
546
                                    resourceMapDeletedPreviousDate = sysDate;//init resourcemapPreviousDate
547
                                }
548
                            } else {
549
                                // current ids
550
                                if(!resourceMapIds.isEmpty()) {
551
                                    if(sysDate.getTime() > resourceMapPreviousDate.getTime()) {
552
                                        resourceMapIds.add(identifier.getValue());//append to the end of the list if current is later than the previous one
553
                                        resourceMapPreviousDate = sysDate;//reset resourceMapPreviousDate to the bigger one
554
                                    } else {
555
                                        int size = resourceMapIds.size();//
556
                                        resourceMapIds.add(size -1, identifier.getValue());//keep the previous one at the end of the list.
557
                                    }
558
                                } else {
559
                                    resourceMapIds.add(identifier.getValue());
560
                                    resourceMapPreviousDate = sysDate;//init resourcemapPreviousDate
561
                                }
562
                            }
563
                        } else if (correctTimeRange) {
564
                            if(sysmeta.getArchived() || sysmeta.getObsoletedBy() != null) {
565
                                //for the archived ids
566
                                if(!otherDeletedIds.isEmpty()) {
567
                                    if(sysDate.getTime() > otherDeletedPreviousDate.getTime()) {
568
                                        otherDeletedIds.add(identifier.getValue());
569
                                        otherDeletedPreviousDate = sysDate;//reset otherDeletedPreviousDate to the bigger one
570
                                    } else {
571
                                        int size = otherDeletedIds.size();
572
                                        otherDeletedIds.add(size-1, identifier.getValue());
573
                                    }
574
                                } else {
575
                                    otherDeletedIds.add(identifier.getValue());
576
                                    otherDeletedPreviousDate = sysDate;//init otherDeletedPreviousDate
577
                                }
578
                            } else {
579
                                //for the current ids
580
                                if(!otherIds.isEmpty()) {
581
                                    if(sysDate.getTime() > otherPreviousDate.getTime()) {
582
                                        otherIds.add(identifier.getValue());
583
                                        otherPreviousDate = sysDate;//reset otherPreviousDate to the bigger one
584
                                    } else {
585
                                        int size = otherIds.size();
586
                                        otherIds.add(size-1, identifier.getValue());
587
                                    }
588
                                } else {
589
                                    otherIds.add(identifier.getValue());
590
                                    otherPreviousDate = sysDate;//init otherPreviousDate
591
                                }
592
                            }
593
                        }
594
                        
595
                    }
596
                }
597
            }
598
        }
599
        return ids;
600
    }
601
    
602
    /*
603
     * If the specified ObjectFormatIdentifier is a resrouce map namespace.
604
     */
605
    public static boolean isResourceMap(ObjectFormatIdentifier formatId) {
606
        boolean isResourceMap = false;
607
        if(formatId != null && resourceMapNamespaces != null) {
608
            for(String namespace : resourceMapNamespaces) {
609
                if(namespace != null && formatId.getValue() != null && !formatId.getValue().trim().equals("") && formatId.getValue().equals(namespace)) {
610
                    isResourceMap = true;
611
                    break;
612
                }
613
            }
614
        }
615
        return isResourceMap;
616
    }
617
    
618
   
619
    
620
    /*
621
     * Generate index for the id.
622
     */
623
    private void generateIndex(String id) throws Exception {
624
        if(id != null)  {
625
                SystemMetadata sysmeta = getSystemMetadata(id);
626
                //only update none-archived id.
627
                if(sysmeta != null && !sysmeta.getArchived() && sysmeta.getObsoletedBy() == null) {
628
                        InputStream data = getDataObject(id);
629
                        Identifier obsolete = sysmeta.getObsoletes();
630
                        List<String> obsoleteChain = null;
631
                        if(obsolete != null) {
632
                            obsoleteChain = getObsoletes(id);
633
                        } 
634
                        solrIndex.update(id, obsoleteChain, sysmeta, data);
635
                } else {
636
                    throw new Exception("IndexGenerator.generate - there is no found SystemMetadata associated with the id "+id);
637
                }
638
           
639
        }
640
    }
641
    
642
    /*
643
     * Remove the solr index for the list of ids
644
     */
645
    private void removeIndex(List<String> ids) throws ServiceFailure, XPathExpressionException, NotImplemented, NotFound, UnsupportedType, IOException, SolrServerException, SAXException, ParserConfigurationException {
646
        if(ids!= null) {
647
            for(String id :ids) {
648
                removeIndex(id);
649
            }
650
        }
651
    }
652
    
653
    /*
654
     * Remove the index for the id
655
     */
656
    private void removeIndex(String id) throws ServiceFailure, XPathExpressionException, NotImplemented, NotFound, UnsupportedType, IOException, SolrServerException, SAXException, ParserConfigurationException  {
657
        if(id != null) {
658
            solrIndex.remove(id);
659
        }
660
    }
661
    
662
    /*
663
     * Initialize the system metadata map
664
     */
665
    private void initSystemMetadataMap() throws FileNotFoundException, ServiceFailure{
666
        int times = 0;
667
        if(systemMetadataMap == null) {
668
            systemMetadataMap = DistributedMapsFactory.getSystemMetadataMap();
669
            /*while(true) {
670
                try {
671
                    systemMetadataMap = DistributedMapsFactory.getSystemMetadataMap();
672
                    break;
673
                } catch (FileNotFoundException e) {
674
                    throw e;
675
                } catch (ServiceFailure e) {
676
                    if(times <= maxAttempts) {
677
                        log.warn("IndexGenerator.initSystemMetadataMap - the hazelcast service is not ready : "
678
                                         +e.getMessage()+"\nWe will try to access it "+waitingTime/1000+" seconds later ");
679
                        try {
680
                            Thread.sleep(waitingTime);
681
                        } catch (Exception ee) {
682
                            log.warn("IndexGenerator.initSystemMetadataMap - the thread can't sleep for "+waitingTime/1000+" seconds to wait the hazelcast service");
683
                        }
684
                       
685
                    } else {
686
                        throw new ServiceFailure("0000", "IndexGenerator.initSystemMetadataMap - the hazelcast service is not ready even though Metacat-index wailted for "+maxAttempts*waitingTime/1000+" seconds. We can't get the system metadata from it and the building index can't happen this time");
687
                    }
688
                }
689
                times++;
690
            }*/
691
        }
692
    }
693
    
694
    /*
695
     * We should call this method after calling initSystemMetadataMap since this method doesn't have the mechanism to wait the readiness of the hazelcast service
696
     */
697
    private void initObjectPathMap() throws FileNotFoundException, ServiceFailure {
698
        if(objectPathMap == null) {
699
            objectPathMap = DistributedMapsFactory.getObjectPathMap();
700
        }
701
    }
702
    /**
703
     * Get an InputStream as the data object for the specific pid.
704
     * @param pid
705
     * @return
706
     * @throws FileNotFoundException
707
     */
708
    private InputStream getDataObject(String pid) throws FileNotFoundException {
709
        Identifier identifier = new Identifier();
710
        identifier.setValue(pid);
711
        String objectPath = objectPathMap.get(identifier);
712
        InputStream data = null;
713
        data = new FileInputStream(objectPath);
714
        return data;
715

    
716
    }
717
    
718
    /**
719
     * Get the SystemMetadata for the specified id from the distributed Map.
720
     * The null maybe is returned if there is no system metadata found.
721
     * @param id  the specified id.
722
     * @return the SystemMetadata associated with the id.
723
     */
724
    private SystemMetadata getSystemMetadata(String id) {
725
        SystemMetadata metadata = null;
726
        if(systemMetadataMap != null && id != null) {
727
            Identifier identifier = new Identifier();
728
            identifier.setValue(id);
729
            metadata = systemMetadataMap.get(identifier);
730
        }
731
        return metadata;
732
    }
733
    
734
    /**
735
     * Get the obsoletes chain of the specified id. The returned list doesn't include
736
     * the specified id itself. The newer version has the lower index number in the list.
737
     * Empty list will be returned if there is no document to be obsoleted by this id.
738
     * @param id
739
     * @return
740
     */
741
    private List<String> getObsoletes(String id) {
742
        List<String> obsoletes = new ArrayList<String>();
743
        while (id != null) {
744
            SystemMetadata metadata = getSystemMetadata(id);
745
            id = null;//set it to be null in order to stop the while loop if the id can't be assinged to a new value in the following code.
746
            if(metadata != null) {
747
                Identifier identifier = metadata.getObsoletes();
748
                if(identifier != null && identifier.getValue() != null && !identifier.getValue().trim().equals("")) {
749
                    obsoletes.add(identifier.getValue());
750
                    id = identifier.getValue();
751
                } 
752
            } 
753
        }
754
        return obsoletes;
755
    }
756
    
757
    /**
758
     * Overwrite and do nothing
759
     */
760
    public boolean cancel() {
761
        return true;
762
    }
763

    
764
}
(3-3/6)