Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2010 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *  Purpose: To test the Access Controls in metacat by JUnit
6
 *
7
 *   '$Author: leinfelder $'
8
 *     '$Date: 2014-08-07 14:28:35 -0700 (Thu, 07 Aug 2014) $'
9
 * '$Revision: 8834 $'
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
 */
25

    
26
package edu.ucsb.nceas.metacat.dataone;
27

    
28
import java.io.InputStream;
29
import java.io.InputStreamReader;
30
import java.io.Reader;
31
import java.math.BigInteger;
32
import java.util.Collections;
33
import java.util.Date;
34
import java.util.Vector;
35

    
36
import junit.framework.Test;
37
import junit.framework.TestSuite;
38

    
39
import org.apache.wicket.protocol.http.mock.MockHttpServletRequest;
40
import org.dataone.client.D1Node;
41
import org.dataone.client.NodeLocator;
42
import org.dataone.client.exception.ClientSideException;
43
import org.dataone.client.v2.CNode;
44
import org.dataone.client.v2.itk.D1Client;
45
import org.dataone.client.v2.formats.ObjectFormatCache;
46
import org.dataone.service.types.v1.AccessPolicy;
47
import org.dataone.service.types.v1.AccessRule;
48
import org.dataone.service.types.v1.Checksum;
49
import org.dataone.service.types.v1.Identifier;
50
import org.dataone.service.types.v2.Node;
51
import org.dataone.service.types.v2.ObjectFormatList;
52
import org.dataone.service.types.v1.NodeReference;
53
import org.dataone.service.types.v1.NodeType;
54
import org.dataone.service.types.v1.Permission;
55
import org.dataone.service.types.v1.Session;
56
import org.dataone.service.types.v1.Subject;
57
import org.dataone.service.types.v2.SystemMetadata;
58
import org.dataone.service.types.v1.comparators.SystemMetadataDateUploadedComparator;
59
import org.dataone.service.types.v1.util.ChecksumUtil;
60
import org.dataone.service.types.v2.util.ObjectFormatServiceImpl;
61
import org.dataone.service.util.Constants;
62
import org.dataone.service.util.TypeMarshaller;
63

    
64

    
65
import edu.ucsb.nceas.MCTestCase;
66
import edu.ucsb.nceas.metacat.client.Metacat;
67
import edu.ucsb.nceas.metacat.client.MetacatFactory;
68

    
69
/**
70
 * A class for testing the scenarios of getting the the head version of an SID chain
71
 */
72
public class SIDTest extends MCTestCase {   
73
    
74
    private static final String OBSOLETES = "obsoletes";
75
    private static final String OBSOLETEDBY = "obsoletedBy";
76
   
77
	/**
78
    * constructor for the test
79
    */
80
    public SIDTest(String name) {
81
        super(name);
82
    }
83
  
84
    /**
85
	 * Establish a testing framework by initializing appropriate objects
86
	 */
87
    public void setUp() throws Exception {
88
    	
89
    }
90

    
91
	/**
92
	 * Release any objects after tests are complete
93
	 */
94
	public void tearDown() {
95
		
96
	}
97
	
98
	/**
99
     * Create a suite of tests to be run together
100
     */
101
    public static Test suite() 
102
    {
103
        TestSuite suite = new TestSuite();
104
        suite.addTest(new SIDTest("initialize"));
105
        suite.addTest(new SIDTest("testCases"));
106
        return suite;
107
    }
108
	
109
	
110
	
111
	/**
112
	 * Run an initial test that always passes to check that the test harness is
113
	 * working.
114
	 */
115
	public void initialize() 
116
	{
117
		assertTrue(1 == 1);
118
	}
119
	
120
	public void testCases() throws Exception {
121
	    testCase1();
122
	    testCase2();
123
	    testCase3();
124
	    testCase4();
125
	    testCase5();
126
	    testCase6();
127
	    testCase7();
128
	    testCase8();
129
	    testCase9();
130
	    testCase10();
131
	    testCase11();
132
	    testCase12();
133
	    testCase13();
134
	    testCase14();
135
	    testCase15();
136
	    testCase16();
137
        testCase17();
138
	}
139
	
140
	/**
141
	 * case 1. P1(S1) <-> P2(S1),  S1 = P2 (Rule 1)
142
	 */
143
	private void testCase1() throws Exception {
144
	    Identifier s1 = new Identifier();
145
        s1.setValue("S1");
146
        Identifier s2 = new Identifier();
147
        s2.setValue("S2");
148
        Identifier p1 = new Identifier();
149
        p1.setValue("P1");
150
        Identifier p2 = new Identifier();
151
        p2.setValue("P2");
152
       
153
        SystemMetadata p1Sys = new SystemMetadata();
154
        p1Sys.setIdentifier(p1);
155
        p1Sys.setSeriesId(s1);
156
        p1Sys.setObsoletedBy(p2);
157
        p1Sys.setDateUploaded(new Date(100));
158
        
159
        SystemMetadata p2Sys = new SystemMetadata();
160
        p2Sys.setIdentifier(p2);
161
        p2Sys.setSeriesId(s1);
162
        p2Sys.setObsoletes(p1);
163
        p2Sys.setDateUploaded(new Date(200));
164
        
165
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
166
        chain.add(p1Sys);
167
        chain.add(p2Sys);
168
      
169
        System.out.println("Case 1:");
170
        Identifier head = getHeadVersion(s1, chain);
171
        //System.out.println("The head is "+head.getValue());
172
        assertTrue(head.equals(p2));
173
	}
174
	
175
	
176
	/**
177
     * Case 2. P1(S1) ? P2(S1), S1 = P2, Error condition, P2 not allowed (should not exist) (Rule 2)
178
     */
179
    private void testCase2() throws Exception {
180
        Identifier s1 = new Identifier();
181
        s1.setValue("S1");
182
        Identifier s2 = new Identifier();
183
        s2.setValue("S2");
184
        Identifier p1 = new Identifier();
185
        p1.setValue("P1");
186
        Identifier p2 = new Identifier();
187
        p2.setValue("P2");
188
       
189
        
190
        SystemMetadata p1Sys = new SystemMetadata();
191
        p1Sys.setIdentifier(p1);
192
        p1Sys.setSeriesId(s1);
193
        p1Sys.setDateUploaded(new Date(100));
194
        
195
        SystemMetadata p2Sys = new SystemMetadata();
196
        p2Sys.setIdentifier(p2);
197
        p2Sys.setSeriesId(s1);
198
        p2Sys.setDateUploaded(new Date(200));
199
        
200
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
201
        chain.add(p1Sys);
202
        chain.add(p2Sys);
203
      
204
        System.out.println("Case 2:");
205
        Identifier head = getHeadVersion(s1, chain);
206
        //System.out.println("The head is "+head.getValue());
207
        assertTrue(head.equals(p2));
208
    }
209
    
210
    /**
211
     * case 3. P1(S1) <- P2(S1), S1 = P2, Discouraged, but not error condition, S1 = P2 (Rule 2, missingFields)
212
     */
213
    private void testCase3() throws Exception {
214
        Identifier s1 = new Identifier();
215
        s1.setValue("S1");
216
        Identifier s2 = new Identifier();
217
        s2.setValue("S2");
218
        Identifier p1 = new Identifier();
219
        p1.setValue("P1");
220
        Identifier p2 = new Identifier();
221
        p2.setValue("P2");
222
       
223
        
224
        SystemMetadata p1Sys = new SystemMetadata();
225
        p1Sys.setIdentifier(p1);
226
        p1Sys.setSeriesId(s1);
227
        p1Sys.setDateUploaded(new Date(100));
228
        
229
        SystemMetadata p2Sys = new SystemMetadata();
230
        p2Sys.setIdentifier(p2);
231
        p2Sys.setSeriesId(s1);
232
        p2Sys.setObsoletes(p1);
233
        p2Sys.setDateUploaded(new Date(200));
234
        
235
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
236
        chain.add(p1Sys);
237
        chain.add(p2Sys);
238
      
239
        System.out.println("Case 3:");
240
        Identifier head = getHeadVersion(s1, chain);
241
        //System.out.println("The head is "+head.getValue());
242
        assertTrue(head.equals(p2));
243
    }
244
    
245
    /**
246
     * case 4. P1(S1) <-> P2(S1) <-> P3(S2), S1 = P2(use Rule 3), S2 = P3 (use Rule 1)
247
     */
248
    private void testCase4() throws Exception {
249
        Identifier s1 = new Identifier();
250
        s1.setValue("S1");
251
        Identifier s2 = new Identifier();
252
        s2.setValue("S2");
253
        Identifier p1 = new Identifier();
254
        p1.setValue("P1");
255
        Identifier p2 = new Identifier();
256
        p2.setValue("P2");
257
        Identifier p3 = new Identifier();
258
        p3.setValue("P3");
259
       
260
        
261
        SystemMetadata p1Sys = new SystemMetadata();
262
        p1Sys.setIdentifier(p1);
263
        p1Sys.setSeriesId(s1);
264
        p1Sys.setObsoletedBy(p2);
265
        p1Sys.setDateUploaded(new Date(100));
266
        
267
        SystemMetadata p2Sys = new SystemMetadata();
268
        p2Sys.setIdentifier(p2);
269
        p2Sys.setSeriesId(s1);
270
        p2Sys.setObsoletes(p1);
271
        p2Sys.setObsoletedBy(p3);
272
        p2Sys.setDateUploaded(new Date(200));
273
        
274
        SystemMetadata p3Sys = new SystemMetadata();
275
        p3Sys.setIdentifier(p3);
276
        p3Sys.setSeriesId(s2);
277
        p3Sys.setObsoletes(p2);
278
        p3Sys.setDateUploaded(new Date(300));
279

    
280
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
281
        chain.add(p1Sys);
282
        chain.add(p2Sys);
283
        chain.add(p3Sys);
284
      
285
        System.out.println("Case 4:");
286
        Identifier head = getHeadVersion(s1, chain);
287
        //System.out.println("The head is "+head.getValue());
288
        assertTrue(head.equals(p2));
289
        Identifier head2 = getHeadVersion(s2, chain);
290
        //System.out.println("The head is "+head.getValue());
291
        assertTrue(head2.equals(p3));
292
    }
293
    
294
    /**
295
     * case 5. P1(S1) <- P2(S1) <- P3(S2), S1 = P2 (use Rule 2 or have missing field), S2 = P3  (use Rule 1)
296
     */
297
    private void testCase5() throws Exception {
298
        Identifier s1 = new Identifier();
299
        s1.setValue("S1");
300
        Identifier s2 = new Identifier();
301
        s2.setValue("S2");
302
        Identifier p1 = new Identifier();
303
        p1.setValue("P1");
304
        Identifier p2 = new Identifier();
305
        p2.setValue("P2");
306
        Identifier p3 = new Identifier();
307
        p3.setValue("P3");
308
       
309
        
310
        SystemMetadata p1Sys = new SystemMetadata();
311
        p1Sys.setIdentifier(p1);
312
        p1Sys.setSeriesId(s1);
313
        p1Sys.setDateUploaded(new Date(100));
314
        
315
        SystemMetadata p2Sys = new SystemMetadata();
316
        p2Sys.setIdentifier(p2);
317
        p2Sys.setSeriesId(s1);
318
        p2Sys.setObsoletes(p1);
319
        p2Sys.setDateUploaded(new Date(200));
320
        
321
        SystemMetadata p3Sys = new SystemMetadata();
322
        p3Sys.setIdentifier(p3);
323
        p3Sys.setSeriesId(s2);
324
        p3Sys.setObsoletes(p2);
325
        p3Sys.setDateUploaded(new Date(300));
326

    
327
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
328
        chain.add(p1Sys);
329
        chain.add(p2Sys);
330
        chain.add(p3Sys);
331
      
332
        System.out.println("Case 5:");
333
        Identifier head = getHeadVersion(s1, chain);
334
        //System.out.println("The head is "+head.getValue());
335
        assertTrue(head.equals(p2));
336
        Identifier head2 = getHeadVersion(s2, chain);
337
        //System.out.println("The head is "+head.getValue());
338
        assertTrue(head2.equals(p3));
339
    }
340
    
341
    /**
342
     * case 6. P1(S1) <-> P2(S1) <-> P3(), S1 = P2 (use Rule 3)
343
     */
344
    private void testCase6() throws Exception {
345
        Identifier s1 = new Identifier();
346
        s1.setValue("S1");
347
        Identifier s2 = new Identifier();
348
        s2.setValue("S2");
349
        Identifier p1 = new Identifier();
350
        p1.setValue("P1");
351
        Identifier p2 = new Identifier();
352
        p2.setValue("P2");
353
        Identifier p3 = new Identifier();
354
        p3.setValue("P3");
355
       
356
        
357
        SystemMetadata p1Sys = new SystemMetadata();
358
        p1Sys.setIdentifier(p1);
359
        p1Sys.setSeriesId(s1);
360
        p1Sys.setObsoletedBy(p2);
361
        p1Sys.setDateUploaded(new Date(100));
362
        
363
        SystemMetadata p2Sys = new SystemMetadata();
364
        p2Sys.setIdentifier(p2);
365
        p2Sys.setSeriesId(s1);
366
        p2Sys.setObsoletes(p1);
367
        p2Sys.setObsoletedBy(p3);
368
        p2Sys.setDateUploaded(new Date(200));
369
        
370
        SystemMetadata p3Sys = new SystemMetadata();
371
        p3Sys.setIdentifier(p3);
372
        //p3Sys.setSeriesId(s2);
373
        p3Sys.setObsoletes(p2);
374
        p3Sys.setDateUploaded(new Date(300));
375

    
376
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
377
        chain.add(p1Sys);
378
        chain.add(p2Sys);
379
        chain.add(p3Sys);
380
      
381
        System.out.println("Case 6:");
382
        Identifier head = getHeadVersion(s1, chain);
383
        //System.out.println("The head is "+head.getValue());
384
        assertTrue(head.equals(p2));
385
    }
386
    
387
    /**
388
     * case 7. P1(S1) <-> P2(S1) <-> P3() <-> P4(S2), S1 = P2 (Rule 3), S2 = P4 (Rule 1)
389
     */
390
    private void testCase7() throws Exception {
391
        Identifier s1 = new Identifier();
392
        s1.setValue("S1");
393
        Identifier s2 = new Identifier();
394
        s2.setValue("S2");
395
        Identifier p1 = new Identifier();
396
        p1.setValue("P1");
397
        Identifier p2 = new Identifier();
398
        p2.setValue("P2");
399
        Identifier p3 = new Identifier();
400
        p3.setValue("P3");
401
        Identifier p4 = new Identifier();
402
        p4.setValue("P4");
403
       
404
        
405
        SystemMetadata p1Sys = new SystemMetadata();
406
        p1Sys.setIdentifier(p1);
407
        p1Sys.setSeriesId(s1);
408
        p1Sys.setObsoletedBy(p2);
409
        p1Sys.setDateUploaded(new Date(100));
410
        
411
        SystemMetadata p2Sys = new SystemMetadata();
412
        p2Sys.setIdentifier(p2);
413
        p2Sys.setSeriesId(s1);
414
        p2Sys.setObsoletes(p1);
415
        p2Sys.setObsoletedBy(p3);
416
        p2Sys.setDateUploaded(new Date(200));
417
        
418
        SystemMetadata p3Sys = new SystemMetadata();
419
        p3Sys.setIdentifier(p3);
420
        //p3Sys.setSeriesId(s2);
421
        p3Sys.setObsoletes(p2);
422
        p3Sys.setObsoletedBy(p4);
423
        p3Sys.setDateUploaded(new Date(300));
424
        
425
        SystemMetadata p4Sys = new SystemMetadata();
426
        p4Sys.setIdentifier(p4);
427
        p4Sys.setSeriesId(s2);
428
        p4Sys.setObsoletes(p3);
429
        p4Sys.setDateUploaded(new Date(400));
430

    
431
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
432
        chain.add(p1Sys);
433
        chain.add(p2Sys);
434
        chain.add(p3Sys);
435
        chain.add(p4Sys);
436
      
437
        System.out.println("Case 7:");
438
        Identifier head = getHeadVersion(s1, chain);
439
        //System.out.println("The head is "+head.getValue());
440
        assertTrue(head.equals(p2));
441
        Identifier head2 = getHeadVersion(s2, chain);
442
        //System.out.println("The head is "+head.getValue());
443
        assertTrue(head2.equals(p4));
444
    }
445
    
446
    /**
447
     * case 8. P1(S1) <-> P2(S1) ->  ??  <- P4(S1), S1 = P4, (Rule 1) (Error, but will happen)
448
     */
449
    private void testCase8() throws Exception {
450
        Identifier s1 = new Identifier();
451
        s1.setValue("S1");
452
        Identifier s2 = new Identifier();
453
        s2.setValue("S2");
454
        Identifier p1 = new Identifier();
455
        p1.setValue("P1");
456
        Identifier p2 = new Identifier();
457
        p2.setValue("P2");
458
        Identifier p3 = new Identifier();
459
        p3.setValue("P3");
460
        Identifier p4 = new Identifier();
461
        p4.setValue("P4");
462
       
463
        
464
        SystemMetadata p1Sys = new SystemMetadata();
465
        p1Sys.setIdentifier(p1);
466
        p1Sys.setSeriesId(s1);
467
        p1Sys.setObsoletedBy(p2);
468
        p1Sys.setDateUploaded(new Date(100));
469
        
470
        SystemMetadata p2Sys = new SystemMetadata();
471
        p2Sys.setIdentifier(p2);
472
        p2Sys.setSeriesId(s1);
473
        p2Sys.setObsoletes(p1);
474
        p2Sys.setObsoletedBy(p3);
475
        p2Sys.setDateUploaded(new Date(200));
476
        
477
        
478
        SystemMetadata p4Sys = new SystemMetadata();
479
        p4Sys.setIdentifier(p4);
480
        p4Sys.setSeriesId(s1);
481
        p4Sys.setObsoletes(p3);
482
        p4Sys.setDateUploaded(new Date(400));
483

    
484
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
485
        chain.add(p1Sys);
486
        chain.add(p2Sys);
487
        chain.add(p4Sys);
488
      
489
        System.out.println("Case 8:");
490
        Identifier head = getHeadVersion(s1, chain);
491
        //System.out.println("The head is "+head.getValue());
492
        assertTrue(head.equals(p4));
493
    }
494
    
495
    /**
496
     * case 9. P1(S1) <-> P2(S1)  ??  <- P4(S1), S1 = P4 (Rule 2) (??: object was not synchronized)
497
     */
498
    private void testCase9() throws Exception {
499
        Identifier s1 = new Identifier();
500
        s1.setValue("S1");
501
        Identifier s2 = new Identifier();
502
        s2.setValue("S2");
503
        Identifier p1 = new Identifier();
504
        p1.setValue("P1");
505
        Identifier p2 = new Identifier();
506
        p2.setValue("P2");
507
        Identifier p3 = new Identifier();
508
        p3.setValue("P3");
509
        Identifier p4 = new Identifier();
510
        p4.setValue("P4");
511
       
512
        
513
        SystemMetadata p1Sys = new SystemMetadata();
514
        p1Sys.setIdentifier(p1);
515
        p1Sys.setSeriesId(s1);
516
        p1Sys.setObsoletedBy(p2);
517
        p1Sys.setDateUploaded(new Date(100));
518
        
519
        SystemMetadata p2Sys = new SystemMetadata();
520
        p2Sys.setIdentifier(p2);
521
        p2Sys.setSeriesId(s1);
522
        p2Sys.setObsoletes(p1);
523
        p2Sys.setDateUploaded(new Date(200));
524
        
525
        
526
        SystemMetadata p4Sys = new SystemMetadata();
527
        p4Sys.setIdentifier(p4);
528
        p4Sys.setSeriesId(s1);
529
        p4Sys.setObsoletes(p3);
530
        p4Sys.setDateUploaded(new Date(400));
531

    
532
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
533
        chain.add(p1Sys);
534
        chain.add(p2Sys);
535
        chain.add(p4Sys);
536
      
537
        System.out.println("Case 9:");
538
        Identifier head = getHeadVersion(s1, chain);
539
        //System.out.println("The head is "+head.getValue());
540
        assertTrue(head.equals(p4));
541
    }
542
    
543
    /**
544
     * case 10: P1(S1) <-> P2(S1) ->  XX  <- P4(S1), S1 = P4, (Rule 1) (XX: object P3 was deleted)
545
     */
546
    private void testCase10() throws Exception {
547
        Identifier s1 = new Identifier();
548
        s1.setValue("S1");
549
        Identifier s2 = new Identifier();
550
        s2.setValue("S2");
551
        Identifier p1 = new Identifier();
552
        p1.setValue("P1");
553
        Identifier p2 = new Identifier();
554
        p2.setValue("P2");
555
        Identifier p3 = new Identifier();
556
        p3.setValue("P3");
557
        Identifier p4 = new Identifier();
558
        p4.setValue("P4");
559
       
560
        
561
        SystemMetadata p1Sys = new SystemMetadata();
562
        p1Sys.setIdentifier(p1);
563
        p1Sys.setSeriesId(s1);
564
        p1Sys.setObsoletedBy(p2);
565
        p1Sys.setDateUploaded(new Date(100));
566
        
567
        SystemMetadata p2Sys = new SystemMetadata();
568
        p2Sys.setIdentifier(p2);
569
        p2Sys.setSeriesId(s1);
570
        p2Sys.setObsoletes(p1);
571
        p2Sys.setObsoletedBy(p3);
572
        p2Sys.setDateUploaded(new Date(200));
573
        
574
        
575
        SystemMetadata p4Sys = new SystemMetadata();
576
        p4Sys.setIdentifier(p4);
577
        p4Sys.setSeriesId(s1);
578
        p4Sys.setObsoletes(p3);
579
        p4Sys.setDateUploaded(new Date(400));
580

    
581
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
582
        chain.add(p1Sys);
583
        chain.add(p2Sys);
584
        chain.add(p4Sys);
585
      
586
        System.out.println("Case 10:");
587
        Identifier head = getHeadVersion(s1, chain);
588
        //System.out.println("The head is "+head.getValue());
589
        assertTrue(head.equals(p4));
590
    }
591
    
592
    /**
593
     * case 11: P1(S1) <-> P2(S1) <-> [archived:P3(S1)], S1 = P3, (Rule 1) 
594
     */
595
    private void testCase11() throws Exception {
596
        Identifier s1 = new Identifier();
597
        s1.setValue("S1");
598
        Identifier s2 = new Identifier();
599
        s2.setValue("S2");
600
        Identifier p1 = new Identifier();
601
        p1.setValue("P1");
602
        Identifier p2 = new Identifier();
603
        p2.setValue("P2");
604
        Identifier p3 = new Identifier();
605
        p3.setValue("P3");
606
        Identifier p4 = new Identifier();
607
        p4.setValue("P4");
608
       
609
        
610
        SystemMetadata p1Sys = new SystemMetadata();
611
        p1Sys.setIdentifier(p1);
612
        p1Sys.setSeriesId(s1);
613
        p1Sys.setObsoletedBy(p2);
614
        p1Sys.setDateUploaded(new Date(100));
615
        
616
        SystemMetadata p2Sys = new SystemMetadata();
617
        p2Sys.setIdentifier(p2);
618
        p2Sys.setSeriesId(s1);
619
        p2Sys.setObsoletes(p1);
620
        p2Sys.setObsoletedBy(p3);
621
        p2Sys.setDateUploaded(new Date(200));
622
        
623
        
624
        SystemMetadata p3Sys = new SystemMetadata();
625
        p3Sys.setIdentifier(p3);
626
        p3Sys.setSeriesId(s1);
627
        p3Sys.setObsoletes(p2);
628
        p3Sys.setArchived(true);
629
        p3Sys.setDateUploaded(new Date(300));
630
        
631

    
632
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
633
        chain.add(p1Sys);
634
        chain.add(p2Sys);
635
        chain.add(p3Sys);
636
      
637
        System.out.println("Case 11:");
638
        Identifier head = getHeadVersion(s1, chain);
639
        //System.out.println("The head is "+head.getValue());
640
        assertTrue(head.equals(p3));
641
    }
642
    
643
    /**
644
     * case 12. P1(S1) <-> P2(S1) -> ??, S1 = P2, (Rule 4) (Error, but will happen)
645
     * @throws Exception
646
     */
647
    private void testCase12() throws Exception {
648
        Identifier s1 = new Identifier();
649
        s1.setValue("S1");
650
        Identifier s2 = new Identifier();
651
        s2.setValue("S2");
652
        Identifier p1 = new Identifier();
653
        p1.setValue("P1");
654
        Identifier p2 = new Identifier();
655
        p2.setValue("P2");
656
        Identifier p3 = new Identifier();
657
        p3.setValue("P3");
658
        
659
        SystemMetadata p1Sys = new SystemMetadata();
660
        p1Sys.setIdentifier(p1);
661
        p1Sys.setSeriesId(s1);
662
        p1Sys.setObsoletedBy(p2);
663
        p1Sys.setDateUploaded(new Date(100));
664
        
665
        SystemMetadata p2Sys = new SystemMetadata();
666
        p2Sys.setIdentifier(p2);
667
        p2Sys.setSeriesId(s1);
668
        p2Sys.setObsoletes(p1);
669
        p2Sys.setObsoletedBy(p3);
670
        p2Sys.setDateUploaded(new Date(200));
671
        
672

    
673
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
674
        chain.add(p1Sys);
675
        chain.add(p2Sys);
676

    
677
        System.out.println("Case 12:");
678
        Identifier head = getHeadVersion(s1, chain);
679
        //System.out.println("The head is "+head.getValue());
680
        assertTrue(head.equals(p2));
681
    }
682
    
683
    /**
684
     * case 13. P1(S1) <- P2(S1) -> ??, S1 = P2
685
     * @throws Exception
686
     */
687
    private void testCase13() throws Exception {
688
        Identifier s1 = new Identifier();
689
        s1.setValue("S1");
690
        Identifier s2 = new Identifier();
691
        s2.setValue("S2");
692
        Identifier p1 = new Identifier();
693
        p1.setValue("P1");
694
        Identifier p2 = new Identifier();
695
        p2.setValue("P2");
696
        Identifier p3 = new Identifier();
697
        p3.setValue("P3");
698
        
699
        SystemMetadata p1Sys = new SystemMetadata();
700
        p1Sys.setIdentifier(p1);
701
        p1Sys.setSeriesId(s1);
702
        p1Sys.setDateUploaded(new Date(100));
703
        
704
        SystemMetadata p2Sys = new SystemMetadata();
705
        p2Sys.setIdentifier(p2);
706
        p2Sys.setSeriesId(s1);
707
        p2Sys.setObsoletes(p1);
708
        p2Sys.setObsoletedBy(p3);
709
        p2Sys.setDateUploaded(new Date(200));
710
        
711

    
712
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
713
        chain.add(p1Sys);
714
        chain.add(p2Sys);
715
      
716
        
717
        System.out.println("Case 13:");
718
        Identifier head = getHeadVersion(s1, chain);
719
        //System.out.println("The head is "+head.getValue());
720
        assertTrue(head.equals(p2));
721
    }
722
	
723
	/**
724
	 * Case 14: P1(S1) <- P2(S1) -> P3(S2).
725
	 * It has a missing obsoletedBy fields, we use the uploadedDate field.S1 = P2
726
	 * @throws Exception
727
	 */
728
	private void testCase14() throws Exception {
729
	    Identifier s1 = new Identifier();
730
	    s1.setValue("S1");
731
	    Identifier s2 = new Identifier();
732
        s2.setValue("S2");
733
	    Identifier p1 = new Identifier();
734
	    p1.setValue("P1");
735
	    Identifier p2 = new Identifier();
736
        p2.setValue("P2");
737
        Identifier p3 = new Identifier();
738
        p3.setValue("P3");
739
	    
740
        SystemMetadata p1Sys = new SystemMetadata();
741
	    p1Sys.setIdentifier(p1);
742
	    p1Sys.setSeriesId(s1);
743
	    p1Sys.setDateUploaded(new Date(100));
744
	    
745
	    SystemMetadata p2Sys = new SystemMetadata();
746
        p2Sys.setIdentifier(p2);
747
        p2Sys.setSeriesId(s1);
748
        p2Sys.setObsoletes(p1);
749
        p2Sys.setObsoletedBy(p3);
750
        p2Sys.setDateUploaded(new Date(200));
751
        
752
        SystemMetadata p3Sys = new SystemMetadata();
753
        p3Sys.setIdentifier(p3);
754
        p3Sys.setSeriesId(s2);
755
        p3Sys.setDateUploaded(new Date(300));
756
        
757
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
758
        chain.add(p1Sys);
759
        chain.add(p2Sys);
760
        chain.add(p3Sys);
761
        
762
        System.out.println("Case 14:");
763
        Identifier head = getHeadVersion(s1, chain);
764
        //System.out.println("The head is "+head.getValue());
765
        assertTrue(head.equals(p2));
766
	}
767
	
768
	/**
769
     * case 15. P1(S1) <-> P2(S1)  ?? <- P4(S1) <-> P5(S2), S1 = P4 (Rule 1) 
770
     * @throws Exception
771
     */
772
    private void testCase15() throws Exception {
773
        Identifier s1 = new Identifier();
774
        s1.setValue("S1");
775
        Identifier s2 = new Identifier();
776
        s2.setValue("S2");
777
        Identifier p1 = new Identifier();
778
        p1.setValue("P1");
779
        Identifier p2 = new Identifier();
780
        p2.setValue("P2");
781
        Identifier p3 = new Identifier();
782
        p3.setValue("P3");
783
        Identifier p4 = new Identifier();
784
        p4.setValue("P4");
785
        Identifier p5 = new Identifier();
786
        p5.setValue("P5");
787
        
788
        SystemMetadata p1Sys = new SystemMetadata();
789
        p1Sys.setIdentifier(p1);
790
        p1Sys.setSeriesId(s1);
791
        p1Sys.setObsoletedBy(p2);
792
        p1Sys.setDateUploaded(new Date(100));
793
        
794
        SystemMetadata p2Sys = new SystemMetadata();
795
        p2Sys.setIdentifier(p2);
796
        p2Sys.setSeriesId(s1);
797
        p2Sys.setObsoletes(p1);
798
        p2Sys.setDateUploaded(new Date(200));
799
        
800
        SystemMetadata p4Sys = new SystemMetadata();
801
        p4Sys.setIdentifier(p4);
802
        p4Sys.setSeriesId(s1);
803
        p4Sys.setObsoletes(p3);
804
        p4Sys.setObsoletedBy(p5);
805
        p4Sys.setDateUploaded(new Date(400));
806
        
807
        SystemMetadata p5Sys = new SystemMetadata();
808
        p5Sys.setIdentifier(p5);
809
        p5Sys.setSeriesId(s2);
810
        p5Sys.setObsoletes(p4);
811
        p5Sys.setDateUploaded(new Date(500));
812
        
813
        
814
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
815
        chain.add(p1Sys);
816
        chain.add(p2Sys);
817
        chain.add(p4Sys);
818
        chain.add(p5Sys);
819
        
820
        System.out.println("Case 15:");
821
        Identifier head = getHeadVersion(s1, chain);
822
        //System.out.println("The head is "+head.getValue());
823
        assertTrue(head.equals(p4));
824
    }
825
    
826
    /**
827
     * case 16. P1(S1) <- P2(S1) -> ?? <-P4(S2) S1 = P2 (two ends, not an ideal chain), S2=P4 (rule1)
828
     * @throws Exception
829
     */
830
    private void testCase16() throws Exception {
831
        Identifier s1 = new Identifier();
832
        s1.setValue("S1");
833
        Identifier s2 = new Identifier();
834
        s2.setValue("S2");
835
        Identifier p1 = new Identifier();
836
        p1.setValue("P1");
837
        Identifier p2 = new Identifier();
838
        p2.setValue("P2");
839
        Identifier p3 = new Identifier();
840
        p3.setValue("P3");
841
        Identifier p4 = new Identifier();
842
        p4.setValue("P4");
843
       
844
        
845
        SystemMetadata p1Sys = new SystemMetadata();
846
        p1Sys.setIdentifier(p1);
847
        p1Sys.setSeriesId(s1);
848
        //p1Sys.setObsoletedBy(p2);
849
        p1Sys.setDateUploaded(new Date(100));
850
        
851
        SystemMetadata p2Sys = new SystemMetadata();
852
        p2Sys.setIdentifier(p2);
853
        p2Sys.setSeriesId(s1);
854
        p2Sys.setObsoletes(p1);
855
        p2Sys.setObsoletedBy(p3);
856
        p2Sys.setDateUploaded(new Date(200));
857
        
858
        SystemMetadata p4Sys = new SystemMetadata();
859
        p4Sys.setIdentifier(p4);
860
        p4Sys.setSeriesId(s2);
861
        p4Sys.setObsoletes(p3);
862
        p4Sys.setDateUploaded(new Date(400));
863
        
864
 
865
        
866
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
867
        chain.add(p1Sys);
868
        chain.add(p2Sys);
869
        chain.add(p4Sys);
870
        
871
        
872
        System.out.println("Case 16:");
873
        Identifier head = getHeadVersion(s1, chain);
874
        //System.out.println("The head is "+head.getValue());
875
        assertTrue(head.equals(p2));
876
        Identifier head2 = getHeadVersion(s2, chain);
877
        //System.out.println("The head is "+head.getValue());
878
        assertTrue(head2.equals(p4));
879
    }
880
    
881
    /**
882
     * case 17. P1(S1) <- P2(S1) -> ?? <-P4(S1) S1 = P4 (P1 and P4 are two ends, not an ideal chain)
883
     * @throws Exception
884
     */
885
    private void testCase17() throws Exception {
886
        Identifier s1 = new Identifier();
887
        s1.setValue("S1");
888
        Identifier s2 = new Identifier();
889
        s2.setValue("S2");
890
        Identifier p1 = new Identifier();
891
        p1.setValue("P1");
892
        Identifier p2 = new Identifier();
893
        p2.setValue("P2");
894
        Identifier p3 = new Identifier();
895
        p3.setValue("P3");
896
        Identifier p4 = new Identifier();
897
        p4.setValue("P4");
898
       
899
        
900
        SystemMetadata p1Sys = new SystemMetadata();
901
        p1Sys.setIdentifier(p1);
902
        p1Sys.setSeriesId(s1);
903
        //p1Sys.setObsoletedBy(p2);
904
        p1Sys.setDateUploaded(new Date(100));
905
        
906
        SystemMetadata p2Sys = new SystemMetadata();
907
        p2Sys.setIdentifier(p2);
908
        p2Sys.setSeriesId(s1);
909
        p2Sys.setObsoletes(p1);
910
        p2Sys.setObsoletedBy(p3);
911
        p2Sys.setDateUploaded(new Date(200));
912
        
913
        SystemMetadata p4Sys = new SystemMetadata();
914
        p4Sys.setIdentifier(p4);
915
        p4Sys.setSeriesId(s1);
916
        p4Sys.setObsoletes(p3);
917
        p4Sys.setDateUploaded(new Date(400));
918
        
919
 
920
        
921
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
922
        chain.add(p1Sys);
923
        chain.add(p2Sys);
924
        chain.add(p4Sys);
925
        
926
        
927
        System.out.println("Case 17:");
928
        Identifier head = getHeadVersion(s1, chain);
929
        //System.out.println("The head is "+head.getValue());
930
        assertTrue(head.equals(p4));
931
      
932
    }
933
	
934
	
935
	/*
936
	 * completed the obsoletes and obsoletedBy information for the given pid. 
937
	 * We will look up the information from the given chain if its obsoletes or obsoletedBy field is missing.
938
	 */
939
	private void decorateSystemMetadata(SystemMetadata targetSysmeta, Vector<SystemMetadata> chain) {
940
	    if(targetSysmeta != null) {
941
	        if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() == null) {
942
	            Identifier obsoletes = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETES, chain);
943
	            if(obsoletes != null) {
944
	                targetSysmeta.setObsoletedBy(obsoletes);
945
	            }
946
	            Identifier obsoleted = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain);
947
	            if(obsoleted != null) {
948
	                targetSysmeta.setObsoletes(obsoleted);
949
	            }
950
	        } else if (targetSysmeta.getObsoletes() != null && targetSysmeta.getObsoletedBy() == null) {
951
	            Identifier obsoleted = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain);
952
                if(obsoleted != null) {
953
                    targetSysmeta.setObsoletes(obsoleted);
954
                }
955
	            
956
	        } else if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() != null) {
957
	            Identifier obsoletes = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETES, chain);
958
                if(obsoletes != null) {
959
                    targetSysmeta.setObsoletedBy(obsoletes);
960
                }
961
            }
962
	    }
963
	}
964
	
965
	/*
966
	 * Get the identifier in chain which obsoleted or obsoletedBy the target id.
967
	 */
968
	private Identifier getRelatedIdentifier(Identifier target, String keyword, Vector<SystemMetadata> chain) {
969
	    Identifier identifier = null;
970
	    if(keyword.equals(OBSOLETES)) {
971
	        for(SystemMetadata sysmeta :chain) {
972
	            Identifier obsoletes = sysmeta.getObsoletes();
973
	            if(obsoletes != null && obsoletes.equals(target)) {
974
	                identifier = sysmeta.getIdentifier();
975
	            }
976
	        }
977
	    } else if(keyword.equals(OBSOLETEDBY)) {
978
	        for(SystemMetadata sysmeta :chain) {
979
	            Identifier obsoletedBy = sysmeta.getObsoletedBy();
980
	            if(obsoletedBy != null && obsoletedBy.equals(target)) {
981
	                identifier = sysmeta.getIdentifier();
982
	            }
983
	        }
984
	        
985
	    }
986
	    return identifier;
987
	}
988
	
989
	
990
	/*
991
	 * Decide if a system metadata object missing a obsoletes or obsoletedBy fields:
992
	 * 1. The system metadata object has both "oboletes" and "obsoletedBy" fields.
993
     * 2. If a system metadata object misses "oboletes" field, another system metadata object whose "obsoletedBy" fields points to the identifier doesn't exist.
994
    *  3. If a system metadata object misses "oboletedBy" field, another system metadata object whose "obsoletes" fields points to the identifier doesn't exist.
995
	 */
996
	private boolean hasMissingObsolescenceFields(SystemMetadata targetSysmeta, Vector<SystemMetadata> chain) {
997
	    boolean has = false;
998
	    if(targetSysmeta != null) {
999
            if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() == null) {
1000
                if(foundIdentifierInAnotherSystemMetadata(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain)) {
1001
                    has = true;
1002
                } else {
1003
                    if(foundIdentifierInAnotherSystemMetadata(targetSysmeta.getIdentifier(), OBSOLETES, chain)) {
1004
                        has = true;
1005
                    }
1006
                }
1007
                
1008
            } else if (targetSysmeta.getObsoletes() != null && targetSysmeta.getObsoletedBy() == null) {
1009
                if(foundIdentifierInAnotherSystemMetadata(targetSysmeta.getIdentifier(), OBSOLETES, chain)) {
1010
                    has = true;
1011
                }
1012
                
1013
            } else if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() != null) {
1014
                if(foundIdentifierInAnotherSystemMetadata(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain)) {
1015
                    has = true;
1016
                }
1017
            }
1018
        }
1019
	    return has;
1020
	}
1021
	
1022
	/**
1023
	 * Determine if the sepcified identifier exists in the sepcified field in another system metadata object.
1024
	 * @param target
1025
	 * @param fieldName
1026
	 * @param chain
1027
	 * @return true if we found it; false otherwise.
1028
	 */
1029
	private boolean foundIdentifierInAnotherSystemMetadata(Identifier target, String fieldName, Vector<SystemMetadata> chain) {
1030
	    boolean found = false;
1031
	    if(fieldName.equals(OBSOLETES)) {
1032
            for(SystemMetadata sysmeta :chain) {
1033
                Identifier obsoletes = sysmeta.getObsoletes();
1034
                if(obsoletes != null && obsoletes.equals(target)) {
1035
                    System.out.println("missing obsoletedBy");
1036
                    found = true;
1037
                }
1038
            }
1039
        } else if(fieldName.equals(OBSOLETEDBY)) {
1040
            for(SystemMetadata sysmeta :chain) {
1041
                Identifier obsoletedBy = sysmeta.getObsoletedBy();
1042
                if(obsoletedBy != null && obsoletedBy.equals(target)) {
1043
                    System.out.println("missing obsoletes");
1044
                    found = true;
1045
                }
1046
            }
1047
            
1048
        }
1049
	    return found;
1050
	}
1051
	
1052
	/**
1053
	 * Get the head version of the chain
1054
	 * @param sid
1055
	 * @return
1056
	 */
1057
	/*public Identifier getHeadVersion(Identifier sid, Vector<SystemMetadata> chain) {
1058
	    Identifier pid = null;
1059
	    Vector<SystemMetadata> sidChain = new Vector<SystemMetadata>();
1060
	    int noObsoletedByCount =0;
1061
	    boolean hasMissingObsolescenceFields = false;
1062
	    if(chain != null) {
1063
	        for(SystemMetadata sysmeta : chain) {
1064
	            if(sysmeta.getSeriesId() != null && sysmeta.getSeriesId().equals(sid)) {
1065
	                //decorateSystemMetadata(sysmeta, chain);
1066
	                System.out.println("identifier "+sysmeta.getIdentifier().getValue()+" :");
1067
	                if(sysmeta.getObsoletes() == null) {
1068
	                    System.out.println("obsolets "+sysmeta.getObsoletes());
1069
	                } else {
1070
	                    System.out.println("obsolets "+sysmeta.getObsoletes().getValue());
1071
	                }
1072
	                if(sysmeta.getObsoletedBy() == null) {
1073
	                    System.out.println("obsoletedBy "+sysmeta.getObsoletedBy());
1074
	                } else {
1075
	                    System.out.println("obsoletedBy "+sysmeta.getObsoletedBy().getValue());
1076
	                }
1077
	                if(!hasMissingObsolescenceFields) {
1078
	                    if(hasMissingObsolescenceFields(sysmeta, chain)) {
1079
	                        hasMissingObsolescenceFields = true;
1080
	                    }
1081
	                }
1082
	                
1083
	                if(sysmeta.getObsoletedBy() == null) {
1084
	                    pid = sysmeta.getIdentifier();
1085
	                    noObsoletedByCount++;
1086
	                }
1087
	                sidChain.add(sysmeta);
1088
	            }
1089
	        }
1090
	    }
1091
	    
1092
	    if(hasMissingObsolescenceFields) {
1093
	        System.out.println("It has an object whose system metadata has a missing obsoletes or obsoletedBy field.");
1094
	        Collections.sort(sidChain, new SystemMetadataDateUploadedComparator());
1095
            pid =sidChain.lastElement().getIdentifier();
1096
	    } else {
1097
	        if(noObsoletedByCount == 1) {
1098
	            //rule 1 . If there is only one object having NULL value in the chain, return the value
1099
	             System.out.println("rule 1");
1100
	             return pid;
1101
	         } else if (noObsoletedByCount > 1 ) {
1102
	             // rule 2. If there is more than one object having NULL value in the chain, return last dateUploaded
1103
	             System.out.println("rule 2");
1104
	             Collections.sort(sidChain, new SystemMetadataDateUploadedComparator());
1105
	             pid =sidChain.lastElement().getIdentifier();
1106
	             
1107
	         } else if (noObsoletedByCount == 0) {
1108
	             // all pids were obsoleted
1109
	             for(SystemMetadata sysmeta : sidChain) {
1110
	                 //System.out.println("=== the pid in system metadata "+sysmeta.getIdentifier().getValue());
1111
	                 Identifier obsoletedBy = sysmeta.getObsoletedBy();
1112
	                 SystemMetadata sysOfObsoletedBy = getSystemMetadata(obsoletedBy, chain);
1113
	                 if(sysOfObsoletedBy == null) {
1114
	                     //Rule 4 We have a obsoletedBy id without system metadata. So we can't decide if a different sid exists. we have to sort it.
1115
	                     System.out.println("rule 4");
1116
	                     Collections.sort(sidChain, new SystemMetadataDateUploadedComparator());
1117
	                     pid = sidChain.lastElement().getIdentifier();
1118
	                     break;
1119
	                 } else {
1120
	                     Identifier sidOfObsoletedBy = sysOfObsoletedBy.getSeriesId();
1121
	                     if(sidOfObsoletedBy != null && !sidOfObsoletedBy.equals(sid)) {
1122
	                         //rule 3, if everything in {S1} is obsoleted, then select object that is obsoleted by another object that does not have the same SID
1123
	                         System.out.println("rule 3-1 (close with another sid "+sidOfObsoletedBy.getValue()+")");
1124
	                         pid = sysmeta.getIdentifier();
1125
	                         break;
1126
	                     } else if (sidOfObsoletedBy == null ) {
1127
	                         //rule 3, If everything in {S1} is obsoleted, then select object that is obsoleted by another object that does not have the same SID (this case, no sid)
1128
	                         System.out.println("rule 3-2 (close without sid)");
1129
	                         pid = sysmeta.getIdentifier();
1130
	                         break;
1131
	                     }
1132
	                 }
1133
	                 
1134
	             }
1135
	         }
1136
	    }
1137
	    
1138
	    return pid;
1139
	}*/
1140
	
1141
	
1142
	private SystemMetadata getSystemMetadata(Identifier id, Vector<SystemMetadata> chain ){
1143
	    SystemMetadata sysmeta = null;
1144
	    if(id != null) {
1145
	        for(SystemMetadata sys : chain) {
1146
	            if(sys.getIdentifier().equals(id)) {
1147
	                sysmeta = sys;
1148
	                break;
1149
	            }
1150
	        }
1151
	    }
1152
	    return sysmeta;
1153
	}
1154
	
1155
	/**
1156
     * Get the head version of the chain
1157
     * @param sid
1158
     * @return
1159
     */
1160
    public Identifier getHeadVersion(Identifier sid, Vector<SystemMetadata> chain) {
1161
        Identifier pid = null;
1162
        Vector<SystemMetadata> sidChain = new Vector<SystemMetadata>();
1163
        int endCounter =0 ;
1164
        String status = null;
1165
        if(chain != null) {
1166
            for(SystemMetadata sysmeta : chain) {
1167
                if(sysmeta.getSeriesId() != null && sysmeta.getSeriesId().equals(sid)) {
1168
                    status = endStatus(sysmeta, chain);
1169
                    if(status.equals(END1) || status.equals(END2)) {
1170
                        endCounter ++;
1171
                        pid = sysmeta.getIdentifier();
1172
                    }
1173
                    sidChain.add(sysmeta);
1174
                }
1175
            }
1176
            if(endCounter != 1) {
1177
                System.out.println("The chain has "+endCounter+" ends and it is not an ideal chain.");
1178
                Collections.sort(sidChain, new SystemMetadataDateUploadedComparator());
1179
                pid =sidChain.lastElement().getIdentifier();
1180
            } else {
1181
                System.out.println(""+status);
1182
            }
1183
        }
1184
        return pid;
1185
    }
1186
	
1187
	
1188
    /*
1189
     * Rules for ends:
1190
     *  Rule 1. An object in the SID chain doesn't have the "obsoletedBy" field.
1191
     *  Rule 2. An object in the SID chain does have the "obsoletedBy" filed, but the "obsoletedBy" value has different the SID value (including no SID value).
1192
     *  It is tricky if the object in the "obsoletedBy" filed is missing since we don't have the knowledge of its series id. Generally we consider it an end except: 
1193
     *  if there is another object in the chain (has the same series id) obsoletes the missing object, the missing object is not an end.
1194
     */
1195
    private String endStatus(SystemMetadata targetSysmeta, Vector<SystemMetadata> chain) {
1196
        String status = END2;
1197
        if(targetSysmeta.getObsoletedBy() == null) {
1198
            status = END1;
1199
        } else {
1200
            Identifier orgSid = targetSysmeta.getSeriesId();
1201
            Identifier obsoletedBy = targetSysmeta.getObsoletedBy();
1202
            SystemMetadata obsoletedBySys = getSystemMetadata(obsoletedBy, chain);
1203
            if(obsoletedBySys != null) {
1204
                if(obsoletedBySys.getSeriesId() != null && obsoletedBySys.getSeriesId().equals(orgSid)) {
1205
                    status = NOTEND;
1206
                }
1207
            } else {
1208
                // the obsoletedBy doesn't exist
1209
                for(SystemMetadata sys : chain) {
1210
                    if(sys.getSeriesId() != null && sys.getSeriesId().equals(orgSid)) {
1211
                        if(sys.getObsoletes() != null && sys.getObsoletes().equals(obsoletedBy)) {
1212
                            status = NOTEND;
1213
                        }
1214
                    }
1215
                }
1216
            }
1217
        }
1218
        return status;
1219
    }
1220
    
1221
    private static final String END1 = "Rule 1";
1222
    private static final String END2 = "Rule 2";
1223
    private static final String NOTEND = "Not an end";
1224
}
(7-7/8)