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
	}
137
	
138
	/**
139
	 * case 1. P1(S1) <-> P2(S1),  S1 = P2 (Rule 1)
140
	 */
141
	private void testCase1() throws Exception {
142
	    Identifier s1 = new Identifier();
143
        s1.setValue("S1");
144
        Identifier s2 = new Identifier();
145
        s2.setValue("S2");
146
        Identifier p1 = new Identifier();
147
        p1.setValue("P1");
148
        Identifier p2 = new Identifier();
149
        p2.setValue("P2");
150
       
151
        SystemMetadata p1Sys = new SystemMetadata();
152
        p1Sys.setIdentifier(p1);
153
        p1Sys.setSeriesId(s1);
154
        p1Sys.setObsoletedBy(p2);
155
        p1Sys.setDateUploaded(new Date(100));
156
        
157
        SystemMetadata p2Sys = new SystemMetadata();
158
        p2Sys.setIdentifier(p2);
159
        p2Sys.setSeriesId(s1);
160
        p2Sys.setObsoletes(p1);
161
        p2Sys.setDateUploaded(new Date(200));
162
        
163
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
164
        chain.add(p1Sys);
165
        chain.add(p2Sys);
166
      
167
        System.out.println("Case 1:");
168
        Identifier head = getHeadVersion(s1, chain);
169
        //System.out.println("The head is "+head.getValue());
170
        assertTrue(head.equals(p2));
171
	}
172
	
173
	
174
	/**
175
     * Case 2. P1(S1) ? P2(S1), S1 = P2, Error condition, P2 not allowed (should not exist) (Rule 2)
176
     */
177
    private void testCase2() throws Exception {
178
        Identifier s1 = new Identifier();
179
        s1.setValue("S1");
180
        Identifier s2 = new Identifier();
181
        s2.setValue("S2");
182
        Identifier p1 = new Identifier();
183
        p1.setValue("P1");
184
        Identifier p2 = new Identifier();
185
        p2.setValue("P2");
186
       
187
        
188
        SystemMetadata p1Sys = new SystemMetadata();
189
        p1Sys.setIdentifier(p1);
190
        p1Sys.setSeriesId(s1);
191
        p1Sys.setDateUploaded(new Date(100));
192
        
193
        SystemMetadata p2Sys = new SystemMetadata();
194
        p2Sys.setIdentifier(p2);
195
        p2Sys.setSeriesId(s1);
196
        p2Sys.setDateUploaded(new Date(200));
197
        
198
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
199
        chain.add(p1Sys);
200
        chain.add(p2Sys);
201
      
202
        System.out.println("Case 2:");
203
        Identifier head = getHeadVersion(s1, chain);
204
        //System.out.println("The head is "+head.getValue());
205
        assertTrue(head.equals(p2));
206
    }
207
    
208
    /**
209
     * case 3. P1(S1) <- P2(S1), S1 = P2, Discouraged, but not error condition, S1 = P2 (Rule 2, missingFields)
210
     */
211
    private void testCase3() throws Exception {
212
        Identifier s1 = new Identifier();
213
        s1.setValue("S1");
214
        Identifier s2 = new Identifier();
215
        s2.setValue("S2");
216
        Identifier p1 = new Identifier();
217
        p1.setValue("P1");
218
        Identifier p2 = new Identifier();
219
        p2.setValue("P2");
220
       
221
        
222
        SystemMetadata p1Sys = new SystemMetadata();
223
        p1Sys.setIdentifier(p1);
224
        p1Sys.setSeriesId(s1);
225
        p1Sys.setDateUploaded(new Date(100));
226
        
227
        SystemMetadata p2Sys = new SystemMetadata();
228
        p2Sys.setIdentifier(p2);
229
        p2Sys.setSeriesId(s1);
230
        p2Sys.setObsoletes(p1);
231
        p2Sys.setDateUploaded(new Date(200));
232
        
233
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
234
        chain.add(p1Sys);
235
        chain.add(p2Sys);
236
      
237
        System.out.println("Case 3:");
238
        Identifier head = getHeadVersion(s1, chain);
239
        //System.out.println("The head is "+head.getValue());
240
        assertTrue(head.equals(p2));
241
    }
242
    
243
    /**
244
     * case 4. P1(S1) <-> P2(S1) <-> P3(S2), S1 = P2(use Rule 3), S2 = P3 (use Rule 1)
245
     */
246
    private void testCase4() throws Exception {
247
        Identifier s1 = new Identifier();
248
        s1.setValue("S1");
249
        Identifier s2 = new Identifier();
250
        s2.setValue("S2");
251
        Identifier p1 = new Identifier();
252
        p1.setValue("P1");
253
        Identifier p2 = new Identifier();
254
        p2.setValue("P2");
255
        Identifier p3 = new Identifier();
256
        p3.setValue("P3");
257
       
258
        
259
        SystemMetadata p1Sys = new SystemMetadata();
260
        p1Sys.setIdentifier(p1);
261
        p1Sys.setSeriesId(s1);
262
        p1Sys.setObsoletedBy(p2);
263
        p1Sys.setDateUploaded(new Date(100));
264
        
265
        SystemMetadata p2Sys = new SystemMetadata();
266
        p2Sys.setIdentifier(p2);
267
        p2Sys.setSeriesId(s1);
268
        p2Sys.setObsoletes(p1);
269
        p2Sys.setObsoletedBy(p3);
270
        p2Sys.setDateUploaded(new Date(200));
271
        
272
        SystemMetadata p3Sys = new SystemMetadata();
273
        p3Sys.setIdentifier(p3);
274
        p3Sys.setSeriesId(s2);
275
        p3Sys.setObsoletes(p2);
276

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

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

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

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

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

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

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

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

    
665
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
666
        chain.add(p1Sys);
667
        chain.add(p2Sys);
668

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

    
704
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
705
        chain.add(p1Sys);
706
        chain.add(p2Sys);
707
      
708
        
709
        System.out.println("Case 13:");
710
        Identifier head = getHeadVersion(s1, chain);
711
        //System.out.println("The head is "+head.getValue());
712
        assertTrue(head.equals(p2));
713
    }
714
	
715
	/**
716
	 * Case 14: P1(S1) <- P2(S1) -> P3(S2).
717
	 * It has a missing obsoletedBy fields, we use the uploadedDate field.S1 = P2
718
	 * @throws Exception
719
	 */
720
	private void testCase14() throws Exception {
721
	    Identifier s1 = new Identifier();
722
	    s1.setValue("S1");
723
	    Identifier s2 = new Identifier();
724
        s2.setValue("S2");
725
	    Identifier p1 = new Identifier();
726
	    p1.setValue("P1");
727
	    Identifier p2 = new Identifier();
728
        p2.setValue("P2");
729
        Identifier p3 = new Identifier();
730
        p3.setValue("P3");
731
	    
732
        SystemMetadata p1Sys = new SystemMetadata();
733
	    p1Sys.setIdentifier(p1);
734
	    p1Sys.setSeriesId(s1);
735
	    p1Sys.setDateUploaded(new Date(100));
736
	    
737
	    SystemMetadata p2Sys = new SystemMetadata();
738
        p2Sys.setIdentifier(p2);
739
        p2Sys.setSeriesId(s1);
740
        p2Sys.setObsoletes(p1);
741
        p2Sys.setObsoletedBy(p3);
742
        p2Sys.setDateUploaded(new Date(200));
743
        
744
        SystemMetadata p3Sys = new SystemMetadata();
745
        p3Sys.setIdentifier(p3);
746
        p3Sys.setSeriesId(s2);
747
        
748
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
749
        chain.add(p1Sys);
750
        chain.add(p2Sys);
751
        chain.add(p3Sys);
752
        
753
        System.out.println("Case 14:");
754
        Identifier head = getHeadVersion(s1, chain);
755
        //System.out.println("The head is "+head.getValue());
756
        assertTrue(head.equals(p2));
757
	}
758
	
759
	/**
760
     * case 15. P1(S1) <-> P2(S1)  ?? <- P4(S1) <-> P5(S2), S1 = P2 (Rule 1)  oops!, should be s1=P4
761
     * @throws Exception
762
     */
763
    private void testCase15() throws Exception {
764
        Identifier s1 = new Identifier();
765
        s1.setValue("S1");
766
        Identifier s2 = new Identifier();
767
        s2.setValue("S2");
768
        Identifier p1 = new Identifier();
769
        p1.setValue("P1");
770
        Identifier p2 = new Identifier();
771
        p2.setValue("P2");
772
        Identifier p3 = new Identifier();
773
        p3.setValue("P3");
774
        Identifier p4 = new Identifier();
775
        p4.setValue("P4");
776
        Identifier p5 = new Identifier();
777
        p5.setValue("P5");
778
        
779
        SystemMetadata p1Sys = new SystemMetadata();
780
        p1Sys.setIdentifier(p1);
781
        p1Sys.setSeriesId(s1);
782
        p1Sys.setObsoletedBy(p2);
783
        p1Sys.setDateUploaded(new Date(100));
784
        
785
        SystemMetadata p2Sys = new SystemMetadata();
786
        p2Sys.setIdentifier(p2);
787
        p2Sys.setSeriesId(s1);
788
        p2Sys.setObsoletes(p1);
789
        p2Sys.setDateUploaded(new Date(200));
790
        
791
        SystemMetadata p4Sys = new SystemMetadata();
792
        p4Sys.setIdentifier(p4);
793
        p4Sys.setSeriesId(s1);
794
        p4Sys.setObsoletes(p3);
795
        p4Sys.setObsoletedBy(p5);
796
        
797
        SystemMetadata p5Sys = new SystemMetadata();
798
        p5Sys.setIdentifier(p5);
799
        p5Sys.setSeriesId(s2);
800
        p5Sys.setObsoletes(p4);
801
        
802
        
803
        Vector<SystemMetadata> chain = new Vector<SystemMetadata>();
804
        chain.add(p1Sys);
805
        chain.add(p2Sys);
806
        chain.add(p4Sys);
807
        chain.add(p5Sys);
808
        
809
        System.out.println("Case 15:");
810
        Identifier head = getHeadVersion(s1, chain);
811
        //System.out.println("The head is "+head.getValue());
812
        assertTrue(head.equals(p4));
813
    }
814
	
815
	
816
	/*
817
	 * completed the obsoletes and obsoletedBy information for the given pid. 
818
	 * We will look up the information from the given chain if its obsoletes or obsoletedBy field is missing.
819
	 */
820
	private void decorateSystemMetadata(SystemMetadata targetSysmeta, Vector<SystemMetadata> chain) {
821
	    if(targetSysmeta != null) {
822
	        if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() == null) {
823
	            Identifier obsoletes = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETES, chain);
824
	            if(obsoletes != null) {
825
	                targetSysmeta.setObsoletedBy(obsoletes);
826
	            }
827
	            Identifier obsoleted = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain);
828
	            if(obsoleted != null) {
829
	                targetSysmeta.setObsoletes(obsoleted);
830
	            }
831
	        } else if (targetSysmeta.getObsoletes() != null && targetSysmeta.getObsoletedBy() == null) {
832
	            Identifier obsoleted = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain);
833
                if(obsoleted != null) {
834
                    targetSysmeta.setObsoletes(obsoleted);
835
                }
836
	            
837
	        } else if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() != null) {
838
	            Identifier obsoletes = getRelatedIdentifier(targetSysmeta.getIdentifier(), OBSOLETES, chain);
839
                if(obsoletes != null) {
840
                    targetSysmeta.setObsoletedBy(obsoletes);
841
                }
842
            }
843
	    }
844
	}
845
	
846
	/*
847
	 * Get the identifier in chain which obsoleted or obsoletedBy the target id.
848
	 */
849
	private Identifier getRelatedIdentifier(Identifier target, String keyword, Vector<SystemMetadata> chain) {
850
	    Identifier identifier = null;
851
	    if(keyword.equals(OBSOLETES)) {
852
	        for(SystemMetadata sysmeta :chain) {
853
	            Identifier obsoletes = sysmeta.getObsoletes();
854
	            if(obsoletes != null && obsoletes.equals(target)) {
855
	                identifier = sysmeta.getIdentifier();
856
	            }
857
	        }
858
	    } else if(keyword.equals(OBSOLETEDBY)) {
859
	        for(SystemMetadata sysmeta :chain) {
860
	            Identifier obsoletedBy = sysmeta.getObsoletedBy();
861
	            if(obsoletedBy != null && obsoletedBy.equals(target)) {
862
	                identifier = sysmeta.getIdentifier();
863
	            }
864
	        }
865
	        
866
	    }
867
	    return identifier;
868
	}
869
	
870
	
871
	/*
872
	 * Decide if a system metadata object missing a obsoletes or obsoletedBy fields:
873
	 * 1. The system metadata object has both "oboletes" and "obsoletedBy" fields.
874
     * 2. If a system metadata object misses "oboletes" field, another system metadata object whose "obsoletedBy" fields points to the identifier doesn't exist.
875
    *  3. If a system metadata object misses "oboletedBy" field, another system metadata object whose "obsoletes" fields points to the identifier doesn't exist.
876
	 */
877
	private boolean hasMissingObsolescenceFields(SystemMetadata targetSysmeta, Vector<SystemMetadata> chain) {
878
	    boolean has = false;
879
	    if(targetSysmeta != null) {
880
            if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() == null) {
881
                if(foundIdentifierInAnotherSystemMetadata(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain)) {
882
                    has = true;
883
                } else {
884
                    if(foundIdentifierInAnotherSystemMetadata(targetSysmeta.getIdentifier(), OBSOLETES, chain)) {
885
                        has = true;
886
                    }
887
                }
888
                
889
            } else if (targetSysmeta.getObsoletes() != null && targetSysmeta.getObsoletedBy() == null) {
890
                if(foundIdentifierInAnotherSystemMetadata(targetSysmeta.getIdentifier(), OBSOLETES, chain)) {
891
                    has = true;
892
                }
893
                
894
            } else if (targetSysmeta.getObsoletes() == null && targetSysmeta.getObsoletedBy() != null) {
895
                if(foundIdentifierInAnotherSystemMetadata(targetSysmeta.getIdentifier(), OBSOLETEDBY, chain)) {
896
                    has = true;
897
                }
898
            }
899
        }
900
	    return has;
901
	}
902
	
903
	/**
904
	 * Determine if the sepcified identifier exists in the sepcified field in another system metadata object.
905
	 * @param target
906
	 * @param fieldName
907
	 * @param chain
908
	 * @return true if we found it; false otherwise.
909
	 */
910
	private boolean foundIdentifierInAnotherSystemMetadata(Identifier target, String fieldName, Vector<SystemMetadata> chain) {
911
	    boolean found = false;
912
	    if(fieldName.equals(OBSOLETES)) {
913
            for(SystemMetadata sysmeta :chain) {
914
                Identifier obsoletes = sysmeta.getObsoletes();
915
                if(obsoletes != null && obsoletes.equals(target)) {
916
                    System.out.println("missing obsoletedBy");
917
                    found = true;
918
                }
919
            }
920
        } else if(fieldName.equals(OBSOLETEDBY)) {
921
            for(SystemMetadata sysmeta :chain) {
922
                Identifier obsoletedBy = sysmeta.getObsoletedBy();
923
                if(obsoletedBy != null && obsoletedBy.equals(target)) {
924
                    System.out.println("missing obsoletes");
925
                    found = true;
926
                }
927
            }
928
            
929
        }
930
	    return found;
931
	}
932
	
933
	/**
934
	 * Get the head version of the chain
935
	 * @param sid
936
	 * @return
937
	 */
938
	public Identifier getHeadVersion(Identifier sid, Vector<SystemMetadata> chain) {
939
	    Identifier pid = null;
940
	    Vector<SystemMetadata> sidChain = new Vector<SystemMetadata>();
941
	    int noObsoletedByCount =0;
942
	    boolean hasMissingObsolescenceFields = false;
943
	    if(chain != null) {
944
	        for(SystemMetadata sysmeta : chain) {
945
	            if(sysmeta.getSeriesId() != null && sysmeta.getSeriesId().equals(sid)) {
946
	                //decorateSystemMetadata(sysmeta, chain);
947
	                /*System.out.println("identifier "+sysmeta.getIdentifier().getValue()+" :");
948
	                if(sysmeta.getObsoletes() == null) {
949
	                    System.out.println("obsolets "+sysmeta.getObsoletes());
950
	                } else {
951
	                    System.out.println("obsolets "+sysmeta.getObsoletes().getValue());
952
	                }
953
	                if(sysmeta.getObsoletedBy() == null) {
954
	                    System.out.println("obsoletedBy "+sysmeta.getObsoletedBy());
955
	                } else {
956
	                    System.out.println("obsoletedBy "+sysmeta.getObsoletedBy().getValue());
957
	                }*/
958
	                if(!hasMissingObsolescenceFields) {
959
	                    if(hasMissingObsolescenceFields(sysmeta, chain)) {
960
	                        hasMissingObsolescenceFields = true;
961
	                    }
962
	                }
963
	                
964
	                if(sysmeta.getObsoletedBy() == null) {
965
	                    pid = sysmeta.getIdentifier();
966
	                    noObsoletedByCount++;
967
	                }
968
	                sidChain.add(sysmeta);
969
	            }
970
	        }
971
	    }
972
	    
973
	    if(hasMissingObsolescenceFields) {
974
	        System.out.println("It has an object whose system metadata has a missing obsoletes or obsoletedBy field.");
975
	        Collections.sort(sidChain, new SystemMetadataDateUploadedComparator());
976
            pid =sidChain.lastElement().getIdentifier();
977
	    } else {
978
	        if(noObsoletedByCount == 1) {
979
	            //rule 1 . If there is only one object having NULL value in the chain, return the value
980
	             System.out.println("rule 1");
981
	             return pid;
982
	         } else if (noObsoletedByCount > 1 ) {
983
	             // rule 2. If there is more than one object having NULL value in the chain, return last dateUploaded
984
	             System.out.println("rule 2");
985
	             Collections.sort(sidChain, new SystemMetadataDateUploadedComparator());
986
	             pid =sidChain.lastElement().getIdentifier();
987
	             
988
	         } else if (noObsoletedByCount == 0) {
989
	             // all pids were obsoleted
990
	             for(SystemMetadata sysmeta : sidChain) {
991
	                 //System.out.println("=== the pid in system metadata "+sysmeta.getIdentifier().getValue());
992
	                 Identifier obsoletedBy = sysmeta.getObsoletedBy();
993
	                 SystemMetadata sysOfObsoletedBy = getSystemMetadata(obsoletedBy, chain);
994
	                 if(sysOfObsoletedBy == null) {
995
	                     //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.
996
	                     System.out.println("rule 4");
997
	                     Collections.sort(sidChain, new SystemMetadataDateUploadedComparator());
998
	                     pid = sidChain.lastElement().getIdentifier();
999
	                     break;
1000
	                 } else {
1001
	                     Identifier sidOfObsoletedBy = sysOfObsoletedBy.getSeriesId();
1002
	                     if(sidOfObsoletedBy != null && !sidOfObsoletedBy.equals(sid)) {
1003
	                         //rule 3, if everything in {S1} is obsoleted, then select object that is obsoleted by another object that does not have the same SID
1004
	                         System.out.println("rule 3-1 (close with another sid "+sidOfObsoletedBy.getValue()+")");
1005
	                         pid = sysmeta.getIdentifier();
1006
	                         break;
1007
	                     } else if (sidOfObsoletedBy == null ) {
1008
	                         //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)
1009
	                         System.out.println("rule 3-2 (close without sid)");
1010
	                         pid = sysmeta.getIdentifier();
1011
	                         break;
1012
	                     }
1013
	                 }
1014
	                 
1015
	             }
1016
	         }
1017
	    }
1018
	    
1019
	    return pid;
1020
	}
1021
	
1022
	
1023
	private SystemMetadata getSystemMetadata(Identifier id, Vector<SystemMetadata> chain ){
1024
	    SystemMetadata sysmeta = null;
1025
	    if(id != null) {
1026
	        for(SystemMetadata sys : chain) {
1027
	            if(sys.getIdentifier().equals(id)) {
1028
	                sysmeta = sys;
1029
	                break;
1030
	            }
1031
	        }
1032
	    }
1033
	    return sysmeta;
1034
	}
1035
}
(7-7/8)