4 package eu
.etaxonomy
.taxeditor
.parser
;
6 import java
.util
.ArrayList
;
9 import eu
.etaxonomy
.cdm
.hibernate
.HibernateProxyHelper
;
10 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
11 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
12 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
13 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
14 import eu
.etaxonomy
.cdm
.model
.reference
.INomenclaturalReference
;
15 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
16 import eu
.etaxonomy
.cdm
.strategy
.match
.MatchException
;
17 import eu
.etaxonomy
.cdm
.strategy
.match
.MatchStrategyConfigurator
.MatchStrategy
;
18 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImpl
;
19 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
20 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
21 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
24 * <p>ParseHandler class.</p>
29 public class ParseHandler
{
31 private TaxonNameBase taxonNameBase
;
33 private class MatchMatrix
{
34 List
<TaxonNameBase
> duplicateNames
= new ArrayList
<TaxonNameBase
>();
36 List
<INomenclaturalReference
> duplicateReferences
= new ArrayList
<INomenclaturalReference
>();
37 List
<INomenclaturalReference
> duplicateInReferences
= new ArrayList
<INomenclaturalReference
>();
39 List
<TeamOrPersonBase
> duplicateCombinationAuthorships
= new ArrayList
<TeamOrPersonBase
>();
40 List
<TeamOrPersonBase
> duplicateExCombinationAuthorships
= new ArrayList
<TeamOrPersonBase
>();
41 List
<TeamOrPersonBase
> duplicateBasionymAuthorships
= new ArrayList
<TeamOrPersonBase
>();
42 List
<TeamOrPersonBase
> duplicateExBasionymAuthorships
= new ArrayList
<TeamOrPersonBase
>();
45 private static NonViralNameParserImpl nonViralNameParser
= NonViralNameParserImpl
.NewInstance();
48 * The name that should get parsed
50 private NonViralName name
;
52 private boolean doResolveInReferences
;
55 * Creates a new instance
60 private ParseHandler(TaxonNameBase name
){
62 this.name
= nonViralNameParser
.getNonViralNameInstance("", PreferencesUtil
.getPreferredNomenclaturalCode());
64 this.name
= (NonViralName
) HibernateProxyHelper
.deproxy(name
);
69 * Factory method to create a new instance of the this class
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
75 public static ParseHandler
NewInstance(TaxonNameBase name
){
76 return new ParseHandler(name
);
81 * Parses a given string and returns a <code>TaxonNameBase</code> instance with the
82 * results of the parsing.
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.
88 * @param unparsedNameString a {@link java.lang.String} object.
89 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
91 public static NonViralName
parseReferencedName(String unparsedNameString
, Rank rank
){
92 NonViralName name
= nonViralNameParser
.parseReferencedName(unparsedNameString
,
93 PreferencesUtil
.getPreferredNomenclaturalCode(), rank
);
95 // if (name.hasProblem()) {
96 // name.setFullTitleCache(unparsedNameString);
102 public static NonViralName
parseName(String unparsedNameString
, Rank rank
){
103 NonViralName name
= nonViralNameParser
.parseFullName(unparsedNameString
,
104 PreferencesUtil
.getPreferredNomenclaturalCode(), rank
);
110 * Creates an empty <code>TaxonNameBase</code> instance with the nomenclatural code
111 * currently set in preferences.
113 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
115 public static NonViralName
createEmptyName(){
116 return nonViralNameParser
.getNonViralNameInstance("", PreferencesUtil
.getPreferredNomenclaturalCode());
120 * Parses the string that was entered into the text widget and returns a
121 * NonViralName object that resulted from the parsing process.
123 * @return The parsed NonViralName object
125 public NonViralName
parse(String unparsedNameString
){
127 // String unparsedNameString = "";
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);
138 nonViralNameParser
.parseReferencedName(name
, unparsedNameString
,
139 name
.getRank(), true);
141 // if (name.hasProblem()) {
142 // name.setFullTitleCache(unparsedNameString);
149 * Parses the string that was entered into the text widget and returns a
150 * NonViralName object that resulted from the parsing process.
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
157 * @return The parsed NonViralName object
159 public NonViralName
parseAndResolveDuplicates(String unparsedNameString
){
161 NonViralName parsedName
= parse(unparsedNameString
);
163 MatchMatrix matchMatrix
= findMatches(parsedName
);
165 resolveDuplicates(parsedName
, matchMatrix
);
174 * @param name The name to resolve duplicates for.
176 private void resolveDuplicates(NonViralName name
, MatchMatrix matchMatrix
) {
177 resolveDuplicateNames(name
, matchMatrix
);
179 resolveAllDuplicateAuthors(name
, matchMatrix
);
181 resolveDuplicateReferences(name
, matchMatrix
);
183 if(matchMatrix
.duplicateInReferences
!= null) {
184 resolveDuplicateInReferences(name
, matchMatrix
);
190 * @param name The name to resolve duplicates for.
192 private void resolveDuplicateNames(NonViralName name
, MatchMatrix matchMatrix
) {
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();
203 * @param name The name to resolve duplicates for.
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
);
218 * @param name The name to resolve duplicates for.
220 private void resolveDuplicateInReferences(NonViralName name
, MatchMatrix matchMatrix
) {
221 Reference reference
= (Reference
) HibernateProxyHelper
.deproxy(name
.getNomenclaturalReference());
223 if(matchMatrix
.duplicateInReferences
.size() > 0){
224 Reference inReference
= (Reference
) matchMatrix
.duplicateInReferences
.iterator().next();
225 reference
.setInReference(inReference
);
226 MessagingUtils
.warn(this.getClass(), reference
.generateTitle());
227 // FIXME TODO resolve multiple duplications. We use first match for a start
228 MessagingUtils
.warn(this.getClass(), reference
.getTitleCache());
234 * @param name The name to resolve duplicates for.
236 private void resolveAllDuplicateAuthors(NonViralName name
, MatchMatrix matchMatrix
) {
238 if(matchMatrix
.duplicateCombinationAuthorships
.size() > 0){
239 name
.setCombinationAuthorship(matchMatrix
.duplicateCombinationAuthorships
.iterator().next());
240 Reference reference
= (Reference
) name
.getNomenclaturalReference();
241 if(reference
!= null){
242 reference
.setAuthorship(matchMatrix
.duplicateCombinationAuthorships
.iterator().next());
244 // FIXME TODO resolve multiple duplications. We use first match for a start.
247 if(matchMatrix
.duplicateExCombinationAuthorships
.size() > 0){
248 name
.setExCombinationAuthorship(matchMatrix
.duplicateExCombinationAuthorships
.iterator().next());
249 // FIXME TODO resolve multiple duplications. We use first match for a start.
252 if(matchMatrix
.duplicateBasionymAuthorships
.size() > 0){
253 name
.setBasionymAuthorship(matchMatrix
.duplicateBasionymAuthorships
.iterator().next());
254 // FIXME TODO resolve multiple duplications. We use first match for a start.
257 if(matchMatrix
.duplicateExBasionymAuthorships
.size() > 0){
258 name
.setExBasionymAuthorship(matchMatrix
.duplicateExBasionymAuthorships
.iterator().next());
259 // FIXME TODO resolve multiple duplications. We use first match for a start.
264 * Splits a NonViralName into its parts and calls methods to find matches for these
265 * parts in the database.
267 * @param name The NonViralName to find matches for.
269 private MatchMatrix
findMatches(NonViralName name
){
271 MatchMatrix matchMatrix
= new MatchMatrix();
273 matchMatrix
.duplicateNames
= findMatchingLatinNames(name
);
275 matchMatrix
.duplicateCombinationAuthorships
= findMatchingAuthors(name
.getCombinationAuthorship());
276 matchMatrix
.duplicateExCombinationAuthorships
= findMatchingAuthors(name
.getExCombinationAuthorship());
277 matchMatrix
.duplicateBasionymAuthorships
= findMatchingAuthors(name
.getBasionymAuthorship());
278 matchMatrix
.duplicateExBasionymAuthorships
= findMatchingAuthors(name
.getExBasionymAuthorship());
280 INomenclaturalReference nomenclaturalReference
= name
.getNomenclaturalReference();
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
);
291 matchMatrix
.duplicateReferences
= findMatchingNomenclaturalReference(nomenclaturalReference
);
297 * @param nomenclaturalReference The NomenclaturalReference to find matches for.
298 * @return A <code>List</code> of possibly matching NomenclaturalReference's.
300 private List
<INomenclaturalReference
> findMatchingNomenclaturalReference(INomenclaturalReference nomenclaturalReference
) {
301 if(nomenclaturalReference
== null) {
302 return new ArrayList
<INomenclaturalReference
>();
306 return CdmStore
.getCommonService().findMatching(nomenclaturalReference
, MatchStrategy
.Reference
);
308 }catch (MatchException e
) {
309 MessagingUtils
.error(this.getClass(), "Error finding matching references", e
);
315 * @param authorTeam The TeamOrPersonBase to find matches for.
316 * @return A <code>List</code> of possibly matching TeamOrPersonBase's.
318 private List
<TeamOrPersonBase
> findMatchingAuthors(TeamOrPersonBase authorTeam
) {
320 if(authorTeam
== null){
321 return new ArrayList
<TeamOrPersonBase
>();
326 return CdmStore
.getCommonService().findMatching(authorTeam
, MatchStrategy
.TeamOrPerson
);
328 }catch (MatchException e
) {
329 MessagingUtils
.error(this.getClass(), "Error finding matching authors", e
);
335 * @param taxonNameBase The TaxonNameBase to find matches for.
336 * @return A <code>List</code> of possibly matching TaxonNameBase's.
338 private List
<TaxonNameBase
> findMatchingLatinNames(TaxonNameBase taxonNameBase
) {
342 return CdmStore
.getCommonService().findMatching(taxonNameBase
, MatchStrategy
.NonViralName
);
345 } catch (MatchException e
) {
346 MessagingUtils
.error(this.getClass(), "Error finding matching names", e
);