cd8690e983ed548b3d94d0ed394a8d457a1ee907
[debian/jabref.git] / src / java / net / sf / jabref / imports / OvidImporter.java
1 package net.sf.jabref.imports;
2
3 import java.util.regex.Matcher;
4 import java.util.regex.Pattern;
5 import java.io.InputStream;
6 import java.io.BufferedReader;
7 import java.io.IOException;
8 import java.util.List;
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import net.sf.jabref.BibtexEntry;
12 import net.sf.jabref.Globals;
13 import net.sf.jabref.Util;
14 import net.sf.jabref.AuthorList;
15
16 /**
17  * Imports an Ovid file.
18  */
19 public class OvidImporter extends ImportFormat {
20
21     public static Pattern ovid_src_pat = Pattern
22     .compile("Source ([ \\w&\\-,:]+)\\.[ ]+([0-9]+)\\(([\\w\\-]+)\\):([0-9]+\\-?[0-9]+?)\\,.*([0-9][0-9][0-9][0-9])");
23
24     public static Pattern ovid_src_pat_no_issue = Pattern
25     .compile("Source ([ \\w&\\-,:]+)\\.[ ]+([0-9]+):([0-9]+\\-?[0-9]+?)\\,.*([0-9][0-9][0-9][0-9])");
26
27     public static Pattern ovid_src_pat_2 = Pattern.compile(
28             "([ \\w&\\-,]+)\\. Vol ([0-9]+)\\(([\\w\\-]+)\\) ([A-Za-z]+) ([0-9][0-9][0-9][0-9]), ([0-9]+\\-?[0-9]+)");
29
30     public static Pattern incollection_pat = Pattern.compile(
31             "(.+)\\(([0-9][0-9][0-9][0-9])\\)\\. ([ \\w&\\-,:]+)\\.[ ]+\\(pp. ([0-9]+\\-?[0-9]+?)\\).[A-Za-z0-9, ]+pp\\. "
32             +"([\\w, ]+): ([\\w, ]+)");
33     public static Pattern book_pat = Pattern.compile(
34                 "\\(([0-9][0-9][0-9][0-9])\\)\\. [A-Za-z, ]+([0-9]+) pp\\. ([\\w, ]+): ([\\w, ]+)");
35
36     //   public static Pattern ovid_pat_inspec= Pattern.compile("Source ([
37     // \\w&\\-]+)");
38
39
40     /**
41      * Return the name of this import format.
42      */
43     public String getFormatName() {
44     return "Ovid";
45     }
46
47     /*
48      *  (non-Javadoc)
49      * @see net.sf.jabref.imports.ImportFormat#getCLIId()
50      */
51     public String getCLIId() {
52       return "ovid";
53     }
54     
55     /**
56      * Check whether the source is in the correct format for this importer.
57      */
58     public boolean isRecognizedFormat(InputStream in) throws IOException {
59     return true;
60     }
61
62     /**
63      * Parse the entries in the source, and return a List of BibtexEntry
64      * objects.
65      */
66     public List importEntries(InputStream stream) throws IOException {
67     ArrayList bibitems = new ArrayList();
68     StringBuffer sb = new StringBuffer();
69     BufferedReader in = new BufferedReader(ImportFormatReader.getReaderDefaultEncoding(stream));
70     String line;
71     while ((line = in.readLine()) != null){
72         if (line.length() > 0 && line.charAt(0) != ' '){
73         sb.append("__NEWFIELD__");
74         }
75         sb.append(line);
76         sb.append('\n');
77     }
78
79     String items[] = sb.toString().split("<[0-9]+>");
80
81     for (int i = 1; i < items.length; i++){
82         HashMap h = new HashMap();
83         String[] fields = items[i].split("__NEWFIELD__");
84         for (int j = 0; j < fields.length; j++){
85             int linebreak = fields[j].indexOf('\n');
86             String fieldName = fields[j].substring(0, linebreak).trim();
87             String content = fields[j].substring(linebreak).trim();
88             // Remove unnecessary dots at the end of lines:
89             if (content.endsWith("."))
90                     content = content.substring(0, content.length()-1);
91             //fields[j] = fields[j].trim();
92             if (fieldName.indexOf("Author") == 0
93                 && fieldName.indexOf("Author Keywords") == -1
94                 && fieldName.indexOf("Author e-mail") == -1){
95
96                 h.put("author", content);
97                 /*if (content.indexOf(";") > 0){ //LN FN; [LN FN;]*
98                     names = content.replaceAll("[^\\.A-Za-z,;\\- ]", "").replaceAll(";", " and");
99                 }else{// LN FN. [LN FN.]*
100                     //author = content.replaceAll("\\.", " and").replaceAll(" and$", "");
101                     names = content;
102                 }
103
104                 StringBuffer buf = new StringBuffer();
105                 for (int ii=0; ii<names.length; ii++) {
106                     names[ii] = names[ii].trim();
107                     int space = names[ii].indexOf(' ');
108                     if (space >= 0) {
109                         buf.append(names[ii].substring(0, space));
110                         buf.append(',');
111                         buf.append(names[ii].substring(space));
112                     } else {
113                         buf.append(names[ii]);
114                     }
115
116                     buf.append()
117                     if (ii < names.length-1)
118                         buf.append(" and ");
119                 }
120                 h.put("author", AuthorList.fixAuthor_lastNameFirst(names));  */
121
122                 //    author = content.replaceAll("  ", " and ").replaceAll(" and $", "");
123
124
125             //h.put("author", ImportFormatReader.fixAuthor_lastNameFirst(author));
126
127         }else if (fieldName.indexOf("Title") == 0) {
128                 content = content.replaceAll("\\[.+\\]", "").trim();
129                 if (content.endsWith("."))
130                     content = content.substring(0, content.length()-1);
131                 h.put("title", content);
132         }
133
134         else if (fieldName.indexOf("Chapter Title") == 0) h.put("chaptertitle", content);
135
136         // The "Source" field is a complete mess - it can have several different formats,
137         // but since it can contain journal name, book title, year, month, volume etc. we
138         // must try to parse it. We use different regular expressions to check different
139         // possible formattings.
140         else if (fieldName.indexOf("Source") == 0){
141                 Matcher matcher;
142             if ((matcher = ovid_src_pat.matcher(content)).find()) {
143             h.put("journal", matcher.group(1));
144             h.put("volume", matcher.group(2));
145             h.put("issue", matcher.group(3));
146             h.put("pages", matcher.group(4));
147             h.put("year", matcher.group(5));
148             } else if ((matcher = ovid_src_pat_no_issue.matcher(content)).find()) {// may be missing the issue
149                 h.put("journal", matcher.group(1));
150                 h.put("volume", matcher.group(2));
151                 h.put("pages", matcher.group(3));
152                 h.put("year", matcher.group(4));
153             } else if ((matcher = ovid_src_pat_2.matcher(content)).find()) {
154
155                 h.put("journal", matcher.group(1));
156                 h.put("volume", matcher.group(2));
157                 h.put("issue", matcher.group(3));
158                 h.put("month", matcher.group(4));
159                 h.put("year", matcher.group(5));
160                 h.put("pages", matcher.group(6));
161
162             } else if ((matcher = incollection_pat.matcher(content)).find()) {
163                 h.put("editor", matcher.group(1).replaceAll(" \\(Ed\\)", ""));
164                 h.put("year", matcher.group(2));
165                 h.put("booktitle", matcher.group(3));
166                 h.put("pages", matcher.group(4));
167                 h.put("address", matcher.group(5));
168                 h.put("publisher", matcher.group(6));
169             } else if ((matcher = book_pat.matcher(content)).find()) {
170                 h.put("year", matcher.group(1));
171                 h.put("pages", matcher.group(2));
172                 h.put("address", matcher.group(3));
173                 h.put("publisher", matcher.group(4));
174
175             }
176             // Add double hyphens to page ranges:
177             if (h.get("pages") != null) {
178                 h.put("pages", ((String)h.get("pages")).replaceAll("-", "--"));
179             }
180
181         } else if (fieldName.equals("Abstract")) {
182                 //System.out.println("'"+content+"'");
183                 h.put("abstract", content);
184
185         } else if (fieldName.equals("Publication Type")) {
186              if (content.indexOf("Book") >= 0)
187                 h.put("entrytype", "book");
188              else if (content.indexOf("Journal") >= 0)
189                 h.put("entrytype", "article");
190         }
191         }
192
193         // Now we need to check if a book entry has given editors in the author field;
194         // if so, rearrange:
195         String auth = (String)h.get("author");
196         if ((auth != null) && (auth.indexOf(" [Ed]") >= 0)) {
197             h.remove("author");
198             h.put("editor", auth.replaceAll(" \\[Ed\\]", ""));
199         }
200
201         // Rearrange names properly:
202         auth = (String)h.get("author");
203         if (auth != null)
204             h.put("author", fixNames(auth));
205         auth = (String)h.get("editor");
206         if (auth != null)
207             h.put("editor", fixNames(auth));
208
209
210
211         // Set the entrytype properly:
212         String entryType = h.containsKey("entrytype") ? (String)h.get("entrytype") : "other";
213         h.remove("entrytype");
214         if (entryType.equals("book")) {
215             if (h.containsKey("chaptertitle")) {
216                 // This means we have an "incollection" entry.
217                 entryType = "incollection";
218                 // Move the "chaptertitle" to just "title":
219                 h.put("title", h.remove("chaptertitle"));
220             }
221         }
222         BibtexEntry b = new BibtexEntry(Util.createNeutralId(), Globals.getEntryType(entryType));
223         b.setField(h);
224
225         bibitems.add(b);
226
227     }
228
229     return bibitems;
230     }
231
232     private String fixNames(String content) {
233         String names;
234         if (content.indexOf(";") > 0){ //LN FN; [LN FN;]*
235             names = content.replaceAll("[^\\.A-Za-z,;\\- ]", "").replaceAll(";", " and");
236         } else
237             names = content;
238         return AuthorList.fixAuthor_lastNameFirst(names);
239     }
240
241 }
242
243