Source code: com/lanceolav/jreftree/WebTools.java
1 /**
2 * JRefTree is a GUI interface to organize and output bibliographic references.
3 * Copyright (C) 2003 Lance O. Eastgate.
4 *
5 * This file is part of JRefTree, and was created on Apr 1, 2003.
6 *
7 * JRefTree is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * The author can be reached at jreftree@lanceolav.com.
22 */
23
24 package com.lanceolav.jreftree;
25
26 import com.lanceolav.jreftree.dialogs.PleaseWaitWindow;
27 import org.w3c.dom.*;
28 import org.xml.sax.SAXException;
29
30 import javax.swing.*;
31 import javax.xml.parsers.DocumentBuilder;
32 import javax.xml.parsers.DocumentBuilderFactory;
33 import javax.xml.parsers.FactoryConfigurationError;
34 import javax.xml.parsers.ParserConfigurationException;
35 import javax.xml.transform.*;
36 import javax.xml.transform.dom.DOMSource;
37 import javax.xml.transform.stream.StreamResult;
38 import java.awt.*;
39 import java.awt.event.ActionEvent;
40 import java.awt.event.ActionListener;
41 import java.io.*;
42 import java.net.HttpURLConnection;
43 import java.net.URL;
44 import java.util.Enumeration;
45 import java.util.Vector;
46
47 public final class WebTools {
48
49 private final static File url_template_file =
50 new File(System.getProperty("user.dir")+"/.URLTemplates.xml");
51 private static Vector journalTemplates = loadURLTemplates(url_template_file);
52 private static class URLTemplate {
53 private String journalRegExp, template;
54 private int minVolume = -1, maxVolume = -1;
55 private int minNumber = -1, maxNumber = -1;
56 private int minFirstpage = -1, maxFirstpage = -1;
57 private int minYear = -1, maxYear = -1;
58
59 public URLTemplate(String journalRegExp, String template) {
60 this.journalRegExp=journalRegExp;
61 this.template=template;
62 }
63
64 public void setMinVolume(int minV) { minVolume = minV; }
65 public void setMaxVolume(int maxV) { maxVolume = maxV; }
66
67 public void setMinNumber(int minV) { minNumber = minV; }
68 public void setMaxNumber(int maxV) { maxNumber = maxV; }
69
70 public void setMinFirstpage(int minV) { minFirstpage = minV; }
71 public void setMaxFirstpage(int maxV) { maxFirstpage = maxV; }
72
73 public void setMinYear(int minV) { minYear = minV; }
74 public void setMaxYear(int maxV) { maxYear = maxV; }
75
76 private boolean limitsOK(int minV, int maxV, String s) {
77 if ((minV<0) && (maxV<0)) { return true; }
78 if (s.length()==0) {
79 // This is bad: the journal should specify this value
80 // in order to find the url
81 return false;
82 }
83 int v = Integer.parseInt(s);
84 if ((minV>=0) && (v<minV)) { return false; }
85 else if ((maxV>=0) && (v>maxV)) { return false; }
86 else { return true; }
87 }
88
89 public String getRealURL(JournalEntry je) {
90 if (!je.getJournal().matches(journalRegExp)) { return null; }
91 else if (!(limitsOK(minVolume,maxVolume,je.getVolume()) &&
92 limitsOK(minNumber,maxNumber,je.getVolume()) &&
93 limitsOK(minFirstpage,maxFirstpage,je.getVolume()) &&
94 limitsOK(minYear,maxYear,je.getVolume()))) {
95 // all the limitsOK have to return true to get a match
96 return null;
97 }
98
99 String url = template;
100 if (url.indexOf("{")!=-1) {
101 // Get all the {}
102 String[] sp = url.split("(^|\\}).*?($|\\{)");
103 for (int i = 0; i < sp.length; i++) {
104 if (sp[i].length()==0) { continue; }
105 String replacement="";
106 if (sp[i].charAt(0)=='V') { replacement = je.getVolume(); }
107 else if (sp[i].charAt(0)=='N') { replacement = je.getNumber(); }
108 else if (sp[i].charAt(0)=='P') { replacement = je.getPages(); }
109 else if (sp[i].charAt(0)=='Y') { replacement = je.getYear(); }
110 else { throw new IllegalArgumentException("Invalid first letter in braces"); }
111 if (sp[i].length()>1) {
112 if (sp[i].charAt(1)!=',') { throw new IllegalArgumentException("Missing comma"); }
113 // This is ok even if there is nothing after the comma:
114 String rest = sp[i].substring(2);
115 if (rest.length()>replacement.length()) {
116 replacement =
117 rest.substring(0,rest.length()-replacement.length())+replacement;
118 }
119 }
120 url=url.replaceFirst("\\{.*?\\}",replacement);
121 }
122 }
123 //System.out.println("DEBUG INFO: URL = "+url);
124 return url;
125 }
126 }
127
128 private static String username="", password="";
129 private static File configFile = new File(System.getProperty("user.dir")+"/.config.xml");
130 private static Vector proxies = loadProxies();
131
132 private WebTools() {}
133
134 private static void setProxy(String p) {
135 String proxyHost="", proxyPort="";
136 if (p!=null) {
137 if (p.indexOf(':')!=-1) {
138 proxyHost = p.substring(0,p.indexOf(':'));
139 proxyPort = p.substring(p.indexOf(':')+1);
140 }
141 else { proxyHost = p; }
142 }
143
144 if (!proxyHost.equals("")) { System.setProperty("proxySet", "true" ); }
145 else { System.setProperty("proxySet", "false" ); }
146 System.setProperty("http.proxyHost", proxyHost );
147 System.setProperty("http.proxyPort", proxyPort );
148
149 //System.getProperties().list(System.out);
150 }
151
152 public static void configProxy() {
153 JOptionPane optionPane;
154 final JComboBox proxy = new JComboBox(proxies);
155 final JButton deleteHostNameButton = new JButton("Delete this host");
156 final JTextField usernameTF = new JTextField(username);
157 final JPasswordField passwordTF = new JPasswordField(password);
158
159 proxy.setEditable(true);
160 proxy.addActionListener(new ActionListener() {
161 public void actionPerformed(ActionEvent e) {
162 if (e.getActionCommand().equals("comboBoxEdited")) {
163 String newProxy = (String) proxy.getSelectedItem();
164 if (!newProxy.equals("")) {
165 for (int i = proxy.getItemCount()-1; i >=0; i--) {
166 if (proxy.getItemAt(i).equals(newProxy)) {
167 proxy.removeItemAt(i);
168 }
169 }
170 proxy.insertItemAt(newProxy,0);
171 deleteHostNameButton.setEnabled(true);
172 }
173 KeyboardFocusManager.getCurrentKeyboardFocusManager()
174 .focusNextComponent(deleteHostNameButton);
175
176 }
177 }
178 });
179 if (proxies.size()==0) { deleteHostNameButton.setEnabled(false); }
180 deleteHostNameButton.addActionListener(new ActionListener() {
181 public void actionPerformed(ActionEvent e) {
182 if (proxy.getItemCount()>0) {
183 proxy.removeItemAt(proxy.getSelectedIndex());
184 }
185 if (proxy.getItemCount()==0) { deleteHostNameButton.setEnabled(false); }
186 }
187 });
188
189 JPanel topPane = new JPanel();
190 topPane.setLayout(new GridLayout(0,1));
191 topPane.add(new JLabel("Enter Proxy:"));
192 topPane.add(new JLabel("(as my.proxy.com or my.proxy.com:portnumber)"));
193 topPane.add(proxy);
194 topPane.add(deleteHostNameButton);
195
196 JPanel bottomPane = new JPanel();
197 bottomPane.setLayout(new GridLayout(0,2));
198 bottomPane.add(new JLabel("Username:"));
199 bottomPane.add(usernameTF);
200 bottomPane.add(new JLabel("Password:"));
201 bottomPane.add(passwordTF);
202
203 Box whole = new Box(BoxLayout.Y_AXIS);
204 whole.add(topPane);
205 whole.add(bottomPane);
206
207 optionPane = new JOptionPane(whole, JOptionPane.PLAIN_MESSAGE,
208 JOptionPane.OK_CANCEL_OPTION);
209 JDialog dialog = optionPane.createDialog(null,"Enter Proxy Information");
210 dialog.setModal(true);
211 dialog.setResizable(true);
212 final Dimension winSize = new Dimension(500,300);
213 final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
214 final Point winLocation = new Point((screenSize.width-winSize.width)/2,(screenSize.height-winSize.height)/2);
215 dialog.setLocation(winLocation);
216 dialog.setSize(winSize);
217 dialog.show();
218
219 if (((Integer) optionPane.getValue()).intValue() == JOptionPane.CANCEL_OPTION) {
220 return;
221 }
222
223 proxies = new Vector();
224 if (proxy.getItemCount()>0) {
225 Object p = proxy.getSelectedItem();
226 proxy.removeItem(p);
227 proxy.insertItemAt(p,0);
228 }
229
230 for (int i = 0; i < proxy.getItemCount(); i++) {
231 String t = (String) proxy.getItemAt(i);
232 if (!t.equals("")) { proxies.add(t); }
233 }
234
235 if (proxies.size()>0) { setProxy((String) proxies.get(0)); }
236 else { setProxy(""); }
237
238 username = usernameTF.getText();
239 password = new String(passwordTF.getPassword());
240
241 saveProxies();
242 }
243
244 private static Vector loadProxies() {
245 Vector loadedProxies = new Vector();
246 if (!configFile.exists()) { return loadedProxies; }
247 try {
248 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
249 DocumentBuilder builder = factory.newDocumentBuilder();
250
251 Document document = builder.parse( configFile );
252
253 Element root = document.getDocumentElement();
254 root.normalize();
255
256 if (!root.getTagName().equals("proxies")) {
257 JOptionPane.showMessageDialog(null,
258 "Invalid xml file: root node not 'proxies'", "ERROR",
259 JOptionPane.ERROR_MESSAGE);
260 return loadedProxies;
261 }
262
263 NodeList proxyElements = root.getElementsByTagName("proxy");
264 for (int idx = 0; idx < proxyElements.getLength(); idx++) {
265 Element e = (Element) proxyElements.item(idx);
266 // Assuming the document has been normalized
267 String proxyHost = e.getAttribute("host");
268 if (proxyHost==null) { continue; }
269 String proxyPort = e.getAttribute("port");
270 if ((proxyPort!=null) && (!proxyPort.equals(""))) {
271 proxyHost += ":"+proxyPort;
272 }
273 loadedProxies.add(proxyHost);
274 }
275 if (loadedProxies.size()>0) {
276 setProxy((String) loadedProxies.get(0));
277 }
278 }
279 catch (ParserConfigurationException e) {
280 e.printStackTrace();
281 }
282 catch (SAXException e) {
283 JOptionPane.showMessageDialog(null,
284 "Problem while parsing XML file (SAXException).",
285 "ERROR", JOptionPane.ERROR_MESSAGE);
286 return null;
287 }
288 catch (FileNotFoundException e) {
289 JOptionPane.showMessageDialog(null,
290 "File not found: "+e.getMessage(),
291 "ERROR", JOptionPane.ERROR_MESSAGE);
292 return null;
293 }
294 catch (IOException e) {
295 e.printStackTrace();
296 return null;
297 }
298 return loadedProxies;
299 }
300
301 private static void saveProxies() {
302 if (proxies.size()==0) {
303 configFile.delete();
304 return;
305 }
306 Document document;
307 try {
308 final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
309 final DocumentBuilder builder = factory.newDocumentBuilder();
310 document = builder.newDocument();
311
312 Element proxyRoot = document.createElement("proxies");
313 for (int i = 0; i < proxies.size(); i++) {
314 Element p = document.createElement("proxy");
315 String t = (String) proxies.get(i);
316 String proxyHost=null, proxyPort=null;
317 if (t.indexOf(':')!=-1) {
318 proxyHost = t.substring(0,t.indexOf(':'));
319 proxyPort = t.substring(t.indexOf(':')+1);
320 }
321 else { proxyHost = t; }
322 p.setAttribute("host",proxyHost);
323 if (proxyPort!=null) { p.setAttribute("port",proxyPort); }
324 proxyRoot.appendChild(p);
325 }
326 document.appendChild(proxyRoot);
327
328 TransformerFactory tFactory = TransformerFactory.newInstance();
329 Transformer transformer = tFactory.newTransformer();
330
331 //transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "JRefTree.dtd");
332 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
333 Enumeration propertyNames = transformer.getOutputProperties().propertyNames();
334 while (propertyNames.hasMoreElements()) {
335 String nextProp = propertyNames.nextElement().toString();
336 if (nextProp.indexOf("indent-amount")>=0) {
337 transformer.setOutputProperty(nextProp,"4");
338 break;
339 }
340 }
341
342 DOMSource source = new DOMSource(document);
343 StreamResult result = new StreamResult(new FileWriter(configFile));
344 transformer.transform(source, result);
345 }
346 catch (FactoryConfigurationError factoryConfigurationError) {
347 factoryConfigurationError.printStackTrace();
348 }
349 catch (ParserConfigurationException e) {
350 e.printStackTrace();
351 }
352 catch (DOMException e) {
353 e.printStackTrace();
354 }
355 catch (TransformerFactoryConfigurationError transformerFactoryConfigurationError) {
356 transformerFactoryConfigurationError.printStackTrace();
357 }
358 catch (TransformerException e) {
359 e.printStackTrace();
360 }
361 catch (IllegalArgumentException e) {
362 e.printStackTrace();
363 }
364 catch (IOException e) {
365 JOptionPane.showMessageDialog(null,
366 "Could not write file: "+e.getMessage(),
367 "ERROR", JOptionPane.ERROR_MESSAGE);
368 return;
369 }
370 }
371
372 private static String refSite(JournalEntry je) {
373 String url = null;
374 for (int i = 0; i < journalTemplates.size(); i++) {
375 url = ((URLTemplate) journalTemplates.elementAt(i)).getRealURL(je);
376 if (url!=null) { return url; }
377 }
378 return null;
379 }
380
381 public static boolean downloadable(JournalEntry je) {
382 return (refSite(je)!=null);
383 }
384
385 private static void setProxyAuthorization(HttpURLConnection uc) {
386 //if ( (username.length() > 0) ) { //&& (password.length()>0) ) {
387 String auth = username+":"+password;
388 String encodedAuth = base64encode( auth );
389 uc.setRequestProperty( "Proxy-Authorization", "Basic "+encodedAuth );
390 //}
391 }
392
393 public static boolean downloadPaper(JournalEntry je) {
394 // Should not be necessary to check this:
395 if (je==null) { throw new NullPointerException("JournalEntry == null"); }
396
397 String url = refSite(je);
398 if (url == null) { throw new NullPointerException("url == null"); }
399 String workingDir = System.getProperty("user.dir");
400 String filename = workingDir+"/papers/"+je.getEntryID()+".pdf";
401 PleaseWaitWindow pww = new PleaseWaitWindow();
402 try {
403 File file = new File(filename);
404 if (file.exists()) { throw new IOException("File exists"); }
405
406 //System.out.println("DEBUG INFO: Attempting to download file: "+file.getName());
407 URL u = new URL(url);
408 HttpURLConnection uc;
409 boolean connectionOK = false, setProxyAuth = false, setCookie = false;
410 String cookie = "";
411 int maxCookies = 1;
412 do {
413 uc = (HttpURLConnection) u.openConnection();
414 // setRequestProperty needs to be done BEFORE connect, getInputStream, or getHeader
415 if (setCookie) { uc.setRequestProperty("Cookie",cookie); }
416 if (setProxyAuth) { setProxyAuthorization(uc); }
417 uc.connect();
418 int code = uc.getResponseCode();
419 //System.out.println("DEBUG INFO: "+uc.getResponseMessage());
420 if (code==HttpURLConnection.HTTP_OK) {
421 // Check for cookies:
422 cookie = uc.getHeaderField("Set-Cookie");
423 if ((cookie == null) || (maxCookies==0)) { connectionOK = true; }
424 else {
425 int index = cookie.indexOf(";");
426 if (index >=0 ) { cookie = cookie.substring(0,index); }
427 setCookie=true;
428 maxCookies--;
429 //System.out.println("DEBUG INFO: Accepting cookie = " + cookie);
430 }
431 }
432 else if (code == HttpURLConnection.HTTP_UNAUTHORIZED) {
433 throw new IOException("Please configure proxy server");
434 }
435 else if (code == HttpURLConnection.HTTP_NOT_FOUND) {
436 throw new IOException("Proxy host/port not found, please RE-configure");
437 }
438 else if (code == HttpURLConnection.HTTP_PROXY_AUTH) {
439 if (!setProxyAuth) { setProxyAuth = true; }
440 else {
441 throw new IOException("Invalid proxy username/password combination.");
442 }
443 }
444 else {
445 throw new IOException(uc.getResponseMessage());
446 }
447 } while (connectionOK == false);
448
449 InputStream in = uc.getInputStream();
450 BufferedInputStream bis = new BufferedInputStream(in);
451 FileOutputStream fos = new FileOutputStream(file);
452 int cnt=1024*10, KbReceived = 0;
453 while (true) {
454 int v = bis.read();
455 if (v!=-1) { fos.write(v); cnt--; }
456 else { break; }
457 if (cnt==0) {
458 KbReceived+=10;
459 cnt=1024*10;
460 pww.setText(" Downloaded "+KbReceived+" Kb");}
461 }
462 pww.setText("Download Finished");
463 bis.close();
464 fos.close();
465 in.close();
466 }
467 catch (IOException e) {
468 pww.dispose();
469 JOptionPane.showMessageDialog(null,"Download Failed:\n"+e.toString(),
470 "ERROR", JOptionPane.ERROR_MESSAGE);
471 return false;
472 }
473
474 pww.dispose();
475 return true;
476 }
477
478 private static String base64encode(String s) {
479 if (s.equals("")) { return ""; }
480
481 final String translationTable =
482 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
483
484 StringBuffer encodedString = new StringBuffer();
485
486
487 int leftOvers = s.length() % 3;
488
489 String padding = "";
490 if (leftOvers==1) {
491 s+="\0\0";
492 padding = "==";
493 }
494 else if (leftOvers==2) {
495 s+="\0";
496 padding="=";
497 }
498 byte[] bytes = s.getBytes();
499 int chunksOfThree = bytes.length / 3;
500 int charactersAdded = 0;
501 for (int i = 0; i < chunksOfThree; i++) {
502 int ii = (bytes[i*3] << 16) + (bytes[i*3+1] << 8) + bytes[i*3+2];
503 encodedString.append(translationTable.charAt(ii >>> 18));
504 encodedString.append(translationTable.charAt((ii >>> 12) & 63));
505 encodedString.append(translationTable.charAt((ii >>> 6) & 63));
506 encodedString.append(translationTable.charAt(ii & 63));
507 charactersAdded += 4;
508 // add a newline for every 76 characters:
509 if ( (charactersAdded % 76) == 0 ) { encodedString.append("\n"); }
510 }
511 String trimmedString = encodedString.toString().trim();
512 String finalString = trimmedString.substring(
513 0,trimmedString.length()-(padding.length())) + padding;
514
515 return finalString;
516 }
517
518 private static Vector loadURLTemplates(File file) {
519 if (!file.exists()) { saveURLTemplates(file); }
520 Vector journalTemplates = new Vector();
521 try {
522 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
523 DocumentBuilder builder = factory.newDocumentBuilder();
524
525 Document document = builder.parse( file );
526
527 Element root = document.getDocumentElement();
528 root.normalize();
529
530 if (!root.getTagName().equals("URL_Templates")) {
531 JOptionPane.showMessageDialog(null,
532 "Invalid xml file: root node not 'URL_Template'", "ERROR",
533 JOptionPane.ERROR_MESSAGE);
534 return null;
535 }
536
537 NodeList templateElements = root.getElementsByTagName("template");
538 for (int idx = 0; idx < templateElements.getLength(); idx++) {
539 Element e = (Element) templateElements.item(idx);
540 // Assuming the document has been normalized
541 Node textNode = e.getFirstChild();
542 if (textNode==null) { continue; } // empty template
543 URLTemplate ut = new URLTemplate(
544 e.getAttribute("journal"), textNode.getNodeValue() );
545 String att;
546 if (!(att=e.getAttribute("minVolume")).equals("")) { ut.setMinVolume(Integer.parseInt(att)); }
547 if (!(att=e.getAttribute("maxVolume")).equals("")) { ut.setMaxVolume(Integer.parseInt(att)); }
548 if (!(att=e.getAttribute("minNumber")).equals("")) { ut.setMinNumber(Integer.parseInt(att)); }
549 if (!(att=e.getAttribute("maxNumber")).equals("")) { ut.setMaxNumber(Integer.parseInt(att)); }
550 if (!(att=e.getAttribute("minFirstpage")).equals("")) { ut.setMinFirstpage(Integer.parseInt(att)); }
551 if (!(att=e.getAttribute("maxFirstpage")).equals("")) { ut.setMaxFirstpage(Integer.parseInt(att)); }
552 if (!(att=e.getAttribute("minYear")).equals("")) { ut.setMinYear(Integer.parseInt(att)); }
553 if (!(att=e.getAttribute("maxYear")).equals("")) { ut.setMaxYear(Integer.parseInt(att)); }
554
555 journalTemplates.add(ut);
556 }
557 }
558 // catch (FactoryConfigurationError factoryConfigurationError) {
559 // factoryConfigurationError.printStackTrace();
560 // }
561 catch (ParserConfigurationException e) {
562 e.printStackTrace();
563 }
564 catch (SAXException e) {
565 JOptionPane.showMessageDialog(null,
566 "Problem while parsing XML file (SAXException).",
567 "ERROR", JOptionPane.ERROR_MESSAGE);
568 return null;
569 }
570 catch (FileNotFoundException e) {
571 JOptionPane.showMessageDialog(null,
572 "File not found: "+e.getMessage(),
573 "ERROR", JOptionPane.ERROR_MESSAGE);
574 return null;
575 }
576 catch (IOException e) {
577 e.printStackTrace();
578 return null;
579 }
580 return journalTemplates;
581 }
582
583 private static void saveURLTemplates(File file){
584 if (file.exists()) { return; }
585
586 Document document;
587 try {
588 final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
589 final DocumentBuilder builder = factory.newDocumentBuilder();
590 document = builder.newDocument();
591
592 Element URLTemplateRoot = document.createElement("URL_Templates");
593 addTemplateElements(URLTemplateRoot, document);
594 document.appendChild(URLTemplateRoot);
595
596 TransformerFactory tFactory = TransformerFactory.newInstance();
597 Transformer transformer = tFactory.newTransformer();
598
599 //transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "JRefTree.dtd");
600 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
601 Enumeration propertyNames = transformer.getOutputProperties().propertyNames();
602 while (propertyNames.hasMoreElements()) {
603 String nextProp = propertyNames.nextElement().toString();
604 if (nextProp.indexOf("indent-amount")>=0) {
605 transformer.setOutputProperty(nextProp,"4");
606 break;
607 }
608 }
609 //transformer.getOutputProperties().list(System.out);
610
611 DOMSource source = new DOMSource(document);
612 StreamResult result = new StreamResult(new FileWriter(file));
613 transformer.transform(source, result);
614 }
615 catch (FactoryConfigurationError factoryConfigurationError) {
616 factoryConfigurationError.printStackTrace();
617 }
618 catch (ParserConfigurationException e) {
619 e.printStackTrace();
620 }
621 catch (DOMException e) {
622 e.printStackTrace();
623 }
624 catch (TransformerFactoryConfigurationError transformerFactoryConfigurationError) {
625 transformerFactoryConfigurationError.printStackTrace();
626 }
627 catch (TransformerException e) {
628 e.printStackTrace();
629 }
630 catch (IllegalArgumentException e) {
631 e.printStackTrace();
632 }
633 catch (IOException e) {
634 JOptionPane.showMessageDialog(null,
635 "Could not write file: "+e.getMessage(),
636 "ERROR", JOptionPane.ERROR_MESSAGE);
637 return;
638 }
639 }
640
641 private static void addTemplateElements(Element URLTemplateRoot, Document d) {
642 Element ut;
643
644 URLTemplateRoot.appendChild(d.createComment(
645 " The main element is called 'URL_Templates'. It has no attributes.\n"+
646 " Within URL_Templates, there is only one kind of element: 'template'.\n"+
647 " This element must have the attribute 'journal', and can in addition\n"+
648 " have attributes 'minVolume', 'maxVolume', 'minIssue', 'maxIssue',\n"+
649 " 'minFirstpage', 'maxFirstpage', 'minYear', and 'maxYear'.\n"+
650 " The 'journal' attribute can be a regular expressions (or just normal text).\n"+
651 " The other attributes are non-negative integers.\n"+
652 " The content of each 'template' element (between <template ...> and\n"+
653 " </template>) can include either {X} or {X,text},\n"+
654 " where X is one of V, N, P, Y (volume, number/issue, first page,\n"+
655 " and year, respectively). The 'text' is background text that the\n"+
656 " first part can overwrite. For example, say we have '{V,00000}',\n"+
657 " and assume that the volume is '86'. The result is then '00086'\n"+
658 " (if the volume was 123456, then the result would be just '123456').\n"+
659 " Another example: If template = 'http://prl.aps.org/v{V}/i{N}/p{P,abcdef}'\n"+
660 " and V='234', N='2', and P='99', we get 'http://prl.aps.org/v234/i2/pabcd99'."
661 ));
662
663 // Phys. Rev. Lett.
664 ut = d.createElement("template");
665 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *Lett((ers?)|\\.)? *");
666 ut.setAttribute("maxVolume","83");
667 ut.appendChild(d.createTextNode("http://prola.aps.org/pdf/PRL/v{V}/"+
668 "i{N}/p{P}_1"));
669 URLTemplateRoot.appendChild(ut);
670
671 ut = d.createElement("template");
672 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *Lett((ers?)|\\.)? *");
673 ut.setAttribute("minVolume","84");
674 ut.setAttribute("maxVolume","999");
675 ut.appendChild(d.createTextNode(
676 "http://ojps.aip.org/getpdf/servlet/GetPDFServlet?filetype=pdf&"+
677 "id=PRLTAO{V,000000}{N,000000}{P,000000}000001&idtype=cvips"));
678 URLTemplateRoot.appendChild(ut);
679
680 // Phys. Rev. A
681 ut = d.createElement("template");
682 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *A\\.? *");
683 ut.setAttribute("maxVolume","60");
684 ut.appendChild(d.createTextNode("http://prola.aps.org/pdf/PRA/v{V}/"+
685 "i{N}/p{P}_1"));
686 URLTemplateRoot.appendChild(ut);
687
688 ut = d.createElement("template");
689 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *A\\.? *");
690 ut.setAttribute("minVolume","61");
691 ut.setAttribute("maxVolume","999");
692 ut.appendChild(d.createTextNode(
693 "http://ojps.aip.org/getpdf/servlet/GetPDFServlet?filetype=pdf&"+
694 "id=PLRAAN{V,000000}{N,000000}{P,000000}000001&idtype=cvips"));
695 URLTemplateRoot.appendChild(ut);
696
697 // Phys. Rev. B
698 ut = d.createElement("template");
699 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *B\\.? *");
700 ut.setAttribute("maxVolume","60");
701 ut.appendChild(d.createTextNode("http://prola.aps.org/pdf/PRB/v{V}/"+
702 "i{N}/p{P}_1"));
703 URLTemplateRoot.appendChild(ut);
704
705 ut = d.createElement("template");
706 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *B\\.? *");
707 ut.setAttribute("minVolume","61");
708 ut.setAttribute("maxVolume","999");
709 ut.appendChild(d.createTextNode(
710 "http://ojps.aip.org/getpdf/servlet/GetPDFServlet?filetype=pdf&"+
711 "id=PRBMDO{V,000000}{N,000000}{P,000000}000001&idtype=cvips"));
712 URLTemplateRoot.appendChild(ut);
713
714 // Phys. Rev. C
715 ut = d.createElement("template");
716 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *C\\.? *");
717 ut.setAttribute("maxVolume","60");
718 ut.appendChild(d.createTextNode("http://prola.aps.org/pdf/PRC/v{V}/"+
719 "i{N}/p{P}_1"));
720 URLTemplateRoot.appendChild(ut);
721
722 ut = d.createElement("template");
723 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *C\\.? *");
724 ut.setAttribute("minVolume","61");
725 ut.setAttribute("maxVolume","999");
726 ut.appendChild(d.createTextNode(
727 "http://ojps.aip.org/getpdf/servlet/GetPDFServlet?filetype=pdf&"+
728 "id=PRVCAN{V,000000}{N,000000}{P,000000}000001&idtype=cvips"));
729 URLTemplateRoot.appendChild(ut);
730
731 // Phys. Rev. D
732 ut = d.createElement("template");
733 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *D\\.? *");
734 ut.setAttribute("maxVolume","60");
735 ut.appendChild(d.createTextNode("http://prola.aps.org/pdf/PRD/v{V}/"+
736 "i{N}/p{P}_1"));
737 URLTemplateRoot.appendChild(ut);
738
739 ut = d.createElement("template");
740 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *D\\.? *");
741 ut.setAttribute("minVolume","61");
742 ut.setAttribute("maxVolume","999");
743 ut.appendChild(d.createTextNode(
744 "http://ojps.aip.org/getpdf/servlet/GetPDFServlet?filetype=pdf&"+
745 "id=PRVDAQ{V,000000}{N,000000}{P,000000}000001&idtype=cvips"));
746 URLTemplateRoot.appendChild(ut);
747
748 // Phys. Rev. E
749 ut = d.createElement("template");
750 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *E\\.? *");
751 ut.setAttribute("maxVolume","60");
752 ut.appendChild(d.createTextNode("http://prola.aps.org/pdf/PRE/v{V}/"+
753 "i{N}/p{P}_1"));
754 URLTemplateRoot.appendChild(ut);
755
756 ut = d.createElement("template");
757 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *E\\.? *");
758 ut.setAttribute("minVolume","61");
759 ut.setAttribute("maxVolume","999");
760 ut.appendChild(d.createTextNode(
761 "http://ojps.aip.org/getpdf/servlet/GetPDFServlet?filetype=pdf&"+
762 "id=PLEEE8{V,000000}{N,000000}{P,000000}000001&idtype=cvips"));
763 URLTemplateRoot.appendChild(ut);
764
765 // Rev. Mod. Phys.
766 ut = d.createElement("template");
767 ut.setAttribute("journal","(?i)Rev((iews)|\\.)? *(of)? *Mod((ern)|\\.)? *Phys((ics)|\\.)? *");
768 ut.setAttribute("maxVolume","71");
769 ut.appendChild(d.createTextNode("http://prola.aps.org/pdf/RMP/v{V}/"+
770 "i{N}/p{P}_1"));
771 URLTemplateRoot.appendChild(ut);
772
773 ut = d.createElement("template");
774 ut.setAttribute("journal","(?i)Rev((iews)|\\.)? *(of)? *Mod((ern)|\\.)? *Phys((ics)|\\.)? *");
775 ut.setAttribute("minVolume","72");
776 ut.setAttribute("maxVolume","999");
777 ut.appendChild(d.createTextNode(
778 "http://ojps.aip.org/getpdf/servlet/GetPDFServlet?filetype=pdf&"+
779 "id=RMPHAT{V,000000}{N,000000}{P,000000}000001&idtype=cvips"));
780 URLTemplateRoot.appendChild(ut);
781
782 // Phys. Rev. Series II
783 ut = d.createElement("template");
784 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *");
785 ut.appendChild(d.createTextNode("http://prola.aps.org/pdf/PR/v{V}/"+
786 "i{N}/p{P}_1"));
787 URLTemplateRoot.appendChild(ut);
788
789 // Phys. Rev. Series I
790 ut = d.createElement("template");
791 ut.setAttribute("journal","(?i)Phys((ical)|\\.)? *Rev((iew)|\\.)? *I\\.? *");
792 ut.appendChild(d.createTextNode("http://prola.aps.org/pdf/PRI/v{V}/"+
793 "i{N}/p{P}_1"));
794 URLTemplateRoot.appendChild(ut);
795 }
796 }