Project

General

Profile

Download (24.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.io.common.utils;
10

    
11
import java.util.Arrays;
12
import java.util.HashMap;
13
import java.util.HashSet;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.Optional;
17
import java.util.Set;
18
import java.util.UUID;
19
import java.util.function.Predicate;
20

    
21
import org.apache.log4j.Logger;
22

    
23
import eu.etaxonomy.cdm.api.application.ICdmRepository;
24
import eu.etaxonomy.cdm.api.service.IService;
25
import eu.etaxonomy.cdm.common.CdmUtils;
26
import eu.etaxonomy.cdm.io.common.ImportResult;
27
import eu.etaxonomy.cdm.io.common.ImportStateBase;
28
import eu.etaxonomy.cdm.model.agent.AgentBase;
29
import eu.etaxonomy.cdm.model.agent.Institution;
30
import eu.etaxonomy.cdm.model.agent.Person;
31
import eu.etaxonomy.cdm.model.agent.Team;
32
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
33
import eu.etaxonomy.cdm.model.common.CdmBase;
34
import eu.etaxonomy.cdm.model.common.ICdmBase;
35
import eu.etaxonomy.cdm.model.media.Rights;
36
import eu.etaxonomy.cdm.model.media.RightsType;
37
import eu.etaxonomy.cdm.model.name.HybridRelationship;
38
import eu.etaxonomy.cdm.model.name.INonViralName;
39
import eu.etaxonomy.cdm.model.name.TaxonName;
40
import eu.etaxonomy.cdm.model.occurrence.Collection;
41
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
42
import eu.etaxonomy.cdm.model.reference.Reference;
43
import eu.etaxonomy.cdm.strategy.match.DefaultMatchStrategy;
44
import eu.etaxonomy.cdm.strategy.match.IMatchStrategyEqual;
45
import eu.etaxonomy.cdm.strategy.match.MatchException;
46
import eu.etaxonomy.cdm.strategy.match.MatchMode;
47

    
48
/**
49
 * Helper class for deduplicating authors, references, names, etc.
50
 * during import.
51
 *
52
 * @author a.mueller
53
 * @since 11.02.2017
54
 */
55
public class ImportDeduplicationHelper<STATE extends ImportStateBase> {
56
    private static final Logger logger = Logger.getLogger(ImportDeduplicationHelper.class);
57

    
58
    private ICdmRepository repository;
59

    
60
    boolean referenceMapIsInitialized = false;
61
    boolean nameMapIsInitialized = false;
62
    boolean agentMapIsInitialized = false;
63
    boolean copyrightMapIsInitialized = false;
64
    boolean collectionMapIsInitialized = false;
65

    
66

    
67
    private Map<String, Set<Reference>> refMap = new HashMap<>();
68
    private Map<String, Set<Team>> teamMap = new HashMap<>();
69
    private Map<String, Set<Person>> personMap = new HashMap<>();
70
    private Map<String, Institution> institutionMap = new HashMap<>();
71
    //using titleCache
72
    private Map<String, Set<INonViralName>> nameMap = new HashMap<>();
73
    private Map<String, Set<Rights>> copyrightMap = new HashMap<>();
74
    private Map<String, Set<Collection>> collectionMap = new HashMap<>();
75

    
76

    
77
    private IMatchStrategyEqual referenceMatcher = DefaultMatchStrategy.NewInstance(Reference.class);
78
//    private IMatchStrategy collectionMatcher = DefaultMatchStrategy.NewInstance(Collection.class);
79
    private IMatchStrategyEqual nameMatcher = DefaultMatchStrategy.NewInstance(TaxonName.class);
80
    private IMatchStrategyEqual personMatcher = DefaultMatchStrategy.NewInstance(Person.class);
81
    private IMatchStrategyEqual teamMatcher = DefaultMatchStrategy.NewInstance(Team.class);
82

    
83

    
84
 // ************************** FACTORY *******************************/
85

    
86
     public static ImportDeduplicationHelper<?> NewInstance(ICdmRepository repository){
87
         return new ImportDeduplicationHelper<>(repository);
88
     }
89

    
90
     public static ImportDeduplicationHelper<?> NewStandaloneInstance(){
91
         return new ImportDeduplicationHelper<>(null);
92
     }
93

    
94
     /**
95
      * @param repository
96
      * @param state not used, only for correct casting of generics
97
      * @return
98
      */
99
     public static <STATE extends ImportStateBase<?,?>> ImportDeduplicationHelper<STATE> NewInstance(ICdmRepository repository, STATE state){
100
         return new ImportDeduplicationHelper<>(repository);
101
     }
102

    
103
 // ************************ CONSTRUCTOR *****************************/
104

    
105
     public ImportDeduplicationHelper(ICdmRepository repository) {
106
         this.repository = repository;
107
         if (repository == null){
108
             logger.warn("Repository is null. Deduplication does not work against database");
109
         }
110
         try {
111
             referenceMatcher.setMatchMode("title", MatchMode.EQUAL);
112
             teamMatcher.setMatchMode("nomenclaturalTitleCache", MatchMode.EQUAL_OR_SECOND_NULL);
113
         } catch (MatchException e) {
114
             throw new RuntimeException(e);  //should not happen
115
         }
116
     }
117

    
118
    public ImportDeduplicationHelper() {
119
        this(null);
120
    }
121

    
122
    public void restartSession(){
123
        restartSession(repository, null);
124
    }
125

    
126
    public void restartSession(ICdmRepository repository, ImportResult importResult){
127
        if (repository == null){
128
            return;
129
        }
130
        refMap = refreshSetMap(refMap, (IService)repository.getReferenceService(), importResult);
131
        personMap = refreshSetMap(personMap, (IService)repository.getAgentService(), importResult);
132
        teamMap = refreshSetMap(teamMap, (IService)repository.getAgentService(), importResult);
133
        institutionMap = refreshMap(institutionMap, (IService)repository.getAgentService(), importResult);
134

    
135
        nameMap = refreshSetMap(nameMap, (IService)repository.getNameService(), importResult);
136
        collectionMap = refreshSetMap(collectionMap, (IService)repository.getCollectionService(), importResult);
137
        //TODO copyright ?
138
    }
139

    
140
    private <T extends ICdmBase> Map<String, T> refreshMap(Map<String, T> oldMap,
141
            IService<T> service, ImportResult importResult) {
142
        Map<String, T> newMap = new HashMap<>();
143
        for (String key : oldMap.keySet()){
144
            T old = oldMap.get(key);
145
            if (old!= null){
146
                T cdmBase = service.find(old.getUuid());
147
                if (cdmBase == null){
148
                    String message = "No cdm object was found for uuid " + old.getUuid() + " of class " + old.getClass().getSimpleName();
149
                    importResult.addWarning(message);
150
                }else{
151
                    newMap.put(key, CdmBase.deproxy(cdmBase));
152
                }
153
            }else{
154
                String message = "Value for key " +  key + " was null in deduplication map";
155
                importResult.addWarning(message);
156
            }
157
        }
158
        return newMap;
159
    }
160

    
161
    private <T extends ICdmBase> Map<String, Set<T>> refreshSetMap(Map<String, Set<T>> oldMap,
162
            IService<T> service, ImportResult importResult) {
163
        Map<String, Set<T>> newMap = new HashMap<>();
164
        logger.debug("Start loading map");  //TODO debug only
165
        //create UUID set
166
        Set<UUID> uuidSet = new HashSet<>();
167
        for (String key : oldMap.keySet()){
168
            Set<T> oldSet = oldMap.get(key);
169
            for (T item : oldSet){
170
                UUID uuid = item.getUuid();
171
                uuidSet.add(uuid);
172
            }
173
        }
174
        //create uuid-item map
175
        Map<UUID, T> itemMap = new HashMap<>();
176
        List<T> list = service.find(uuidSet);
177
        for (T item : list){
178
            itemMap.put(item.getUuid(), item);
179
        }
180
        //refresh
181
        for (String key : oldMap.keySet()){
182
            Set<T> oldSet = oldMap.get(key);
183
            Set<T> newSet = new HashSet<>();
184
            if (oldSet != null){
185
                newMap.put(key, newSet);
186
                for (T item : oldSet){
187
                    T cdmBase = CdmBase.deproxy(itemMap.get(item.getUuid()));
188
                    if (cdmBase == null){
189
                        String message = "No cdm object was found for uuid " + item.getUuid() + " of class " + item.getClass().getSimpleName();
190
                        importResult.addWarning(message);
191
                    }else{
192
                        newSet.add(cdmBase);
193
                    }
194
                }
195
            }else{
196
                String message = "Value for key " +  key + " was null in deduplication map";
197
                importResult.addWarning(message);
198
            }
199
        }
200
        return newMap;
201
    }
202

    
203

    
204
//************************ PUTTER / GETTER *****************************/
205

    
206
    //REFERENCES
207
    private void putReference(String title, Reference ref){
208
        Set<Reference> refs = refMap.get(title);
209
        if (refs == null){
210
            refs = new HashSet<>();
211
            refMap.put(title, refs);
212
        }
213
        refs.add(CdmBase.deproxy(ref));
214
    }
215
    private Set<Reference> getReferences(String title){
216
        return refMap.get(title);
217
    }
218

    
219
    private Optional<Reference> getMatchingReference(Reference newReference){
220
        Predicate<Reference> matchFilter = reference ->{
221
            try {
222
                return referenceMatcher.invoke(reference, newReference).isSuccessful();
223
            } catch (MatchException e) {
224
                throw new RuntimeException(e);
225
            }
226
        };
227
        return Optional.ofNullable(getReferences(newReference.getTitleCache()))
228
                .orElse(new HashSet<>())
229
                .stream()
230
                .filter(matchFilter)
231
                .findAny();
232
    }
233

    
234
    // AGENTS
235
    private void putAgentBase(String title, AgentBase<?> agent){
236
        if (agent.isInstanceOf(Person.class) ){
237
            putAgent(title, CdmBase.deproxy(agent, Person.class), personMap);
238
        }else if (agent.isInstanceOf(Team.class)){
239
            putAgent(title, CdmBase.deproxy(agent, Team.class), teamMap);
240
        }else{
241
//            putAgent(title, CdmBase.deproxy(agent, Institution.class), institutionMap);
242
            institutionMap.put(title, CdmBase.deproxy(agent, Institution.class));
243
        }
244
    }
245
    //put agent
246
    private <T extends AgentBase> void putAgent(String title, T agent, Map<String, Set<T>> map){
247
        Set<T> items = map.get(title);
248
        if (items == null){
249
            items = new HashSet<>();
250
            map.put(title, items);
251
        }
252
        items.add(CdmBase.deproxy(agent));
253
    }
254

    
255
    private Optional<Person> getMatchingPerson(Person newPerson){
256
        Person newPersonDeproxy = CdmBase.deproxy(newPerson);
257
        Predicate<Person> matchFilter = (person) ->{
258
            try {
259
                return personMatcher.invoke(person, newPersonDeproxy).isSuccessful();
260
            } catch (MatchException e) {
261
                throw new RuntimeException(e);
262
            }
263
        };
264

    
265
        return Optional.ofNullable(getPersons(newPerson.getTitleCache()))
266
                .orElse(new HashSet<>())
267
                .stream()
268
                .filter(matchFilter)
269
                .findAny();
270
    }
271

    
272
    private <T extends TeamOrPersonBase<?>> T getTeamOrPerson(T agent){
273
        T result = agent;
274
        if (agent.isInstanceOf(Person.class)){
275
            result = (T)getMatchingPerson(CdmBase.deproxy(agent, Person.class)).orElse(null) ; // personMap.get(title);
276
        }else if (agent.isInstanceOf(Team.class)) {
277
            result = (T)getMatchingTeam(CdmBase.deproxy(agent, Team.class)).orElse(null); // teamMap.get(title);
278
        }
279
        return result;
280
    }
281

    
282
    private Optional<Team> getMatchingTeam(Team newTeam){
283
        Team newTeamDeproxy = CdmBase.deproxy(newTeam);
284
        Predicate<Team> matchFilter = (team) ->{
285
            try {
286
                return teamMatcher.invoke(team, newTeamDeproxy).isSuccessful();
287
            } catch (MatchException e) {
288
                throw new RuntimeException(e);
289
            }
290
        };
291
        //TODO better adapt matching strategy
292
//        newTeam.getNomenclaturalTitle();
293
        return Optional.ofNullable(getTeams(newTeam.getTitleCache()))
294
                .orElse(new HashSet<>())
295
                .stream()
296
                .filter(matchFilter)
297
                .findAny();
298
    }
299
    private Set<Person> getPersons(String title){
300
        return personMap.get(title);
301
    }
302
    private Set<Team> getTeams(String title){
303
        return teamMap.get(title);
304
    }
305

    
306
    //NAMES
307
    private void putName(String title, INonViralName name){
308
        Set<INonViralName> names = nameMap.get(title);
309
        if (names == null){
310
            names = new HashSet<>();
311
            nameMap.put(title, names);
312
        }
313
        names.add(CdmBase.deproxy(name));
314
    }
315
    private Set<INonViralName> getNames(String title){
316
        return nameMap.get(title);
317
    }
318

    
319
    private Optional<INonViralName> getMatchingName(INonViralName existing){
320
        Predicate<INonViralName> matchFilter = name ->{
321
            try {
322
                return nameMatcher.invoke(name, existing).isSuccessful();
323
            } catch (MatchException e) {
324
                throw new RuntimeException(e);
325
            }
326
        };
327
        return Optional.ofNullable(getNames(existing.getTitleCache()))
328
                .orElse(new HashSet<>())
329
                .stream()
330
                .filter(matchFilter)
331
                .findAny();
332
    }
333

    
334
    //COLLECTIONS
335
    private void putCollection(String title, Collection collection){
336
        Set<Collection> collections = collectionMap.get(title);
337
        if (collections == null){
338
            collections = new HashSet<>();
339
            collectionMap.put(title, collections);
340
        }
341
        collections.add(CdmBase.deproxy(collection));
342
    }
343

    
344
    private Set<Collection> getCollections(String title){
345
        return collectionMap.get(title);
346
    }
347

    
348
    private Optional<Collection> getMatchingCollections(Collection existing){
349
        Predicate<Collection> matchFilter = collection ->{
350
//            try {
351
                //TODO right Collection matching
352
                if (CdmUtils.nullSafeEqual(collection.getName(), existing.getName())
353
                        && CdmUtils.nullSafeEqual(collection.getCode(), existing.getCode())){
354
                    return true;
355
                }else{
356
                    return false;
357
                }
358
//                return collectionMatcher.invoke(collection, existing);
359
//            } catch (MatchException e) {
360
//                throw new RuntimeException(e);
361
//            }
362
        };
363
        return Optional.ofNullable(getCollections(existing.getTitleCache()))
364
                .orElse(new HashSet<>())
365
                .stream()
366
                .filter(matchFilter)
367
                .findAny();
368
    }
369

    
370
// **************************** METHODS *****************************/
371

    
372
    /**
373
     * This method replaces name authors, nomenclatural reference and
374
     * nomenclatural reference author by existing authors and references
375
     * if matching authors or references exist. If not, the given authors
376
     * and references are added to the map of existing entities.
377
     *
378
     * @param state the import state
379
     * @param name the name with authors and references to replace
380
     */
381
    public void replaceAuthorNamesAndNomRef(STATE state,
382
            INonViralName name) {
383
        TeamOrPersonBase<?> combAuthor = name.getCombinationAuthorship();
384
        name.setCombinationAuthorship(getExistingAuthor(state, combAuthor));
385

    
386
        TeamOrPersonBase<?> exAuthor = name.getExCombinationAuthorship();
387
        name.setExCombinationAuthorship(getExistingAuthor(state, exAuthor));
388

    
389
        TeamOrPersonBase<?> basioAuthor = name.getBasionymAuthorship();
390
        name.setBasionymAuthorship(getExistingAuthor(state, basioAuthor));
391

    
392
        TeamOrPersonBase<?> exBasioAuthor = name.getExBasionymAuthorship();
393
        name.setExBasionymAuthorship(getExistingAuthor(state, exBasioAuthor));
394

    
395
        INomenclaturalReference nomRef = name.getNomenclaturalReference();
396
        if (nomRef != null){
397
            TeamOrPersonBase<?> refAuthor = nomRef.getAuthorship();
398
            nomRef.setAuthorship(getExistingAuthor(state, refAuthor));
399

    
400
            Reference existingRef = getExistingReference(state, (Reference)nomRef);
401
            if (existingRef != null){
402
                name.setNomenclaturalReference(existingRef);
403
            }
404
        }
405
    }
406

    
407
    public <T extends TeamOrPersonBase<?>> T getExistingAuthor(STATE state,
408
            T author) {
409
        if (author == null){
410
            return null;
411
        }else{
412
            initAgentMap(state);
413
            initAuthorTitleCaches(author);
414
            T result = getTeamOrPerson(author);
415
            if (result == null){
416
                putAgentBase(author.getTitleCache(), author);
417
                if (author.isInstanceOf(Team.class)){
418
                    handleTeam(state, CdmBase.deproxy(author, Team.class));
419
                }
420
                result = author;
421
            }
422
            return result;
423
        }
424
    }
425

    
426
    private <T extends TeamOrPersonBase<?>> void initAuthorTitleCaches(T author) {
427
        //NOTE: this is more or less redundant copy from CdmPreDataChangeListener
428
        author.getNomenclaturalTitleCache();
429
        author.getCollectorTitleCache();
430
        String titleCache = author.getTitleCache();
431
      //not sure if this is really needed
432
        if (! author.isProtectedTitleCache()){
433
            author.setTitleCache(titleCache, false);
434
        }
435
    }
436

    
437
    private void initReferenceCaches(Reference ref) {
438
        ////TODO better do via matching strategy  (newReference might have caches == null)
439
        //more or less copy from CdmPreDataChangeListener
440
        ref.getAbbrevTitleCache();
441
        ref.getTitleCache();
442
   }
443

    
444
    public AgentBase<?> getExistingAgent(STATE state,
445
            AgentBase<?> agent) {
446
        if (agent == null){
447
            return null;
448
        } else if (agent.isInstanceOf(TeamOrPersonBase.class)){
449
            return getExistingAuthor(state, CdmBase.deproxy(agent, TeamOrPersonBase.class));
450
        }else{
451
            initAgentMap(state);
452
            Institution result = institutionMap.get(agent.getTitleCache());
453
            if (result == null){
454
                putAgentBase(agent.getTitleCache(), agent);
455
                result = CdmBase.deproxy(agent, Institution.class);
456
            }
457
            return result;
458
        }
459
    }
460

    
461
    @SuppressWarnings("rawtypes")
462
    private void initAgentMap(STATE state) {
463
        if (!agentMapIsInitialized && repository != null){
464
            List<String> propertyPaths = Arrays.asList("");
465
            List<AgentBase> existingAgents = repository.getAgentService().list(null, null, null, null, propertyPaths);
466
            for (AgentBase agent : existingAgents){
467
                putAgentBase(agent.getTitleCache(), CdmBase.deproxy(agent));
468
            }
469
            agentMapIsInitialized = true;
470
        }
471
    }
472

    
473
    private void handleTeam(STATE state, Team team) {
474
        List<Person> members = team.getTeamMembers();
475
        for (int i =0; i< members.size(); i++){
476
            Person person = CdmBase.deproxy(members.get(i));
477
            Person existingPerson = getMatchingPerson(person).orElse(null);
478
            if (existingPerson != null){
479
                members.set(i, existingPerson);
480
            }else{
481
                putAgentBase(person.getTitleCache(), person);
482
            }
483
        }
484
    }
485

    
486
    public Collection getExistingCollection(STATE state, Collection collection) {
487
        if (collection == null){
488
            return null;
489
        }else{
490
            initCollectionMap(state);
491
            Collection result = getMatchingCollections(collection).orElse(null);
492
            if (result == null){
493
                result = collection;
494
                putCollection(result.getTitleCache(), result);
495
            }else{
496
                if(logger.isDebugEnabled()) {
497
                    logger.debug("Matches");
498
                 }
499
            }
500
            return result;
501
        }
502
    }
503

    
504
    private void initCollectionMap(STATE state) {
505
        if (!collectionMapIsInitialized && repository != null){
506
            List<String> propertyPaths = Arrays.asList("");
507
            List<Collection> existingCollections = repository.getCollectionService().list(null, null, null, null, propertyPaths);
508
            for (Collection collection : existingCollections){
509
                putCollection(collection.getTitleCache(), collection);
510
            }
511
            collectionMapIsInitialized = true;
512
        }
513
    }
514

    
515
   public Reference getExistingReference(STATE state, Reference ref) {
516
       if (ref == null){
517
           return null;
518
       }else{
519
           initRerenceMap(state);
520
           initReferenceCaches(ref);
521
           Reference result = getMatchingReference(ref).orElse(null);
522
           if (result == null){
523
               result = ref;
524
               Reference inRef = result.getInReference();
525
               if (inRef != null){
526
                   result.setInReference(getExistingReference(state, result.getInReference()));
527
               }
528
               putReference(result.getTitleCache(), result);
529
           }else{
530
               if(logger.isDebugEnabled()) {
531
                   logger.debug("Matches");
532
                }
533
           }
534
           return result;
535
       }
536
   }
537

    
538
   private void initRerenceMap(STATE state) {
539
       if (!referenceMapIsInitialized && repository != null){
540
           List<String> propertyPaths = Arrays.asList("");
541
           List<Reference> existingReferences = repository.getReferenceService().list(null, null, null, null, propertyPaths);
542
           for (Reference ref : existingReferences){
543
               putReference(ref.getTitleCache(), ref);
544
           }
545
           referenceMapIsInitialized = true;
546
       }
547
   }
548

    
549
   public <NAME extends INonViralName> NAME getExistingName(STATE state, NAME name) {
550
       if (name == null){
551
           return null;
552
       }else{
553
           initNameMap(state);
554
           @SuppressWarnings("unchecked")
555
           NAME result = (NAME)getMatchingName(name).orElse(null);
556
           if (result == null){
557
               result = name;
558
               Set<HybridRelationship> parentRelations = result.getHybridChildRelations();
559
               for (HybridRelationship rel : parentRelations){
560
                   INonViralName parent = rel.getParentName();
561
                   if (parent != null){
562
                       rel.setParentName(getExistingName(state, parent));
563
                   }
564
               }
565
               putName(result.getTitleCache(), result);
566
           }else{
567
               if(logger.isDebugEnabled()) {
568
                   logger.debug("Matches");
569
                }
570
           }
571
           return result;
572
       }
573
   }
574

    
575
   private void initNameMap(STATE state) {
576
       if (!nameMapIsInitialized && repository != null){
577
           List<String> propertyPaths = Arrays.asList("");
578
           List<TaxonName> existingNames = repository.getNameService().list(null, null, null, null, propertyPaths);
579
           for (TaxonName name : existingNames){
580
               putName(name.getTitleCache(), name);
581
           }
582
          nameMapIsInitialized = true;
583
       }
584
   }
585

    
586
   public Rights getExistingCopyright(STATE state,
587
           Rights right) {
588
       if (right == null || !RightsType.COPYRIGHT().equals(right.getType())){
589
           return null;
590
       }else{
591
           initCopyrightMap(state);
592
           String key = makeCopyrightKey(right);
593
           Set<Rights> set = copyrightMap.get(key);
594
           if (set == null || set.isEmpty()){
595
               putCopyright(key, right);
596
               return right;
597
           }else if (set.size()>1){
598
               //TODO
599
               logger.warn("More than 1 matching copyright not yet handled for key: " + key);
600
           }
601
           return set.iterator().next();
602
       }
603
   }
604

    
605
    private void initCopyrightMap(STATE state) {
606
        if (!copyrightMapIsInitialized && repository != null){
607
            List<String> propertyPaths = Arrays.asList("");
608
            List<Rights> existingRights = repository.getRightsService().list(null, null, null, null, propertyPaths);
609
            for (Rights right : existingRights){
610
                if (RightsType.COPYRIGHT().equals(right.getType())){
611
                    putCopyright(makeCopyrightKey(right), right);
612
                }
613
            }
614
            copyrightMapIsInitialized = true;
615
        }
616

    
617
    }
618

    
619
    private void putCopyright(String key, Rights right) {
620
        Set<Rights> rights = copyrightMap.get(key);
621
        if (rights == null){
622
            rights = new HashSet<>();
623
            copyrightMap.put(key, rights);
624
        }
625
        rights.add(CdmBase.deproxy(right));
626

    
627
    }
628

    
629
    private String makeCopyrightKey(Rights right) {
630
        if (right.getAgent() != null){
631
            return right.getAgent().getTitleCache();
632
        }else if (right.getText() != null){
633
            return right.getText();
634
        }else {
635
            logger.warn("Key for copyright could not be created: " + right);
636
            return right.getUuid().toString();
637
        }
638
    }
639
}
    (1-1/1)