Revision cd602b47
Added by Andreas Müller about 7 years ago
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/common/IoResultBase.java | ||
---|---|---|
20 | 20 |
*/ |
21 | 21 |
public abstract class IoResultBase { |
22 | 22 |
|
23 |
private List<Error> errors = new ArrayList<>();
|
|
24 |
private List<String> warnings = new ArrayList<>();
|
|
25 |
private List<Error> exceptions = new ArrayList<>();
|
|
23 |
private List<IoInfo> ioInfos = new ArrayList<>();
|
|
24 |
private List<IoInfo> warnings = new ArrayList<>();
|
|
25 |
private List<IoInfo> exceptions = new ArrayList<>();
|
|
26 | 26 |
|
27 |
public class Error{
|
|
27 |
public class IoInfo{
|
|
28 | 28 |
String message; |
29 | 29 |
Exception exception; |
30 |
private Error(String msg, Exception e){this.message = msg; this.exception = e;} |
|
30 |
String location; |
|
31 |
private IoInfo(String msg, Exception e){ |
|
32 |
this.message = msg; |
|
33 |
this.exception = e; |
|
34 |
} |
|
35 |
private IoInfo(String msg, Exception e, String location){ |
|
36 |
this.message = msg; |
|
37 |
this.exception = e; |
|
38 |
this.location = location; |
|
39 |
} |
|
31 | 40 |
|
32 | 41 |
public String getMessage(){ |
33 | 42 |
return message; |
... | ... | |
40 | 49 |
|
41 | 50 |
// ************* GETTERS / SETTERS / ADDERS ***********************/ |
42 | 51 |
|
43 |
public List<Error> getErrors() {return errors;}
|
|
44 |
public void setErrors(List<Error> errors) {this.errors = errors;}
|
|
52 |
public List<IoInfo> getErrors() {return ioInfos;}
|
|
53 |
public void setErrors(List<IoInfo> ioInfos) {this.ioInfos = ioInfos;}
|
|
45 | 54 |
public void addError(String error) { |
46 |
errors.add(new Error(error, null));
|
|
55 |
ioInfos.add(new IoInfo(error, null));
|
|
47 | 56 |
} |
48 | 57 |
public void addError(String error, Exception e) { |
49 |
errors.add(new Error(error, e)); |
|
58 |
ioInfos.add(new IoInfo(error, e)); |
|
59 |
} |
|
60 |
public void addError(String message, int location) { |
|
61 |
ioInfos.add(new IoInfo(message, null, String.valueOf(location))); |
|
50 | 62 |
} |
51 | 63 |
|
52 |
public List<String> getWarnings() {return warnings;}
|
|
53 |
public void setWarnings(List<String> warnings) {this.warnings = warnings;}
|
|
64 |
public List<IoInfo> getWarnings() {return warnings;}
|
|
65 |
public void setWarnings(List<IoInfo> warnings) {this.warnings = warnings;}
|
|
54 | 66 |
public void addWarning(String warning) { |
55 | 67 |
// warnings.add(warning.getBytes(StandardCharsets.UTF_8)); |
56 |
warnings.add(warning); |
|
68 |
warnings.add(new IoInfo(warning, null)); |
|
69 |
} |
|
70 |
public void addWarning(String message, int location) { |
|
71 |
warnings.add(new IoInfo(message, null, String.valueOf(location))); |
|
57 | 72 |
} |
58 | 73 |
|
59 |
public List<Error> getExceptions() {return exceptions;}
|
|
60 |
public void setExceptions(List<Error> exceptions) {this.exceptions = exceptions;}
|
|
74 |
public List<IoInfo> getExceptions() {return exceptions;}
|
|
75 |
public void setExceptions(List<IoInfo> exceptions) {this.exceptions = exceptions;}
|
|
61 | 76 |
public void addException(Exception e) { |
62 |
exceptions.add(new Error(null, e));
|
|
77 |
exceptions.add(new IoInfo(null, e));
|
|
63 | 78 |
setExceptionState(); |
64 | 79 |
} |
65 | 80 |
public void addException(Exception e, String message) { |
66 |
exceptions.add(new Error(message, e));
|
|
81 |
exceptions.add(new IoInfo(message, e));
|
|
67 | 82 |
setExceptionState(); |
68 | 83 |
} |
69 | 84 |
|
... | ... | |
85 | 100 |
*/ |
86 | 101 |
public StringBuffer createReport() { |
87 | 102 |
StringBuffer report = new StringBuffer(""); |
88 |
addErrorReport(report, "Errors", errors);
|
|
103 |
addErrorReport(report, "Errors", ioInfos);
|
|
89 | 104 |
addErrorReport(report, "Exceptions", exceptions); |
90 |
addWarnings(report, "Warnings", warnings);
|
|
105 |
addErrorReport(report, "Warnings", warnings);
|
|
91 | 106 |
return report; |
92 | 107 |
} |
108 |
// /** |
|
109 |
// * @param report |
|
110 |
// * @param string |
|
111 |
// * @param warnings2 |
|
112 |
// */ |
|
113 |
// private void addWarnings(StringBuffer report, String label, List<String> list) { |
|
114 |
// if (!list.isEmpty()){ |
|
115 |
// report.append("\n\n" + label + ":\n" + StringUtils.leftPad("", label.length()+1, "=")); |
|
116 |
// for (String warning : list){ |
|
117 |
// String str = String.valueOf(warning); |
|
118 |
// report.append("\n" + str); |
|
119 |
// } |
|
120 |
// } |
|
121 |
// } |
|
122 |
|
|
93 | 123 |
/** |
94 | 124 |
* @param report |
95 |
* @param string |
|
96 |
* @param warnings2 |
|
97 |
*/ |
|
98 |
private void addWarnings(StringBuffer report, String label, List<String> list) { |
|
99 |
if (!list.isEmpty()){ |
|
100 |
report.append("\n\n" + label + ":\n" + StringUtils.leftPad("", label.length()+1, "=")); |
|
101 |
for (String warning : list){ |
|
102 |
String str = String.valueOf(warning); |
|
103 |
report.append("\n" + str); |
|
104 |
} |
|
105 |
} |
|
106 |
} |
|
107 |
/** |
|
108 |
* @param report |
|
109 |
* @param string |
|
110 |
* @param newRecords2 |
|
125 |
* @param label |
|
126 |
* @param list |
|
111 | 127 |
*/ |
112 |
private void addErrorReport(StringBuffer report, String label, List<Error> list) {
|
|
113 |
if (!errors.isEmpty()){
|
|
128 |
private void addErrorReport(StringBuffer report, String label, List<IoInfo> list) {
|
|
129 |
if (!ioInfos.isEmpty()){
|
|
114 | 130 |
report.append("\n\n" + label + ":\n" + StringUtils.leftPad("", label.length()+1, "=")); |
115 |
for (Error error : list){ |
|
116 |
String message = error.message != null ? error.message : error.exception != null ? error.exception.getMessage() : ""; |
|
131 |
for (IoInfo ioInfo : list){ |
|
132 |
String location = ioInfo.location == null ? "" : (ioInfo.location + ": "); |
|
133 |
String message = ioInfo.message != null ? ioInfo.message : ioInfo.exception != null ? ioInfo.exception.getMessage() : ""; |
|
117 | 134 |
message = StringUtils.isBlank(message)? "no message" : message; |
118 |
Object stacktrace = error.exception.getStackTrace();
|
|
135 |
Object stacktrace = ioInfo.exception.getStackTrace();
|
|
119 | 136 |
String available = (stacktrace == null ? " not" : ""); |
120 |
report.append("\n" + message + "(stacktrace" + available + ")"); |
|
137 |
report.append("\n" + location + message + "(stacktrace" + available + ")");
|
|
121 | 138 |
} |
122 | 139 |
} |
123 | 140 |
} |
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/reference/ris/in/RisRecordReader.java | ||
---|---|---|
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.reference.ris.in; |
|
10 |
|
|
11 |
import java.io.BufferedReader; |
|
12 |
import java.io.IOException; |
|
13 |
import java.io.InputStreamReader; |
|
14 |
import java.util.HashMap; |
|
15 |
import java.util.Map; |
|
16 |
|
|
17 |
import org.apache.commons.lang3.StringUtils; |
|
18 |
|
|
19 |
/** |
|
20 |
* @author a.mueller |
|
21 |
* @date 11.05.2017 |
|
22 |
* |
|
23 |
*/ |
|
24 |
public class RisRecordReader { |
|
25 |
|
|
26 |
private BufferedReader lineReader; |
|
27 |
private RisReferenceImportState state; |
|
28 |
private int lineNo = 0; |
|
29 |
private String lineNoStr; |
|
30 |
|
|
31 |
public static final Map<RisReferenceTag, String> EOF = new HashMap<>(); |
|
32 |
private static final String NL = "\n"; |
|
33 |
|
|
34 |
|
|
35 |
/** |
|
36 |
* @param baseReader |
|
37 |
*/ |
|
38 |
public RisRecordReader(RisReferenceImportState state, InputStreamReader inputReader) { |
|
39 |
lineReader = new BufferedReader(inputReader); |
|
40 |
this.state = state; |
|
41 |
} |
|
42 |
|
|
43 |
public Map<RisReferenceTag, String> readRecord(){ |
|
44 |
try { |
|
45 |
Map<RisReferenceTag, String> result = new HashMap<>(); |
|
46 |
String line; |
|
47 |
int count = 0; |
|
48 |
boolean started = false; |
|
49 |
RisReferenceTag lastType = null; |
|
50 |
while ((line = lineReader.readLine()) != null) { |
|
51 |
lineNo++; |
|
52 |
if (isBlank(line)){ |
|
53 |
continue; |
|
54 |
} |
|
55 |
RisReferenceTag type; |
|
56 |
if (matchesRisLine(line)){ |
|
57 |
type = RisReferenceTag.TY; |
|
58 |
if (isTypeLine(line)){ |
|
59 |
type = RisReferenceTag.TY; |
|
60 |
result.put(type, replaceTag(line)); |
|
61 |
count++; |
|
62 |
}else if (isErLine(line)){ |
|
63 |
return result; |
|
64 |
}else{ |
|
65 |
//TODO |
|
66 |
try { |
|
67 |
type = RisReferenceTag.valueOf(line.substring(0, 2)); |
|
68 |
} catch (Exception e) { |
|
69 |
//type stays null |
|
70 |
} |
|
71 |
if (type == null){ |
|
72 |
//TODO |
|
73 |
//Sollte aber als als extension trotzdem übergeben werden |
|
74 |
String message = "Unknown reference type %s . Reference attribute could not be added"; |
|
75 |
state.getResult().addWarning(message, lineNo); |
|
76 |
}else{ |
|
77 |
result.put(type, replaceTag(line)); |
|
78 |
} |
|
79 |
count++; |
|
80 |
} |
|
81 |
if (type != null){ |
|
82 |
lastType = type; |
|
83 |
} |
|
84 |
}else{ |
|
85 |
if (started){ |
|
86 |
//add to prior |
|
87 |
String prior = result.get(lastType); |
|
88 |
result.put(lastType, prior + NL + line); |
|
89 |
}else{ |
|
90 |
String message = lineNoStr + "RIS record does not start with TY. Can't create record"; |
|
91 |
state.getResult().addError(message, lineNo); |
|
92 |
} |
|
93 |
|
|
94 |
} |
|
95 |
} |
|
96 |
if (count>0){ |
|
97 |
String message = lineNoStr + "Unexpected end of file. Some records may not have been imported"; |
|
98 |
state.getResult().addError(message, lineNo); |
|
99 |
} |
|
100 |
return EOF; |
|
101 |
|
|
102 |
} catch (IOException e) { |
|
103 |
String message = "Unexpected exception during RIS Reference Import"; |
|
104 |
state.getResult().addException(e, message); |
|
105 |
return EOF; |
|
106 |
} |
|
107 |
} |
|
108 |
|
|
109 |
|
|
110 |
/** |
|
111 |
* @param line |
|
112 |
* @return |
|
113 |
*/ |
|
114 |
private String replaceTag(String line) { |
|
115 |
return line.substring(5).trim(); |
|
116 |
} |
|
117 |
|
|
118 |
|
|
119 |
private static final String risLineReStr = "[A-Z1-9]{2}\\s\\s-\\s.*"; |
|
120 |
private static final String typeLineReStr = "TY\\s\\s-\\s.*"; |
|
121 |
private static final String erLineReStr = "ER\\s\\s-\\s+"; |
|
122 |
|
|
123 |
|
|
124 |
/** |
|
125 |
* @param line |
|
126 |
* @return |
|
127 |
*/ |
|
128 |
private boolean isErLine(String line) { |
|
129 |
return line.matches(erLineReStr); |
|
130 |
} |
|
131 |
|
|
132 |
|
|
133 |
/** |
|
134 |
* @param line |
|
135 |
* @return |
|
136 |
*/ |
|
137 |
private boolean isTypeLine(String line) { |
|
138 |
return line.matches(typeLineReStr); |
|
139 |
} |
|
140 |
|
|
141 |
|
|
142 |
/** |
|
143 |
* @param line |
|
144 |
* @return |
|
145 |
*/ |
|
146 |
private boolean matchesRisLine(String line) { |
|
147 |
return line.matches(risLineReStr); |
|
148 |
} |
|
149 |
|
|
150 |
private boolean isBlank(String str){ |
|
151 |
return StringUtils.isBlank(str); |
|
152 |
} |
|
153 |
} |
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/reference/ris/in/RisRecordType.java | ||
---|---|---|
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.reference.ris.in; |
|
10 |
|
|
11 |
import eu.etaxonomy.cdm.model.reference.ReferenceType; |
|
12 |
|
|
13 |
/** |
|
14 |
* @author a.mueller |
|
15 |
* @date 12.05.2017 |
|
16 |
* |
|
17 |
*/ |
|
18 |
public enum RisRecordType { |
|
19 |
AGGR("Aggregated Database" , ReferenceType.Database ), |
|
20 |
ANCIENT("Ancient Text" ), |
|
21 |
ART("Art Work" ), |
|
22 |
BILL("Bill" ), |
|
23 |
BLOG("Blog" ), |
|
24 |
BOOK("Whole book" , ReferenceType.Book ), |
|
25 |
CASE("Case" ), |
|
26 |
CHAP("Book chapter" , ReferenceType.BookSection ), |
|
27 |
CHART("Chart" ), |
|
28 |
CLSWK("Classical Work" ), |
|
29 |
COMP("Computer program" ), |
|
30 |
CONF("Conference proceeding" , ReferenceType.InProceedings ), |
|
31 |
CPAPER("Conference paper" ), |
|
32 |
CTLG("Catalog" ), |
|
33 |
DATA("Data file" ), |
|
34 |
DBASE("Online Database" , ReferenceType.Database ), |
|
35 |
DICT("Dictionary" ), |
|
36 |
EBOOK("Electronic Book" ), |
|
37 |
ECHAP("Electronic Book Section" ), |
|
38 |
EDBOOK("Edited Book" , ReferenceType.Book ), |
|
39 |
EJOUR("Electronic Article" ), |
|
40 |
ELEC("Web Page" , ReferenceType.WebPage ), |
|
41 |
ENCYC("Encyclopedia" ), |
|
42 |
EQUA("Equation" ), |
|
43 |
FIGURE("Figure" ), |
|
44 |
GEN("Generic" , ReferenceType.Generic ), |
|
45 |
GOVDOC("Government Document" ), |
|
46 |
GRANT("Grant" ), |
|
47 |
HEAR("Hearing" ), |
|
48 |
ICOMM("Internet Communication" ), |
|
49 |
INPR("In Press" ), |
|
50 |
JFULL("Journal (full)" , ReferenceType.Journal ), |
|
51 |
JOUR("Journal" , ReferenceType.Article ), |
|
52 |
LEGAL("Legal Rule or Regulation" ), |
|
53 |
MANSCPT("Manuscript" ), |
|
54 |
MAP("Map" , ReferenceType.Map ), |
|
55 |
MGZN("Magazine article" , ReferenceType.Article ), |
|
56 |
MPCT("Motion picture" ), |
|
57 |
MULTI("Online Multimedia" ), |
|
58 |
MUSIC("Music score" ), |
|
59 |
NEWS("Newspaper" ), |
|
60 |
PAMP("Pamphlet" ), |
|
61 |
PAT("Patent" ), |
|
62 |
PCOMM("Personal communication" , ReferenceType.PersonalCommunication ), |
|
63 |
RPRT("Report" , ReferenceType.Report ), |
|
64 |
SER("Serial publication" , ReferenceType.PrintSeries ), |
|
65 |
SLIDE("Slide" ), |
|
66 |
SOUND("Sound recording" ), |
|
67 |
STAND("Standard" ), |
|
68 |
STAT("Statute" ), |
|
69 |
THES("Thesis/Dissertation" , ReferenceType.Thesis ), |
|
70 |
UNPB("Unpublished work" ), |
|
71 |
VIDEO("Video recording" ), |
|
72 |
|
|
73 |
|
|
74 |
; |
|
75 |
|
|
76 |
private String description; |
|
77 |
private ReferenceType refType; |
|
78 |
|
|
79 |
private RisRecordType(String description){ |
|
80 |
this.description = description; |
|
81 |
} |
|
82 |
|
|
83 |
private RisRecordType(String description, ReferenceType refType){ |
|
84 |
this.description = description; |
|
85 |
this.refType = refType; |
|
86 |
} |
|
87 |
|
|
88 |
/** |
|
89 |
* @return the description |
|
90 |
*/ |
|
91 |
public String getDescription() { |
|
92 |
return description; |
|
93 |
} |
|
94 |
|
|
95 |
/** |
|
96 |
* @return |
|
97 |
*/ |
|
98 |
public ReferenceType getCdmReferenceType() { |
|
99 |
return refType; |
|
100 |
} |
|
101 |
} |
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/reference/ris/in/RisReferenceImport.java | ||
---|---|---|
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.reference.ris.in; |
|
10 |
|
|
11 |
import java.io.InputStreamReader; |
|
12 |
import java.util.HashSet; |
|
13 |
import java.util.Map; |
|
14 |
import java.util.Set; |
|
15 |
|
|
16 |
import org.apache.log4j.Logger; |
|
17 |
import org.springframework.stereotype.Component; |
|
18 |
|
|
19 |
import eu.etaxonomy.cdm.common.DOI; |
|
20 |
import eu.etaxonomy.cdm.io.common.CdmImportBase; |
|
21 |
import eu.etaxonomy.cdm.model.agent.Person; |
|
22 |
import eu.etaxonomy.cdm.model.common.Annotation; |
|
23 |
import eu.etaxonomy.cdm.model.common.AnnotationType; |
|
24 |
import eu.etaxonomy.cdm.model.common.Language; |
|
25 |
import eu.etaxonomy.cdm.model.common.TimePeriod; |
|
26 |
import eu.etaxonomy.cdm.model.reference.Reference; |
|
27 |
import eu.etaxonomy.cdm.model.reference.ReferenceFactory; |
|
28 |
import eu.etaxonomy.cdm.model.reference.ReferenceType; |
|
29 |
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser; |
|
30 |
|
|
31 |
/** |
|
32 |
* @author a.mueller |
|
33 |
* @date 11.05.2017 |
|
34 |
* |
|
35 |
*/ |
|
36 |
@Component |
|
37 |
public class RisReferenceImport |
|
38 |
extends CdmImportBase<RisReferenceImportConfigurator, RisReferenceImportState>{ |
|
39 |
|
|
40 |
private static final long serialVersionUID = 7022034669942979722L; |
|
41 |
@SuppressWarnings("unused") |
|
42 |
private static final Logger logger = Logger.getLogger(RisReferenceImport.class); |
|
43 |
|
|
44 |
/** |
|
45 |
* {@inheritDoc} |
|
46 |
*/ |
|
47 |
@Override |
|
48 |
protected void doInvoke(RisReferenceImportState state) { |
|
49 |
RisReferenceImportConfigurator config = state.getConfig(); |
|
50 |
try { |
|
51 |
// new FileReader(file) |
|
52 |
InputStreamReader inputReader = config.getSource(); |
|
53 |
RisRecordReader risReader = new RisRecordReader(state, inputReader); |
|
54 |
|
|
55 |
Set<Reference> referencesToSave = new HashSet<>(); |
|
56 |
|
|
57 |
|
|
58 |
Map<RisReferenceTag, String> next = risReader.readRecord(); |
|
59 |
while (next != RisRecordReader.EOF){ |
|
60 |
Reference ref = makeReference(next); |
|
61 |
referencesToSave.add(ref); |
|
62 |
next = risReader.readRecord(); |
|
63 |
} |
|
64 |
|
|
65 |
getReferenceService().saveOrUpdate(referencesToSave); |
|
66 |
|
|
67 |
} catch (Exception e) { |
|
68 |
String message = "Unexpected exception during RIS Reference Import"; |
|
69 |
state.getResult().addException(e, message); |
|
70 |
} |
|
71 |
} |
|
72 |
|
|
73 |
/** |
|
74 |
* @param next |
|
75 |
* @return |
|
76 |
*/ |
|
77 |
private Reference makeReference(Map<RisReferenceTag, String> record) { |
|
78 |
ReferenceType type = makeReferenceType(record); |
|
79 |
Reference result = ReferenceFactory.newReference(type); |
|
80 |
ReferenceType inRefType = type == ReferenceType.Article ? ReferenceType.Journal : ReferenceType.Generic; |
|
81 |
Reference inRef = ReferenceFactory.newReference(inRefType); |
|
82 |
|
|
83 |
for (RisReferenceTag tag : record.keySet()){ |
|
84 |
String value = record.get(tag); |
|
85 |
|
|
86 |
if (isNotBlank(value)){ |
|
87 |
switch (tag) { |
|
88 |
case T1: |
|
89 |
result.setTitle(value); |
|
90 |
break; |
|
91 |
case AU: |
|
92 |
Person author = Person.NewTitledInstance(value); |
|
93 |
result.setAuthorship(author); |
|
94 |
break; |
|
95 |
case Y1: |
|
96 |
TimePeriod y1 = TimePeriodParser.parseString(value); |
|
97 |
result.setDatePublished(y1); |
|
98 |
break; |
|
99 |
case PY: |
|
100 |
//TODO |
|
101 |
TimePeriod py = TimePeriodParser.parseString(value); |
|
102 |
result.setDatePublished(py); |
|
103 |
break; |
|
104 |
case DA: |
|
105 |
//TODO |
|
106 |
TimePeriod da = TimePeriodParser.parseString(value); |
|
107 |
result.setDatePublished(da); |
|
108 |
break; |
|
109 |
case N1: |
|
110 |
Annotation annotation = Annotation.NewInstance(value, AnnotationType.EDITORIAL(), Language.DEFAULT()); |
|
111 |
result.addAnnotation(annotation); |
|
112 |
break; |
|
113 |
case DO: |
|
114 |
DOI doi = DOI.fromString(value); |
|
115 |
result.setDoi(doi); |
|
116 |
break; |
|
117 |
case T2: |
|
118 |
inRef.setTitle(value); |
|
119 |
break; |
|
120 |
case JF: |
|
121 |
inRef.setTitle(value); |
|
122 |
break; |
|
123 |
case JO: |
|
124 |
inRef.setTitle(value); |
|
125 |
break; |
|
126 |
case SP: |
|
127 |
String startPage = value; |
|
128 |
result.setPages(startPage); |
|
129 |
break; |
|
130 |
case EP: |
|
131 |
String endPage = value; |
|
132 |
result.setPages(endPage); |
|
133 |
break; |
|
134 |
case VL: |
|
135 |
String volume = value; |
|
136 |
result.setVolume(volume); |
|
137 |
break; |
|
138 |
case IS: |
|
139 |
String issueNumber = value; |
|
140 |
result.setVolume(issueNumber); |
|
141 |
break; |
|
142 |
case PB: |
|
143 |
String publisher = value; |
|
144 |
result.setPublisher(publisher); |
|
145 |
break; |
|
146 |
case N2: |
|
147 |
String n2Str = value; |
|
148 |
result.setReferenceAbstract(n2Str); |
|
149 |
break; |
|
150 |
case AB: |
|
151 |
String abstractStr = value; |
|
152 |
result.setReferenceAbstract(abstractStr); |
|
153 |
break; |
|
154 |
case SN: |
|
155 |
String issn = value; |
|
156 |
result.setIssn(issn); |
|
157 |
break; |
|
158 |
default: |
|
159 |
//TODO |
|
160 |
break; |
|
161 |
} |
|
162 |
}else { |
|
163 |
//TODO isBlank |
|
164 |
} |
|
165 |
|
|
166 |
} |
|
167 |
return result; |
|
168 |
} |
|
169 |
|
|
170 |
/** |
|
171 |
* @param record |
|
172 |
* @return |
|
173 |
*/ |
|
174 |
private ReferenceType makeReferenceType(Map<RisReferenceTag, String> record) { |
|
175 |
RisReferenceTag tyTag = RisReferenceTag.TY; |
|
176 |
String typeStr = record.get(tyTag); |
|
177 |
RisRecordType type = RisRecordType.valueOf(typeStr); |
|
178 |
ReferenceType cdmType = type.getCdmReferenceType(); |
|
179 |
record.remove(tyTag); |
|
180 |
return cdmType; |
|
181 |
} |
|
182 |
|
|
183 |
/** |
|
184 |
* {@inheritDoc} |
|
185 |
*/ |
|
186 |
@Override |
|
187 |
protected boolean doCheck(RisReferenceImportState state) { |
|
188 |
return true; |
|
189 |
} |
|
190 |
|
|
191 |
/** |
|
192 |
* {@inheritDoc} |
|
193 |
*/ |
|
194 |
@Override |
|
195 |
protected boolean isIgnore(RisReferenceImportState state) { |
|
196 |
return false; |
|
197 |
} |
|
198 |
} |
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/reference/ris/in/RisReferenceImportConfigurator.java | ||
---|---|---|
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.reference.ris.in; |
|
10 |
|
|
11 |
import java.io.IOException; |
|
12 |
import java.io.InputStream; |
|
13 |
import java.io.InputStreamReader; |
|
14 |
import java.net.MalformedURLException; |
|
15 |
import java.net.URI; |
|
16 |
import java.net.URL; |
|
17 |
|
|
18 |
import eu.etaxonomy.cdm.database.ICdmDataSource; |
|
19 |
import eu.etaxonomy.cdm.io.common.IImportConfigurator; |
|
20 |
import eu.etaxonomy.cdm.io.common.ImportConfiguratorBase; |
|
21 |
import eu.etaxonomy.cdm.io.common.mapping.IInputTransformer; |
|
22 |
import eu.etaxonomy.cdm.model.reference.Reference; |
|
23 |
import eu.etaxonomy.cdm.model.reference.ReferenceFactory; |
|
24 |
|
|
25 |
/** |
|
26 |
* @author a.mueller |
|
27 |
* @date 11.05.2017 |
|
28 |
* |
|
29 |
*/ |
|
30 |
public class RisReferenceImportConfigurator |
|
31 |
extends ImportConfiguratorBase<RisReferenceImportState, InputStreamReader>{ |
|
32 |
|
|
33 |
private static final long serialVersionUID = -5982826645441621962L; |
|
34 |
private static IInputTransformer defaultTransformer = null; |
|
35 |
|
|
36 |
/** |
|
37 |
* @param uri |
|
38 |
* @param object |
|
39 |
* @return |
|
40 |
* @throws IOException |
|
41 |
* @throws MalformedURLException |
|
42 |
*/ |
|
43 |
public static IImportConfigurator NewInstance(URI uri, ICdmDataSource cdm) throws MalformedURLException, IOException { |
|
44 |
return NewInstance(uri.toURL(), cdm); |
|
45 |
} |
|
46 |
|
|
47 |
/** |
|
48 |
* @param url |
|
49 |
* @param object |
|
50 |
* @return |
|
51 |
* @throws IOException |
|
52 |
*/ |
|
53 |
public static IImportConfigurator NewInstance(URL url, ICdmDataSource cdm) throws IOException { |
|
54 |
InputStream stream = url.openStream(); |
|
55 |
InputStreamReader reader = new InputStreamReader(stream); |
|
56 |
RisReferenceImportConfigurator result = new RisReferenceImportConfigurator(reader, cdm); |
|
57 |
return result; |
|
58 |
} |
|
59 |
|
|
60 |
/** |
|
61 |
* @param transformer |
|
62 |
*/ |
|
63 |
protected RisReferenceImportConfigurator() { |
|
64 |
super(defaultTransformer); |
|
65 |
} |
|
66 |
|
|
67 |
protected RisReferenceImportConfigurator(InputStreamReader source, ICdmDataSource cdm) { |
|
68 |
super(defaultTransformer); |
|
69 |
this.setSource(source); |
|
70 |
this.setDestination(cdm); |
|
71 |
} |
|
72 |
|
|
73 |
|
|
74 |
/** |
|
75 |
* {@inheritDoc} |
|
76 |
*/ |
|
77 |
@Override |
|
78 |
public RisReferenceImportState getNewState() { |
|
79 |
return new RisReferenceImportState(this); |
|
80 |
} |
|
81 |
|
|
82 |
|
|
83 |
/** |
|
84 |
* {@inheritDoc} |
|
85 |
*/ |
|
86 |
@Override |
|
87 |
protected void makeIoClassList() { |
|
88 |
ioClassList = new Class[]{ |
|
89 |
RisReferenceImport.class |
|
90 |
}; |
|
91 |
} |
|
92 |
|
|
93 |
|
|
94 |
/** |
|
95 |
* {@inheritDoc} |
|
96 |
*/ |
|
97 |
@Override |
|
98 |
public Reference getSourceReference() { |
|
99 |
if (this.sourceReference == null){ |
|
100 |
sourceReference = ReferenceFactory.newGeneric(); |
|
101 |
if (this.getSource() == null){ |
|
102 |
sourceReference.setTitleCache("RIS Reference Import " + getDateString(), true); |
|
103 |
}else{ |
|
104 |
sourceReference.setTitleCache(getSource().toString(), true); |
|
105 |
} |
|
106 |
} |
|
107 |
return sourceReference; |
|
108 |
} |
|
109 |
|
|
110 |
|
|
111 |
} |
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/reference/ris/in/RisReferenceImportState.java | ||
---|---|---|
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.reference.ris.in; |
|
10 |
|
|
11 |
import eu.etaxonomy.cdm.io.common.ImportStateBase; |
|
12 |
|
|
13 |
/** |
|
14 |
* @author a.mueller |
|
15 |
* @date 11.05.2017 |
|
16 |
* |
|
17 |
*/ |
|
18 |
public class RisReferenceImportState |
|
19 |
extends ImportStateBase<RisReferenceImportConfigurator, RisReferenceImport>{ |
|
20 |
|
|
21 |
/** |
|
22 |
* @param config |
|
23 |
*/ |
|
24 |
protected RisReferenceImportState(RisReferenceImportConfigurator config) { |
|
25 |
super(config); |
|
26 |
} |
|
27 |
|
|
28 |
} |
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/reference/ris/in/RisReferenceTag.java | ||
---|---|---|
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.reference.ris.in; |
|
10 |
|
|
11 |
/** |
|
12 |
* @author a.mueller |
|
13 |
* @date 11.05.2017 |
|
14 |
* |
|
15 |
*/ |
|
16 |
public enum RisReferenceTag { |
|
17 |
TY("Type of reference"), |
|
18 |
A1("First Author"), |
|
19 |
A2("Secondary Author (each author on its own line preceded by the tag)"), |
|
20 |
A3("Tertiary Author (each author on its own line preceded by the tag)"), |
|
21 |
A4("Subsidiary Author (each author on its own line preceded by the tag)"), |
|
22 |
AB("Abstract"), |
|
23 |
AD("Author Address"), |
|
24 |
AN("Accession Number"), |
|
25 |
AU("Author (each author on its own line preceded by the tag)"), |
|
26 |
AV("Location in Archives"), |
|
27 |
BT("This field can contain alphanumeric characters. There is no practical limit to the length of this field."), |
|
28 |
C1("Custom 1"), |
|
29 |
C2("Custom 2"), |
|
30 |
C3("Custom 3"), |
|
31 |
C4("Custom 4"), |
|
32 |
C5("Custom 5"), |
|
33 |
C6("Custom 6"), |
|
34 |
C7("Custom 7"), |
|
35 |
C8("Custom 8"), |
|
36 |
CA("Caption"), |
|
37 |
CN("Call Number"), |
|
38 |
CP("This field can contain alphanumeric characters. There is no practical limit to the length of this field."), |
|
39 |
CT("Title of unpublished reference"), |
|
40 |
CY("Place Published"), |
|
41 |
DA("Date"), |
|
42 |
DB("Name of Database"), |
|
43 |
DO("DOI"), |
|
44 |
DP("Database Provider"), |
|
45 |
ED("Editor"), |
|
46 |
EP("End Page"), |
|
47 |
ET("Edition"), |
|
48 |
ID("Reference ID"), |
|
49 |
IS("Issue number"), |
|
50 |
J1("Periodical name: user abbreviation 1. This is an alphanumeric field of up to 255 characters."), |
|
51 |
J2("Alternate Title (this field is used for the abbreviated title of a book or journal name, the latter mapped to T2)"), |
|
52 |
JA("Periodical name: standard abbreviation. This is the periodical in which the article was (or is to be, in the case of in-press references) published. This is an alphanumeric field of up to 255 characters."), |
|
53 |
JF("Journal/Periodical name: full format. This is an alphanumeric field of up to 255 characters."), |
|
54 |
JO("Journal/Periodical name: full format. This is an alphanumeric field of up to 255 characters."), |
|
55 |
KW("Keywords (keywords should be entered each on its own line preceded by the tag)"), |
|
56 |
L1("Link to PDF. There is no practical limit to the length of this field. URL addresses can be entered individually, one per tag or multiple addresses can be entered on one line using a semi-colon as a separator."), |
|
57 |
L2("Link to Full-text. There is no practical limit to the length of this field. URL addresses can be entered individually, one per tag or multiple addresses can be entered on one line using a semi-colon as a separator."), |
|
58 |
L3("Related Records. There is no practical limit to the length of this field."), |
|
59 |
L4("Image(s). There is no practical limit to the length of this field."), |
|
60 |
LA("Language"), |
|
61 |
LB("Label"), |
|
62 |
LK("Website Link"), |
|
63 |
M1("Number"), |
|
64 |
M2("Miscellaneous 2. This is an alphanumeric field and there is no practical limit to the length of this field."), |
|
65 |
M3("Type of Work"), |
|
66 |
N1("Notes"), |
|
67 |
N2("Abstract. This is a free text field and can contain alphanumeric characters. There is no practical length limit to this field."), |
|
68 |
NV("Number of Volumes"), |
|
69 |
OP("Original Publication"), |
|
70 |
PB("Publisher"), |
|
71 |
PP("Publishing Place"), |
|
72 |
PY("Publication year (YYYY/MM/DD)"), |
|
73 |
RI("Reviewed Item"), |
|
74 |
RN("Research Notes"), |
|
75 |
RP("Reprint Edition"), |
|
76 |
SE("Section"), |
|
77 |
SN("ISBN/ISSN"), |
|
78 |
SP("Start Page"), |
|
79 |
ST("Short Title"), |
|
80 |
T1("Primary Title"), |
|
81 |
T2("Secondary Title (journal title, if applicable)"), |
|
82 |
T3("Tertiary Title"), |
|
83 |
TA("Translated Author"), |
|
84 |
TI("Title"), |
|
85 |
TT("Translated Title"), |
|
86 |
U1("User definable 1. This is an alphanumeric field and there is no practical limit to the length of this field."), |
|
87 |
U2("User definable 2. This is an alphanumeric field and there is no practical limit to the length of this field."), |
|
88 |
U3("User definable 3. This is an alphanumeric field and there is no practical limit to the length of this field."), |
|
89 |
U4("User definable 4. This is an alphanumeric field and there is no practical limit to the length of this field."), |
|
90 |
U5("User definable 5. This is an alphanumeric field and there is no practical limit to the length of this field."), |
|
91 |
UR("URL"), |
|
92 |
VL("Volume number"), |
|
93 |
VO("Published Standard number"), |
|
94 |
Y1("Primary Date"), |
|
95 |
Y2("Access Date"), |
|
96 |
ER("End of Reference") |
|
97 |
; |
|
98 |
|
|
99 |
private String description; |
|
100 |
|
|
101 |
private RisReferenceTag(String description){ |
|
102 |
this.description = description; |
|
103 |
} |
|
104 |
|
|
105 |
/** |
|
106 |
* @return the description |
|
107 |
*/ |
|
108 |
public String getDescription() { |
|
109 |
return description; |
|
110 |
} |
|
111 |
|
|
112 |
|
|
113 |
} |
cdmlib-io/src/test/java/eu/etaxonomy/cdm/io/reference/RisReferenceImportTest.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2007 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 |
|
|
10 |
package eu.etaxonomy.cdm.io.reference; |
|
11 |
|
|
12 |
import static org.junit.Assert.assertNotNull; |
|
13 |
|
|
14 |
import java.io.FileNotFoundException; |
|
15 |
import java.net.URL; |
|
16 |
|
|
17 |
import org.junit.Assert; |
|
18 |
import org.junit.Before; |
|
19 |
import org.junit.Ignore; |
|
20 |
import org.junit.Test; |
|
21 |
import org.unitils.spring.annotation.SpringBeanByName; |
|
22 |
import org.unitils.spring.annotation.SpringBeanByType; |
|
23 |
|
|
24 |
import eu.etaxonomy.cdm.api.service.INameService; |
|
25 |
import eu.etaxonomy.cdm.io.common.CdmApplicationAwareDefaultImport; |
|
26 |
import eu.etaxonomy.cdm.io.common.IImportConfigurator; |
|
27 |
import eu.etaxonomy.cdm.io.common.ImportResult; |
|
28 |
import eu.etaxonomy.cdm.io.reference.ris.in.RisReferenceImportConfigurator; |
|
29 |
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest; |
|
30 |
|
|
31 |
/** |
|
32 |
* @author andy |
|
33 |
* |
|
34 |
*/ |
|
35 |
public class RisReferenceImportTest extends CdmTransactionalIntegrationTest { |
|
36 |
|
|
37 |
@SpringBeanByName |
|
38 |
private CdmApplicationAwareDefaultImport<?> defaultImport; |
|
39 |
|
|
40 |
@SpringBeanByType |
|
41 |
private INameService nameService; |
|
42 |
|
|
43 |
private IImportConfigurator configurator; |
|
44 |
|
|
45 |
@Before |
|
46 |
public void setUp() { |
|
47 |
String inputFile = "/eu/etaxonomy/cdm/io/reference/RisReferenceImportTest-input.ris"; |
|
48 |
URL url = this.getClass().getResource(inputFile); |
|
49 |
assertNotNull("URL for the test file '" + inputFile + "' does not exist", url); |
|
50 |
try { |
|
51 |
configurator = RisReferenceImportConfigurator.NewInstance(url, null); |
|
52 |
} catch (Exception e) { |
|
53 |
e.printStackTrace(); |
|
54 |
Assert.fail(); |
|
55 |
} |
|
56 |
assertNotNull("Configurator could not be created", configurator); |
|
57 |
} |
|
58 |
|
|
59 |
//***************************** TESTS *************************************// |
|
60 |
|
|
61 |
@Test |
|
62 |
public void testInit() { |
|
63 |
// assertNotNull("XXX should not be null", defaultImport); |
|
64 |
assertNotNull("nameService should not be null", nameService); |
|
65 |
assertNotNull("configurator should not be null", configurator); |
|
66 |
} |
|
67 |
|
|
68 |
@Test |
|
69 |
public void testDoInvokeWithoutExceptions() { |
|
70 |
ImportResult result = defaultImport.invoke(configurator); |
|
71 |
String report = result.createReport().toString(); |
|
72 |
System.out.println(report); |
|
73 |
} |
|
74 |
|
|
75 |
@Test |
|
76 |
@Ignore("Import does not fully work yet") |
|
77 |
public void testDoInvoke() { |
|
78 |
boolean result = defaultImport.invoke(configurator).isSuccess(); |
|
79 |
//TODO result is still false |
|
80 |
logger.warn("No real testing for ris import yet"); |
|
81 |
Assert.assertTrue("Return value for import.invoke() should be true", result); |
|
82 |
// assertEquals("Number of TaxonNames should be 5", 5, nameService.count()); |
|
83 |
} |
|
84 |
|
|
85 |
@Override |
|
86 |
public void createTestDataSet() throws FileNotFoundException {} |
|
87 |
} |
cdmlib-io/src/test/resources/eu/etaxonomy/cdm/io/reference/RisReferenceImportTest-input.ris | ||
---|---|---|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
TY - JOUR |
|
5 |
T1 - Decorsella arborea, a second species in Decorsella (Violaceae), and Decorsella versus Rinorea |
|
6 |
AU - Jongkind, Carel C. H. |
|
7 |
Y1 - 2017/02/13 |
|
8 |
PY - 2017 |
|
9 |
DA - 2017/04/01 |
|
10 |
N1 - doi: 10.3372/wi.47.47105 |
|
11 |
DO - 10.3372/wi.47.47105 |
|
12 |
T2 - Willdenowia |
|
13 |
JF - Willdenowia |
|
14 |
JO - Willdenowia |
|
15 |
SP - 43 |
|
16 |
EP - 47 |
|
17 |
VL - 47 |
|
18 |
IS - 1 |
|
19 |
PB - Botanic Garden and Botanical Museum Berlin (BGBM) |
|
20 |
N2 - Abstract: A new species of Violaceae, Decorsella arborea Jongkind, is described and illustrated. The new species differs from the only other species in the genus, D. paradoxa A. Chev., by the larger size of the plants, smaller leaves, more slender flowers, and stamen filaments that are free for a much larger part. Both species are from the Guineo-Congolian forest of tropical Africa. The differences between Decorsella and Rinorea are discussed. Confirming recent reports, some species of Rinorea can have zygomorphic flowers and some of these can be almost equal in shape to Decorsella flowers. Citation: Jongkind C. C. H. 2017: Decorsella arborea, a second species in Decorsella (Violaceae), and Decorsella versus Rinorea. ? Willdenowia 47: 43?47. doi: https://doi.org/10.3372/wi.47.47105 Version of record first published online on 13 February 2017 ahead of inclusion in April 2017 issue. |
|
21 |
AB - Abstract: A new species of Violaceae, Decorsella arborea Jongkind, is described and illustrated. The new species differs from the only other species in the genus, D. paradoxa A. Chev., by the larger size of the plants, smaller leaves, more slender flowers, and stamen filaments that are free for a much larger part. Both species are from the Guineo-Congolian forest of tropical Africa. The differences between Decorsella and Rinorea are discussed. Confirming recent reports, some species of Rinorea can have zygomorphic flowers and some of these can be almost equal in shape to Decorsella flowers. Citation: Jongkind C. C. H. 2017: Decorsella arborea, a second species in Decorsella (Violaceae), and Decorsella versus Rinorea. ? Willdenowia 47: 43?47. doi: https://doi.org/10.3372/wi.47.47105 Version of record first published online on 13 February 2017 ahead of inclusion in April 2017 issue. |
|
22 |
SN - 0511-9618 |
|
23 |
M3 - doi: 10.3372/wi.47.47105 |
|
24 |
UR - http://dx.doi.org/10.3372/wi.47.47105 |
|
25 |
Y2 - 2017/04/25 |
|
26 |
ER - |
Also available in: Unified diff
ref #6636 firs incomplete version of RIS reference import