Project

General

Profile

Download (20 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2018 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.strategy.match;
10

    
11
import eu.etaxonomy.cdm.model.agent.Person;
12
import eu.etaxonomy.cdm.model.agent.Team;
13
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
14
import eu.etaxonomy.cdm.model.name.TaxonName;
15
import eu.etaxonomy.cdm.model.reference.Reference;
16
import eu.etaxonomy.cdm.model.reference.ReferenceType;
17

    
18
/**
19
 * @author a.mueller
20
 * @since 17.10.2018
21
 */
22
public class MatchStrategyFactory {
23

    
24
    public static IMatchStrategyEqual NewDefaultInstance(Class<? extends IMatchable> matchClass){
25
        return new DefaultMatchStrategy(matchClass);
26
    }
27

    
28
    public static IParsedMatchStrategy NewParsedInstance(Class<? extends IMatchable> matchClass){
29
        IParsedMatchStrategy parsedMatchStrategy = new ParsedBaseMatchStrategy(matchClass);
30
        return parsedMatchStrategy;
31
    }
32

    
33
    public static IParsedMatchStrategy NewParsedPersonInstance(){
34
        try {
35
            IParsedMatchStrategy parsedPersonMatchStrategy = NewParsedInstance(Person.class);
36

    
37
            addParsedAgentBaseMatchModes(parsedPersonMatchStrategy);
38

    
39
            //FIXME adapt for  for inRef authors
40
            parsedPersonMatchStrategy.setMatchMode("nomenclaturalTitle", MatchMode.EQUAL);
41

    
42
            //FIXME adapt for inRef authors
43
            parsedPersonMatchStrategy.setMatchMode("familyName", MatchMode.EQUAL_OR_FIRST_NULL);
44

    
45
            //TODO lifespan may implement MATCH_OR_ONE_NULL
46
            String[] equalOrNullParams = new String[]{"collectorTitle","givenName","initials",
47
                    "lifespan","orcid","prefix","suffix"};
48
            for(String param : equalOrNullParams){
49
                parsedPersonMatchStrategy.setMatchMode(param, MatchMode.EQUAL_OR_FIRST_NULL);
50
            }
51

    
52
            String[] ignoreParams = new String[]{"institutionalMemberships"};
53
            for(String param : ignoreParams){
54
                parsedPersonMatchStrategy.setMatchMode(param, MatchMode.IGNORE);
55
            }
56

    
57
            return parsedPersonMatchStrategy;
58
        } catch (MatchException e) {
59
            throw new RuntimeException("Exception when creating parsed person match strategy.", e);
60
        }
61
    }
62

    
63
    public static IParsedMatchStrategy NewParsedTeamInstance(){
64
        IParsedMatchStrategy parsedTeamMatchStrategy = NewParsedInstance(Team.class);
65
        try {
66
            addParsedAgentBaseMatchModes(parsedTeamMatchStrategy);
67

    
68
            parsedTeamMatchStrategy.setMatchMode("teamMembers", MatchMode.MATCH, NewParsedPersonInstance());
69

    
70
            parsedTeamMatchStrategy.setMatchMode("hasMoreMembers", MatchMode.EQUAL);
71

    
72
            parsedTeamMatchStrategy.setMatchMode("protectedCollectorTitleCache", MatchMode.EQUAL_OR_FIRST_NULL);
73
            parsedTeamMatchStrategy.setMatchMode("protectedNomenclaturalTitleCache", MatchMode.EQUAL);
74

    
75
            String[] equalOrNullParams = new String[]{};
76
            for(String param : equalOrNullParams){
77
                parsedTeamMatchStrategy.setMatchMode(param, MatchMode.EQUAL_OR_FIRST_NULL);
78
            }
79

    
80
            String[] ignoreParams = new String[]{};
81
            for(String param : ignoreParams){
82
                parsedTeamMatchStrategy.setMatchMode(param, MatchMode.IGNORE);
83
            }
84

    
85
            return parsedTeamMatchStrategy;
86
        } catch (MatchException e) {
87
            throw new RuntimeException("Exception when creating parsed team match strategy.", e);
88
        }
89
    }
90

    
91
    public static IParsedMatchStrategy NewParsedTeamOrPersonInstance(){
92
        @SuppressWarnings("rawtypes")
93
        SubClassMatchStrategy<TeamOrPersonBase> parsedAuthorMatchStrategy = SubClassMatchStrategy.NewInstance(TeamOrPersonBase.class);
94
        try {
95
            parsedAuthorMatchStrategy.putStrategy(Person.class, NewParsedPersonInstance());
96
            parsedAuthorMatchStrategy.putStrategy(Team.class, NewParsedTeamInstance());
97
            return parsedAuthorMatchStrategy;
98
        } catch (MatchException e) {
99
            throw new RuntimeException("Exception when creating parsed author match strategy.", e);
100
        }
101
    }
102

    
103
    public static IParsedMatchStrategy NewParsedBookInstance(){
104
        try {
105
            IParsedMatchStrategy parsedBookMatchStrategy = NewParsedInstance(Reference.class);
106

    
107
            addParsedReferenceMatchModes(parsedBookMatchStrategy);
108

    
109
            //author (as it should always be known for a parsed book)
110
            parsedBookMatchStrategy.setMatchMode("authorship", MatchMode.MATCH_REQUIRED, NewParsedTeamOrPersonInstance());
111
            //in-reference , parsed book has no in-Reference
112
            parsedBookMatchStrategy.setMatchMode("inReference", MatchMode.EQUAL_OR_FIRST_NULL);
113
            parsedBookMatchStrategy.setMatchMode("title", MatchMode.EQUAL_OR_FIRST_NULL);  //not available in parsed book
114
            parsedBookMatchStrategy.setMatchMode("abbrevTitle", MatchMode.EQUAL_REQUIRED);
115

    
116
            //TODO caches
117

    
118
            return parsedBookMatchStrategy;
119
        } catch (MatchException e) {
120
            throw new RuntimeException("Exception when creating parsed team match strategy.", e);
121
        }
122
    }
123

    
124
    /**
125
     * As the book section is not clearly defined if parsed (usually only the author and publication date is known),
126
     * it can only match exactly. If pages, title, abbrevTitle are known for the more complete references
127
     * it will match only if they are also known for the parsed instance.
128
     */
129
    public static IParsedMatchStrategy NewParsedBookSectionInstance(){
130
        try {
131
            IParsedMatchStrategy parsedBookSectionMatchStrategy = (IParsedMatchStrategy)NewDefaultInstance(Reference.class);
132

    
133
            addParsedSectionReferenceMatchModes(parsedBookSectionMatchStrategy);
134

    
135
            //author (or either title or authorship match, but usually only authorship is known for parsed instances)
136
            parsedBookSectionMatchStrategy.setMatchMode("authorship", MatchMode.MATCH_REQUIRED, NewParsedTeamOrPersonInstance());
137
            //in-reference
138
            parsedBookSectionMatchStrategy.setMatchMode("inReference", MatchMode.MATCH_REQUIRED, NewParsedBookInstance());
139
            //see comment on title and abbrevTitle in #NewParsedArticleInstance
140
            parsedBookSectionMatchStrategy.setMatchMode("title", MatchMode.EQUAL);
141
            parsedBookSectionMatchStrategy.setMatchMode("abbrevTitle", MatchMode.EQUAL);
142

    
143
            //TODO caches
144

    
145
            return parsedBookSectionMatchStrategy;
146

    
147
        } catch (MatchException e) {
148
            throw new RuntimeException("Exception when creating parsed team match strategy.", e);
149
        }
150
    }
151

    
152
    public static IParsedMatchStrategy NewParsedArticleInstance(){ //or should it better be Section (in Journal)
153
        try {
154
            IParsedMatchStrategy articleMatchStrategy = (IParsedMatchStrategy)NewDefaultInstance(Reference.class);
155

    
156
            addParsedSectionReferenceMatchModes(articleMatchStrategy);
157

    
158
            //if a title or abbrevTitle exists for the existing (first) article
159
            //we can not guarantee that the article is really the one that is
160
            //meant in the context, there could be other articles with the same
161
            //author.
162
            //Having a soft matching for possible candidates may solve this issue.
163
            //Also comparing the detail (page) with a filled field "pages" may solve
164
            //it in many cases.
165
            //However, we need to accept that articles as nomenclatural references are not
166
            //clearly enough defined so exact matching with rich data is not possible at
167
            //this point
168
            //TODO improvement, check page number
169
            articleMatchStrategy.setMatchMode("title", MatchMode.EQUAL);
170
            articleMatchStrategy.setMatchMode("abbrevTitle", MatchMode.EQUAL);
171

    
172
            articleMatchStrategy.setMatchMode("authorship", MatchMode.MATCH_REQUIRED, NewParsedTeamOrPersonInstance());
173
            articleMatchStrategy.setMatchMode("inReference", MatchMode.MATCH, NewParsedJournalInstance());
174

    
175
            //TODO caches
176

    
177
            return articleMatchStrategy;
178
        } catch (MatchException e) {
179
            throw new RuntimeException("Problems when creating parsed article match strategy.");
180
        }
181
    }
182

    
183
    /**
184
     * Adds all typical parsed reference match modes which are equal for non section references
185
     * (journal, book, (generic(?))).
186
     * The following fields need to be handled explicitly by each calling method:<BR>
187
     *
188
     * <LI>authorship</LI>
189
     * <LI>title</LI>
190
     * <LI>abbrevTitle</LI>
191
     * <LI>titleCache</LI>
192
     * <LI>abbrevTitleCache</LI>
193
     * <LI>protectedTitleCache</LI>
194
     * <LI>protectedAbbrevTitleCache</LI>
195
     * <LI>inReference</LI>
196
     *
197
     * @see #addParsedSectionReferenceMatchModes(IParsedMatchStrategy)
198
     * @param referenceMatchStrategy the strategy to fill
199
     * @throws MatchException
200
     */
201
    private static void addParsedReferenceMatchModes(IParsedMatchStrategy referenceMatchStrategy) throws MatchException {
202

    
203
        //"placePublished" should be MatchMode.EQUAL if parser parses place published
204
        //TODO datePublished could also be more detailed in first then in second, e.g. Apr 2008 <-> 2008,
205
        //something like MatchMode.IncludedIn is needed here
206

    
207
        //TODO externally managed
208

    
209
        addParsedIdentifiableEntityModes(referenceMatchStrategy);
210

    
211
        String[] equalOrNullParams = new String[]{"accessed","doi",
212
                "institution","isbn","issn","organization",
213
                "pages","publisher","placePublished",
214
                "referenceAbstract","school","uri"};
215
        for(String param : equalOrNullParams){
216
            referenceMatchStrategy.setMatchMode(param, MatchMode.EQUAL_OR_FIRST_NULL);
217
        }
218

    
219
        String[] equalParams = new String[]{"datePublished","edition",
220
                "editor","seriesPart","volume"};
221
        for(String param : equalParams){
222
            referenceMatchStrategy.setMatchMode(param, MatchMode.EQUAL);
223
        }
224
        String[] matchOrNullParams = new String[]{"institution"};
225
        for(String param : matchOrNullParams){
226
            referenceMatchStrategy.setMatchMode(param, MatchMode.MATCH_OR_FIRST_NULL);
227
        }
228
    }
229

    
230
    /**
231
     * Adds all typical parsed reference match modes which are equal for section references
232
     * (article, book section).
233
     * The following fields need to be handled explicitly by each calling method:<BR>
234
     *
235
     * For further information see: #9157
236
     *
237
     * <LI>authorship</LI>
238
     * <LI>title</LI>
239
     * <LI>abbrevTitle</LI>
240
     * <LI>titleCache</LI>
241
     * <LI>abbrevTitleCache</LI>
242
     * <LI>protectedTitleCache</LI>
243
     * <LI>protectedAbbrevTitleCache</LI>
244
     * <LI>inReference</LI>
245
     *
246
     * @see #addParsedReferenceMatchModes(IParsedMatchStrategy)
247
     * @param referenceMatchStrategy the strategy to fill
248
     * @throws MatchException
249
     */
250
    private static void addParsedSectionReferenceMatchModes(IParsedMatchStrategy referenceMatchStrategy) throws MatchException {
251

    
252
        //"placePublished" should be MatchMode.EQUAL if parser parses place published
253
        //TODO datePublished could also be more detailed in first then in second, e.g. Apr 2008 <-> 2008,
254
        //something like MatchMode.IncludedIn is needed here
255
        //TODO pages if a page number is given the parsed reference may not be unidentified anymore
256

    
257
        //TODO externally managed
258

    
259
        addParsedIdentifiableEntityModes(referenceMatchStrategy);
260

    
261
        //here the result differs from addParsedReferenceMatchModes
262
        String[] equalOrNullParams = new String[]{"accessed","doi",
263
                "institution","isbn","issn","organization",
264
                "pages","publisher","placePublished",
265
                "referenceAbstract","school","uri"};
266
        for(String param : equalOrNullParams){
267
            referenceMatchStrategy.setMatchMode(param, MatchMode.EQUAL); //EQUAL !!
268
        }
269

    
270
        String[] equalParams = new String[]{"datePublished","edition",
271
                "editor","seriesPart","volume"};
272
        for(String param : equalParams){
273
            referenceMatchStrategy.setMatchMode(param, MatchMode.EQUAL);
274
        }
275
        String[] matchOrNullParams = new String[]{"institution"};
276
        for(String param : matchOrNullParams){
277
            referenceMatchStrategy.setMatchMode(param, MatchMode.MATCH); //MATCH!!
278
        }
279
    }
280

    
281
    private static void addParsedAgentBaseMatchModes(IParsedMatchStrategy matchStrategy) throws MatchException {
282

    
283
        addParsedIdentifiableEntityModes(matchStrategy);
284

    
285
        //TODO contact does not yet works, also not with EQUAL_OR_ONE_NULL, leads to agent.id=? or agent.id is null query
286
        //better should be even handled with MATCH.Equal_OR_ONE_NULL
287
        String[] equalOrNullParams = new String[]{};
288
        for(String param : equalOrNullParams){
289
            matchStrategy.setMatchMode(param, MatchMode.EQUAL_OR_FIRST_NULL);
290
        }
291
        String[] ignoreCollectionParams = new String[]{"media"};
292
        for(String param : ignoreCollectionParams){
293
            matchStrategy.setMatchMode(param, MatchMode.IGNORE);
294
        }
295
    }
296

    
297
    private static void addParsedIdentifiableEntityModes(IParsedMatchStrategy matchStrategy) throws MatchException {
298

    
299
        addAnnotatableEntityModes(matchStrategy);
300

    
301
        //TODO titleCache and protectedTitleCache
302

    
303
        //TODO lsid should be handled with MATCH
304
        String[] equalOrNullParams = new String[]{"lsid"};
305
        for(String param : equalOrNullParams){
306
            matchStrategy.setMatchMode(param, MatchMode.EQUAL_OR_FIRST_NULL);
307
        }
308
        String[] ignoreCollectionParams = new String[]{"credits","extensions","identifiers","links","rights"};
309
        for(String param : ignoreCollectionParams){
310
            matchStrategy.setMatchMode(param, MatchMode.IGNORE);
311
        }
312
    }
313

    
314
    private static void addAnnotatableEntityModes(IParsedMatchStrategy matchStrategy) throws MatchException {
315

    
316
//        //TODO titleCache and protectedTitleCache
317
//
318
//        //TODO lsid should be handled with MATCH
319
//        String[] equalOrNullParams = new String[]{"lsid"};
320
//        for(String param : equalOrNullParams){
321
//            matchStrategy.setMatchMode(param, MatchMode.EQUAL_OR_ONE_NULL);
322
//        }
323
        String[] ignoreCollectionParams = new String[]{"sources","annotations","markers"};
324
        for(String param : ignoreCollectionParams){
325
            matchStrategy.setMatchMode(param, MatchMode.IGNORE);
326
        }
327
    }
328

    
329
    public static IParsedMatchStrategy NewParsedJournalInstance(){
330

    
331
        try {
332
            IParsedMatchStrategy parsedJournalMatchStrategy = NewParsedInstance(Reference.class);
333
            addParsedReferenceMatchModes(parsedJournalMatchStrategy);
334

    
335
            //journals must not have an author, better MatchMode would be MatchMode.NULL
336
            parsedJournalMatchStrategy.setMatchMode("authorship", MatchMode.MATCH, NewParsedTeamOrPersonInstance());
337
            //in-reference, parsed journal has no in-reference
338
            parsedJournalMatchStrategy.setMatchMode("inReference", MatchMode.EQUAL_OR_FIRST_NULL);
339
            parsedJournalMatchStrategy.setMatchMode("title", MatchMode.EQUAL_OR_FIRST_NULL);  //full title not available in parsed journal
340
            parsedJournalMatchStrategy.setMatchMode("abbrevTitle", MatchMode.EQUAL_REQUIRED);
341

    
342
            //TODO caches
343

    
344
            return parsedJournalMatchStrategy;
345
        } catch (MatchException e) {
346
            throw new RuntimeException("Exception when creating parsed journal match strategy.", e);
347
        }
348
    }
349

    
350
    public static IParsedMatchStrategy NewParsedReferenceInstance(){
351
        IParsedMatchStrategy refStrat = ParsedReferenceMatchStrategy.INSTANCE();
352
        return refStrat;
353
    }
354

    
355
    /**
356
     * Returns the best matching strategy for a given reference
357
     * with a given reference type
358
     * @return the matching strategy
359
     * @throws NullPointerException if ref is <code>null</code>
360
     */
361
    public static IMatchStrategy NewParsedReferenceInstance(Reference ref) {
362
        ReferenceType type = ref.getType();
363
        if (type.equals(ReferenceType.Article)){
364
            return NewParsedArticleInstance();
365
        }else if (type.equals(ReferenceType.Book)){
366
            return NewParsedBookInstance();
367
        }else if (type.equals(ReferenceType.BookSection)){
368
            return NewParsedBookSectionInstance();
369
        }else if (type.equals(ReferenceType.Journal)){
370
            return NewParsedJournalInstance();
371
        }else if (type.equals(ReferenceType.Generic)){
372
            //TODO
373
            return NewDefaultInstance(Reference.class);
374
        }else{
375
            //TODO
376
            return NewDefaultInstance(Reference.class);
377
        }
378
    }
379

    
380
    //  public static IMatchStrategy NewParsedNameInstance(){
381
    //      IMatchStrategy result = new DefaultMatchStrategy(TaxonName.class);
382
    //      return result;
383
    //  }
384

    
385
    public static IParsedMatchStrategy NewParsedOriginalSpellingInstance(){
386
        try {
387
            IParsedMatchStrategy originalSpellingMatchStrategy = (IParsedMatchStrategy)NewDefaultInstance(TaxonName.class);
388
            addParsedIdentifiableEntityModes(originalSpellingMatchStrategy);
389

    
390
            //authorshipCache, nameCache, fullTitleCache,
391
            //protectedFullTitleCache, protectedNameCache, protectedAuthorshipCache,
392
            //nomenclaturalSource,
393
            originalSpellingMatchStrategy.setMatchMode("genusOrUninomial", MatchMode.EQUAL_REQUIRED);
394
            originalSpellingMatchStrategy.setMatchMode("nameType", MatchMode.EQUAL_REQUIRED);
395
            originalSpellingMatchStrategy.setMatchMode("rank", MatchMode.EQUAL_REQUIRED);  //?? MatchMode.MATCH_REQUIRED => not yet implemented as Match class
396

    
397
            //equal
398
            String[] equalParams = new String[]{"acronym","anamorphic","appendedPhrase",
399
                    "binomHybrid", "monomHybrid","trinomHybrid","hybridFormula",
400
                    "breed","cultivarName","infraGenericEpithet","infraSpecificEpithet",
401
                    "publicationYear","originalPublicationYear","specificEpithet","subGenusAuthorship"};
402
            for(String param : equalParams){
403
                originalSpellingMatchStrategy.setMatchMode(param, MatchMode.EQUAL);
404
            }
405

    
406
            //equal or first
407
            String[] equalOrNullParams = new String[]{"nameApprobation"};
408
            for(String param : equalOrNullParams){
409
                originalSpellingMatchStrategy.setMatchMode(param, MatchMode.EQUAL_OR_FIRST_NULL);
410
            }
411

    
412
            //match
413
            String[] authorMatchParams = new String[]{"combinationAuthorship","basionymAuthorship","exCombinationAuthorship",
414
                    "exBasionymAuthorship","inBasionymAuthorship", "inCombinationAuthorship"};
415
            for(String param : authorMatchParams){
416
                originalSpellingMatchStrategy.setMatchMode(param, MatchMode.MATCH, NewParsedTeamOrPersonInstance());
417
            }
418

    
419
            //match or first
420
            String[] matchOrNullParams = new String[]{"nomenclaturalSource"};
421
            for(String param : matchOrNullParams){
422
                originalSpellingMatchStrategy.setMatchMode(param, MatchMode.MATCH_OR_FIRST_NULL);
423
            }
424

    
425
            //?? should be MatchMode.EQUAL_OR_FIRST_NULL for Collections
426
            String[] ignoreCollectionParams = new String[]{"taxonBases", "typeDesignations", "descriptions", "registrations",
427
                    "relationsFromThisName", "relationsToThisName", "hybridChildRelations", "hybridParentRelations",
428
                    "status"};
429
            for(String param : ignoreCollectionParams){
430
                originalSpellingMatchStrategy.setMatchMode(param, MatchMode.IGNORE);
431
            }
432

    
433
            //ignore
434
            String[] ignoreParams = new String[]{"homotypicalGroup"   //??
435
                    ,"parsingProblem", "problemEnds", "problemStarts"};
436
            for(String param : ignoreParams){
437
                originalSpellingMatchStrategy.setMatchMode(param, MatchMode.IGNORE);
438
            }
439

    
440
            //TODO caches
441

    
442
            return originalSpellingMatchStrategy;
443
        } catch (MatchException e) {
444
            throw new RuntimeException("Exception when creating parsed original spelling match strategy.", e);
445
        }
446
    }
447

    
448
}
(14-14/18)