4 package eu
.etaxonomy
.taxeditor
.parser
;
6 import java
.util
.ArrayList
;
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
.match
.MatchStrategyConfigurator
.MatchStrategy
;
19 import eu
.etaxonomy
.cdm
.strategy
.parser
.NonViralNameParserImpl
;
20 import eu
.etaxonomy
.taxeditor
.model
.MessagingUtils
;
21 import eu
.etaxonomy
.taxeditor
.preference
.PreferencesUtil
;
22 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
25 * <p>ParseHandler class.</p>
30 public class ParseHandler
{
32 private TaxonNameBase taxonNameBase
;
34 private class MatchMatrix
{
35 List
<TaxonNameBase
> duplicateNames
= new ArrayList
<TaxonNameBase
>();
37 List
<INomenclaturalReference
> duplicateReferences
= new ArrayList
<INomenclaturalReference
>();
38 List
<INomenclaturalReference
> duplicateInReferences
= new ArrayList
<INomenclaturalReference
>();
40 List
<TeamOrPersonBase
> duplicateCombinationAuthorTeams
= new ArrayList
<TeamOrPersonBase
>();
41 List
<TeamOrPersonBase
> duplicateExCombinationAuthorTeams
= new ArrayList
<TeamOrPersonBase
>();
42 List
<TeamOrPersonBase
> duplicateBasionymAuthorTeams
= new ArrayList
<TeamOrPersonBase
>();
43 List
<TeamOrPersonBase
> duplicateExBasionymAuthorTeams
= new ArrayList
<TeamOrPersonBase
>();
46 private static NonViralNameParserImpl nonViralNameParser
= NonViralNameParserImpl
.NewInstance();
49 * The name that should get parsed
51 private NonViralName name
;
53 private boolean doResolveInReferences
;
56 * Creates a new instance
61 private ParseHandler(TaxonNameBase name
){
63 this.name
= nonViralNameParser
.getNonViralNameInstance("", PreferencesUtil
.getPreferredNomenclaturalCode());
65 this.name
= (NonViralName
) HibernateProxyHelper
.deproxy(name
);
70 * Factory method to create a new instance of the this class
72 * @param textWidget The text widget where the NonViralName may be entered into
73 * @param name An initial NonViralName or null when creating a new name
74 * @return An instance of this class
76 public static ParseHandler
NewInstance(TaxonNameBase name
){
77 return new ParseHandler(name
);
82 * Parses a given string and returns a <code>TaxonNameBase</code> instance with the
83 * results of the parsing.
85 * This method should be used to quickly create a new name from a string.
86 * Wherever the string will be parsed again in subsequent editing, an instance
87 * of <code>ParseHandler</code> should be attached to the text widget.
89 * @param unparsedNameString a {@link java.lang.String} object.
90 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
92 public static TaxonNameBase
parseReferencedName(String unparsedNameString
, Rank rank
){
93 TaxonNameBase name
= nonViralNameParser
.parseReferencedName(unparsedNameString
,
94 PreferencesUtil
.getPreferredNomenclaturalCode(), rank
);
96 // if (name.hasProblem()) {
97 // name.setFullTitleCache(unparsedNameString);
103 public static TaxonNameBase
parseName(String unparsedNameString
, Rank rank
){
104 TaxonNameBase name
= nonViralNameParser
.parseFullName(unparsedNameString
,
105 PreferencesUtil
.getPreferredNomenclaturalCode(), rank
);
111 * Creates an empty <code>TaxonNameBase</code> instance with the nomenclatural code
112 * currently set in preferences.
114 * @return a {@link eu.etaxonomy.cdm.model.name.TaxonNameBase} object.
116 public static TaxonNameBase
createEmptyName(){
117 return nonViralNameParser
.getNonViralNameInstance("", PreferencesUtil
.getPreferredNomenclaturalCode());
121 * Parses the string that was entered into the text widget and returns a
122 * NonViralName object that resulted from the parsing process.
124 * @return The parsed NonViralName object
126 public NonViralName
parse(String unparsedNameString
){
128 // String unparsedNameString = "";
131 // getText = textWidget.getClass().getDeclaredMethod("getText", null);
132 // unparsedNameString = (String) getText.invoke(textWidget, null);
133 // } catch (Exception e) {
134 // // we should never get here
135 // StoreUtil.error(this.getClass(), "Error trying to invoke getText method", e);
139 nonViralNameParser
.parseReferencedName(name
, unparsedNameString
,
140 name
.getRank(), true);
142 // if (name.hasProblem()) {
143 // name.setFullTitleCache(unparsedNameString);
150 * Parses the string that was entered into the text widget and returns a
151 * NonViralName object that resulted from the parsing process.
153 * The atomized fields (scientific name, author and reference) will be matched
154 * against the database to find possible duplicates. If duplicates were found
155 * the respective parts of the NonViralName will be replaced with the found
158 * @return The parsed NonViralName object
160 public NonViralName
parseAndResolveDuplicates(String unparsedNameString
){
162 NonViralName parsedName
= parse(unparsedNameString
);
164 MatchMatrix matchMatrix
= findMatches(parsedName
);
166 resolveDuplicates(parsedName
, matchMatrix
);
175 * @param name The name to resolve duplicates for.
177 private void resolveDuplicates(NonViralName name
, MatchMatrix matchMatrix
) {
178 resolveDuplicateNames(name
, matchMatrix
);
180 resolveAllDuplicateAuthors(name
, matchMatrix
);
182 resolveDuplicateReferences(name
, matchMatrix
);
184 if(matchMatrix
.duplicateInReferences
!= null) {
185 resolveDuplicateInReferences(name
, matchMatrix
);
191 * @param name The name to resolve duplicates for.
193 private void resolveDuplicateNames(NonViralName name
, MatchMatrix matchMatrix
) {
195 if (matchMatrix
.duplicateNames
.size() == 1){
196 name
= (NonViralName
) matchMatrix
.duplicateNames
.iterator().next();
197 }else if(matchMatrix
.duplicateNames
.size() > 1){
198 // FIXME TODO resolve multiple duplications. Use first match for a start
199 name
= (NonViralName
) matchMatrix
.duplicateNames
.iterator().next();
204 * @param name The name to resolve duplicates for.
206 private void resolveDuplicateReferences(NonViralName name
, MatchMatrix matchMatrix
) {
207 if(matchMatrix
.duplicateReferences
.size() == 1){
208 // exactly one match. We assume that the user wants this reference
209 INomenclaturalReference duplicate
= matchMatrix
.duplicateReferences
.iterator().next();
210 name
.setNomenclaturalReference(duplicate
);
211 }else if(matchMatrix
.duplicateReferences
.size() > 1){
212 // FIXME TODO resolve multiple duplications. Use first match for a start
213 INomenclaturalReference duplicate
= matchMatrix
.duplicateReferences
.iterator().next();
214 name
.setNomenclaturalReference(duplicate
);
219 * @param name The name to resolve duplicates for.
221 private void resolveDuplicateInReferences(NonViralName name
, MatchMatrix matchMatrix
) {
222 Reference reference
= (Reference
) HibernateProxyHelper
.deproxy(name
.getNomenclaturalReference());
224 if(matchMatrix
.duplicateInReferences
.size() > 0){
225 Reference inReference
= (Reference
) matchMatrix
.duplicateInReferences
.iterator().next();
226 reference
.setInReference(inReference
);
227 MessagingUtils
.warn(this.getClass(), reference
.generateTitle());
228 // FIXME TODO resolve multiple duplications. We use first match for a start
229 MessagingUtils
.warn(this.getClass(), reference
.getTitleCache());
235 * @param name The name to resolve duplicates for.
237 private void resolveAllDuplicateAuthors(NonViralName name
, MatchMatrix matchMatrix
) {
239 if(matchMatrix
.duplicateCombinationAuthorTeams
.size() > 0){
240 name
.setCombinationAuthorTeam(matchMatrix
.duplicateCombinationAuthorTeams
.iterator().next());
241 Reference reference
= (Reference
) name
.getNomenclaturalReference();
242 if(reference
!= null){
243 reference
.setAuthorship(matchMatrix
.duplicateCombinationAuthorTeams
.iterator().next());
245 // FIXME TODO resolve multiple duplications. We use first match for a start.
248 if(matchMatrix
.duplicateExCombinationAuthorTeams
.size() > 0){
249 name
.setExCombinationAuthorTeam(matchMatrix
.duplicateExCombinationAuthorTeams
.iterator().next());
250 // FIXME TODO resolve multiple duplications. We use first match for a start.
253 if(matchMatrix
.duplicateBasionymAuthorTeams
.size() > 0){
254 name
.setBasionymAuthorTeam(matchMatrix
.duplicateBasionymAuthorTeams
.iterator().next());
255 // FIXME TODO resolve multiple duplications. We use first match for a start.
258 if(matchMatrix
.duplicateExBasionymAuthorTeams
.size() > 0){
259 name
.setExBasionymAuthorTeam(matchMatrix
.duplicateExBasionymAuthorTeams
.iterator().next());
260 // FIXME TODO resolve multiple duplications. We use first match for a start.
265 * Splits a NonViralName into its parts and calls methods to find matches for these
266 * parts in the database.
268 * @param name The NonViralName to find matches for.
270 private MatchMatrix
findMatches(NonViralName name
){
272 MatchMatrix matchMatrix
= new MatchMatrix();
274 matchMatrix
.duplicateNames
= findMatchingLatinNames(name
);
276 matchMatrix
.duplicateCombinationAuthorTeams
= findMatchingAuthors(name
.getCombinationAuthorTeam());
277 matchMatrix
.duplicateExCombinationAuthorTeams
= findMatchingAuthors(name
.getExCombinationAuthorTeam());
278 matchMatrix
.duplicateBasionymAuthorTeams
= findMatchingAuthors(name
.getBasionymAuthorTeam());
279 matchMatrix
.duplicateExBasionymAuthorTeams
= findMatchingAuthors(name
.getExBasionymAuthorTeam());
281 INomenclaturalReference nomenclaturalReference
= name
.getNomenclaturalReference();
283 // check if the reference has an inreference and also check if the inReference already exists
284 if(nomenclaturalReference
!= null){
285 Reference inReference
= ((Reference
)nomenclaturalReference
).getInReference();
286 if(inReference
!= null){
287 doResolveInReferences
= true;
288 matchMatrix
.duplicateInReferences
= findMatchingNomenclaturalReference(inReference
);
292 matchMatrix
.duplicateReferences
= findMatchingNomenclaturalReference(nomenclaturalReference
);
298 * @param nomenclaturalReference The NomenclaturalReference to find matches for.
299 * @return A <code>List</code> of possibly matching NomenclaturalReference's.
301 private List
<INomenclaturalReference
> findMatchingNomenclaturalReference(INomenclaturalReference nomenclaturalReference
) {
302 if(nomenclaturalReference
== null) {
303 return new ArrayList
<INomenclaturalReference
>();
306 return CdmStore
.getService(ICommonService
.class).findMatching(nomenclaturalReference
, MatchStrategy
.Reference
);
307 }catch (MatchException e
) {
308 MessagingUtils
.error(this.getClass(), "Error finding matching references", e
);
314 * @param authorTeam The TeamOrPersonBase to find matches for.
315 * @return A <code>List</code> of possibly matching TeamOrPersonBase's.
317 private List
<TeamOrPersonBase
> findMatchingAuthors(TeamOrPersonBase authorTeam
) {
319 if(authorTeam
== null){
320 return new ArrayList
<TeamOrPersonBase
>();
324 return CdmStore
.getService(ICommonService
.class).findMatching(authorTeam
, MatchStrategy
.TeamOrPerson
);
325 }catch (MatchException e
) {
326 MessagingUtils
.error(this.getClass(), "Error finding matching authors", e
);
332 * @param taxonNameBase The TaxonNameBase to find matches for.
333 * @return A <code>List</code> of possibly matching TaxonNameBase's.
335 private List
<TaxonNameBase
> findMatchingLatinNames(TaxonNameBase taxonNameBase
) {
338 return CdmStore
.getService(ICommonService
.class).findMatching(taxonNameBase
, MatchStrategy
.NonViralName
);
340 } catch (MatchException e
) {
341 MessagingUtils
.error(this.getClass(), "Error finding matching names", e
);