Project

General

Profile

Download (12 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * 
3
 */
4
package eu.etaxonomy.taxeditor.parser;
5

    
6
import java.util.ArrayList;
7
import java.util.List;
8

    
9
import eu.etaxonomy.cdm.api.service.ICommonService;
10
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
11
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
12
import eu.etaxonomy.cdm.model.name.NonViralName;
13
import eu.etaxonomy.cdm.model.name.Rank;
14
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
15
import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
16
import eu.etaxonomy.cdm.model.reference.Reference;
17
import eu.etaxonomy.cdm.strategy.match.MatchException;
18
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
19
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
20
import eu.etaxonomy.taxeditor.store.CdmStore;
21
import eu.etaxonomy.taxeditor.store.StoreUtil;
22

    
23
/**
24
 * <p>ParseHandler class.</p>
25
 *
26
 * @author n.hoffmann
27
 * @version $Id: $
28
 */
29
public class ParseHandler{
30

    
31
	private TaxonNameBase taxonNameBase;
32
	
33
	private class MatchMatrix {
34
		List<TaxonNameBase> duplicateNames = new ArrayList<TaxonNameBase>();
35
		
36
		List<INomenclaturalReference> duplicateReferences = new ArrayList<INomenclaturalReference>();
37
		List<INomenclaturalReference> duplicateInReferences = new ArrayList<INomenclaturalReference>();
38

    
39
		List<TeamOrPersonBase> duplicateCombinationAuthorTeams = new ArrayList<TeamOrPersonBase>();
40
		List<TeamOrPersonBase> duplicateExCombinationAuthorTeams = new ArrayList<TeamOrPersonBase>();
41
		List<TeamOrPersonBase> duplicateBasionymAuthorTeams = new ArrayList<TeamOrPersonBase>();
42
		List<TeamOrPersonBase> duplicateExBasionymAuthorTeams = new ArrayList<TeamOrPersonBase>();
43
	}
44

    
45
	private static NonViralNameParserImpl nonViralNameParser = NonViralNameParserImpl.NewInstance();
46

    
47
	/**
48
	 * The name that should get parsed
49
	 */
50
	private NonViralName name;
51

    
52
	private boolean doResolveInReferences;
53
	
54
	/**
55
	 * Creates a new instance 
56
	 * 
57
	 * @param textWidget
58
	 * @param name
59
	 */
60
	private ParseHandler(TaxonNameBase name){
61
		if(name == null){
62
			this.name = nonViralNameParser.getNonViralNameInstance("", PreferencesUtil.getPreferredNomenclaturalCode());
63
		}else{
64
			this.name = (NonViralName) HibernateProxyHelper.deproxy(name);
65
		}
66
	}
67
	
68
	/**
69
	 * Factory method to create a new instance of the this class
70
	 *
71
	 * @param textWidget	The text widget where the NonViralName may be entered into
72
	 * @param name			An initial NonViralName or null when creating a new name
73
	 * @return				An instance of this class
74
	 */
75
	public static ParseHandler NewInstance(TaxonNameBase name){
76
		return new ParseHandler(name);
77
		
78
	}
79
	
80
	/**
81
	 * Parses a given string and returns a <code>TaxonNameBase</code> instance with the
82
	 * results of the parsing.
83
	 *
84
	 * This method should be used to quickly create a new name from a string.
85
	 * Wherever the string will be parsed again in subsequent editing, an instance
86
	 * of <code>ParseHandler</code> should be attached to the text widget.
87
	 *
88
	 * @param unparsedNameString a {@link java.lang.String} object.
89
	 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
90
	 */
91
	public static TaxonNameBase parseReferencedName(String unparsedNameString, Rank rank){
92
		TaxonNameBase name = nonViralNameParser.parseReferencedName(unparsedNameString,
93
				PreferencesUtil.getPreferredNomenclaturalCode(), rank);
94

    
95
//		if (name.hasProblem()) {
96
//			name.setFullTitleCache(unparsedNameString);
97
//		}
98
		
99
		return name;
100
	}
101
	
102
	public static TaxonNameBase parseName(String unparsedNameString, Rank rank){
103
		TaxonNameBase name = nonViralNameParser.parseFullName(unparsedNameString,
104
				PreferencesUtil.getPreferredNomenclaturalCode(), rank);
105
		
106
		return name;
107
	}
108
	
109
	/**
110
	 * Creates an empty <code>TaxonNameBase</code> instance with the nomenclatural code
111
	 * currently set in preferences.
112
	 *
113
	 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
114
	 */
115
	public static TaxonNameBase createEmptyName(){
116
		return nonViralNameParser.getNonViralNameInstance("", PreferencesUtil.getPreferredNomenclaturalCode());
117
	}
118
	
119
	/**
120
	 * Parses the string that was entered into the text widget and returns a
121
	 * NonViralName object that resulted from the parsing process.
122
	 *
123
	 * @return	The parsed NonViralName object
124
	 */
125
	public NonViralName parse(String unparsedNameString){
126
		
127
//		String unparsedNameString = "";
128
//		try {
129
//			Method getText;
130
//			getText = textWidget.getClass().getDeclaredMethod("getText", null);
131
//			unparsedNameString = (String) getText.invoke(textWidget, null);
132
//		} catch (Exception e) {
133
//			// we should never get here
134
//			StoreUtil.error(this.getClass(), "Error trying to invoke getText method", e);
135
//		}
136
		
137
		
138
		nonViralNameParser.parseReferencedName(name, unparsedNameString,
139
				name.getRank(), true);
140

    
141
//		if (name.hasProblem()) {
142
//			name.setFullTitleCache(unparsedNameString);
143
//		}
144
		
145
		return name;
146
	}
147
	
148
	/**
149
	 * Parses the string that was entered into the text widget and returns a
150
	 * NonViralName object that resulted from the parsing process.
151
	 *
152
	 * The atomized fields (scientific name, author and reference) will be matched
153
	 * against the database to find possible duplicates. If duplicates were found
154
	 * the respective parts of the NonViralName will be replaced with the found
155
	 * objects.
156
	 *
157
	 * @return	The parsed NonViralName object
158
	 */
159
	public NonViralName parseAndResolveDuplicates(String unparsedNameString){
160
		
161
		NonViralName parsedName = parse(unparsedNameString);
162
		
163
		// FIXME
164
//		MatchMatrix matchMatrix = findMatches(parsedName);
165
//		
166
//		resolveDuplicates(parsedName, matchMatrix);
167
		
168
		return parsedName;
169
	}
170
		
171
	
172
	
173
	
174
	/** 
175
	 * @param name The name to resolve duplicates for.
176
	 */
177
	private void resolveDuplicates(NonViralName name, MatchMatrix matchMatrix) {
178
		resolveDuplicateNames(name, matchMatrix);
179
		
180
		resolveAllDuplicateAuthors(name, matchMatrix);
181
		
182
		resolveDuplicateReferences(name, matchMatrix);
183
		
184
		if(matchMatrix.duplicateInReferences != null)
185
			resolveDuplicateInReferences(name, matchMatrix);
186
	}
187

    
188

    
189
	/** 
190
	 * @param name The name to resolve duplicates for.
191
	 */
192
	private void resolveDuplicateNames(NonViralName name, MatchMatrix matchMatrix) {
193
				
194
		if (matchMatrix.duplicateNames.size() == 1){
195
			name = (NonViralName) matchMatrix.duplicateNames.iterator().next();
196
		}else if(matchMatrix.duplicateNames.size() > 1){
197
			// FIXME TODO resolve multiple duplications. Use first match for a start
198
			name = (NonViralName) matchMatrix.duplicateNames.iterator().next();
199
		}
200
	}
201

    
202
	/** 
203
	 * @param name The name to resolve duplicates for.
204
	 */
205
	private void resolveDuplicateReferences(NonViralName name, MatchMatrix matchMatrix) {
206
		if(matchMatrix.duplicateReferences.size() == 1){
207
			// exactly one match. We assume that the user wants this reference
208
			INomenclaturalReference duplicate = matchMatrix.duplicateReferences.iterator().next();	
209
			name.setNomenclaturalReference(duplicate);
210
		}else if(matchMatrix.duplicateReferences.size() > 1){
211
			// FIXME TODO resolve multiple duplications. Use first match for a start
212
			INomenclaturalReference duplicate = matchMatrix.duplicateReferences.iterator().next();
213
			name.setNomenclaturalReference(duplicate);
214
		}		
215
	}
216

    
217
	/** 
218
	 * @param name The name to resolve duplicates for.
219
	 */
220
	private void resolveDuplicateInReferences(NonViralName name, MatchMatrix matchMatrix) {
221
		Reference reference = (Reference) HibernateProxyHelper.deproxy(name.getNomenclaturalReference());
222
		
223
		if(matchMatrix.duplicateInReferences.size() > 0){
224
			Reference inReference = (Reference) matchMatrix.duplicateInReferences.iterator().next();
225
			reference.setInReference(inReference);
226
			StoreUtil.warn(this.getClass(), reference.generateTitle());
227
			// FIXME TODO resolve multiple duplications. We use first match for a start
228
			StoreUtil.warn(this.getClass(), reference.getTitleCache());
229
		}
230
	}
231
	
232

    
233
	/** 
234
	 * @param name The name to resolve duplicates for.
235
	 */
236
	private void resolveAllDuplicateAuthors(NonViralName name, MatchMatrix matchMatrix) {
237
		
238
		if(matchMatrix.duplicateCombinationAuthorTeams.size() > 0){
239
			name.setCombinationAuthorTeam(matchMatrix.duplicateCombinationAuthorTeams.iterator().next());
240
			Reference reference = (Reference) name.getNomenclaturalReference();
241
			if(reference != null){
242
				reference.setAuthorTeam(matchMatrix.duplicateCombinationAuthorTeams.iterator().next());
243
			}
244
			// FIXME TODO resolve multiple duplications. We use first match for a start.
245
		}
246
		
247
		if(matchMatrix.duplicateExCombinationAuthorTeams.size() > 0){
248
			name.setExCombinationAuthorTeam(matchMatrix.duplicateExCombinationAuthorTeams.iterator().next());
249
			// FIXME TODO resolve multiple duplications. We use first match for a start.
250
		}
251
		
252
		if(matchMatrix.duplicateBasionymAuthorTeams.size() > 0){
253
			name.setBasionymAuthorTeam(matchMatrix.duplicateBasionymAuthorTeams.iterator().next());
254
			// FIXME TODO resolve multiple duplications. We use first match for a start.
255
		}
256
		
257
		if(matchMatrix.duplicateExBasionymAuthorTeams.size() > 0){
258
			name.setExBasionymAuthorTeam(matchMatrix.duplicateExBasionymAuthorTeams.iterator().next());
259
			// FIXME TODO resolve multiple duplications. We use first match for a start.
260
		}
261
	}
262
	
263
	/** 
264
	 * Splits a NonViralName into its parts and calls methods to find matches for these
265
	 * parts in the database.
266
	 * 
267
	 * @param name	The NonViralName to find matches for.
268
	 */
269
	private MatchMatrix findMatches(NonViralName name){
270
		
271
		MatchMatrix matchMatrix = new MatchMatrix();
272
		
273
		matchMatrix.duplicateNames = findMatchingLatinNames(name);
274
		
275
		matchMatrix.duplicateCombinationAuthorTeams = findMatchingAuthors((TeamOrPersonBase) name.getCombinationAuthorTeam());
276
		matchMatrix.duplicateExCombinationAuthorTeams = findMatchingAuthors((TeamOrPersonBase) name.getExCombinationAuthorTeam());
277
		matchMatrix.duplicateBasionymAuthorTeams = findMatchingAuthors((TeamOrPersonBase) name.getBasionymAuthorTeam());
278
		matchMatrix.duplicateExBasionymAuthorTeams = findMatchingAuthors((TeamOrPersonBase) name.getExBasionymAuthorTeam());
279
		
280
		INomenclaturalReference nomenclaturalReference = name.getNomenclaturalReference();
281
		
282
		// check if the reference has an inreference and also check if the inReference already exists 
283
		if(nomenclaturalReference != null){
284
			Reference inReference = ((Reference)nomenclaturalReference).getInReference();
285
			if(inReference != null){
286
				doResolveInReferences = true;
287
				matchMatrix.duplicateInReferences = findMatchingNomenclaturalReference(inReference);
288
			}
289
		}
290
		
291
		matchMatrix.duplicateReferences = findMatchingNomenclaturalReference(nomenclaturalReference);
292
		
293
		return matchMatrix;
294
	}
295
	
296
	/**
297
	 * @param nomenclaturalReference	The NomenclaturalReference to find matches for.
298
	 * @return	A <code>List</code> of possibly matching NomenclaturalReference's.
299
	 */
300
	private List<INomenclaturalReference> findMatchingNomenclaturalReference(INomenclaturalReference nomenclaturalReference) {
301
		if(nomenclaturalReference == null) return new ArrayList<INomenclaturalReference>();
302
		try{
303
			return CdmStore.getService(ICommonService.class).findMatching(nomenclaturalReference, MatchStrategyConfigurator.ReferenceMatchStrategy());
304
		}catch (MatchException e) {
305
			StoreUtil.error(this.getClass(), "Error finding matching references", e);
306
		}
307
		return null;
308
	}
309

    
310
	/**
311
	 * @param authorTeam	The TeamOrPersonBase to find matches for.
312
	 * @return	A <code>List</code> of possibly matching TeamOrPersonBase's.
313
	 */
314
	private List<TeamOrPersonBase> findMatchingAuthors(TeamOrPersonBase authorTeam) {
315

    
316
		if(authorTeam == null){
317
			return new ArrayList<TeamOrPersonBase>();
318
		}
319
		
320
		try{
321
			return CdmStore.getService(ICommonService.class).findMatching(authorTeam, MatchStrategyConfigurator.TeamOrPersonMatchStrategy());
322
		}catch (MatchException e) {
323
			StoreUtil.error(this.getClass(), "Error finding matching authors", e);
324
		}
325
		return null;
326
	}
327

    
328
	/**
329
	 * @param taxonNameBase	The TaxonNameBase to find matches for.
330
	 * @return	A <code>List</code> of possibly matching TaxonNameBase's.
331
	 */
332
	private List<TaxonNameBase> findMatchingLatinNames(TaxonNameBase taxonNameBase) {
333

    
334
		try {
335
			return CdmStore.getService(ICommonService.class).findMatching(taxonNameBase, MatchStrategyConfigurator.NonViralNameMatchStrategy());
336
			
337
		} catch (MatchException e) {
338
			StoreUtil.error(this.getClass(), "Error finding matching names", e);
339
		}
340
		return null;
341
	}
342
}
(2-2/2)