1 /*
2  ******************************************************************************
3  * Copyright (C) 2004-2005, International Business Machines Corporation and        *
4  * others. All Rights Reserved.                                               *
5  ******************************************************************************
6  *
7  * in shell:  (such as .cldrrc)
8  *   export CWDEBUG="-DCLDR_DTD_CACHE=/tmp/cldrdtd/"
9  *   export CWDEFS="-DCLDR_DTD_CACHE_DEBUG=y ${CWDEBUG}"
10  *
11  *
12  * in code:
13  *   docBuilder.setEntityResolver(new CachingEntityResolver());
14  *
15  */
16 
17 package org.unicode.cldr.util;
18 
19 /**
20  * @author Steven R Loomis
21  *
22  * Caching entity resolver
23  */
24 import java.io.BufferedReader;
25 import java.io.BufferedWriter;
26 import java.io.File;
27 import java.io.FileWriter;
28 import java.io.InputStreamReader;
29 import java.net.MalformedURLException;
30 
31 import org.xml.sax.EntityResolver;
32 import org.xml.sax.InputSource;
33 
34 /**
35  * Use this class to cache DTDs, speeding up tools.
36  */
37 public class CachingEntityResolver implements EntityResolver {
38     static final String CLDR_DTD_CACHE = "CLDR_DTD_CACHE";
39     static final String CLDR_DTD_OVERRIDE = "CLDR_DTD_OVERRIDE";
40     private static String gCacheDir = null;
41     private static String gOverrideDir = System.getProperty(CLDR_DTD_OVERRIDE);
42     private static boolean gCheckedEnv = false;
43     private static boolean gDebug = false;
44 
45     // TODO: synch?
46 
47     /**
48      * Create the cache dir if it doesn't exist.
49      * delete all regular files within the cache dir.
50      */
createAndEmptyCacheDir()51     public static void createAndEmptyCacheDir() {
52         if (getCacheDir() == null) {
53             return;
54         }
55         File cacheDir = new File(getCacheDir());
56         cacheDir.mkdir();
57         File cachedFiles[] = cacheDir.listFiles();
58         if (cachedFiles != null) {
59             for (int i = 0; i < cachedFiles.length; i++) {
60                 if (cachedFiles[i].isFile()) {
61                     cachedFiles[i].delete();
62                 }
63             }
64         }
65     }
66 
setCacheDir(String s)67     public static void setCacheDir(String s) {
68         gCacheDir = s;
69         if ((gCacheDir == null) || (gCacheDir.length() <= 0)) {
70             gCacheDir = null;
71         }
72     }
73 
getCacheDir()74     public static String getCacheDir() {
75         // boolean aDebug = false;
76         // if((System.getProperty("CLDR_DTD_CACHE_DEBUG")!=null) ||
77         // "y".equals(System.getProperty("CLDR_DTD_CACHE_ADEBUG"))) {
78         // aDebug = true;
79         // }
80 
81         if ((gCacheDir == null) && (!gCheckedEnv)) {
82             gCacheDir = System.getProperty(CLDR_DTD_CACHE);
83 
84             if (gCacheDir == null) {
85                 if (gDebug) {
86                     System.err.println("CLDR_DTD_CACHE = " + System.getProperty(CLDR_DTD_CACHE));
87                     System.err.println("CLDR_DTD_CACHE_DEBUG = " + System.getProperty("CLDR_DTD_CACHE_DEBUG"));
88                 }
89                 // String tmpdir = System.getProperty("java.io.tmpdir"));
90                 // if(tmpdir != null && tmpdir.length()>0) {
91                 // File f = new File(tmpdir);
92                 // if(f.canWrite()) {
93                 // }
94                 // }
95                 // for (Object s : System.getProperties().keySet() ) {
96                 // //System.err.println("tmp was " + System.getProperty("java.tmp"));
97                 // System.err.println(s);
98                 // }
99             }
100 
101             if (gDebug) {
102                 System.out.println("CRE:  " + CLDR_DTD_CACHE + " = " + gCacheDir);
103             }
104 
105             if ((gCacheDir == null) || (gCacheDir.length() <= 0)) {
106                 gCacheDir = null;
107             }
108             if ((gOverrideDir == null) || (gOverrideDir.length() <= 0)) {
109                 gOverrideDir = null;
110             }
111             gCheckedEnv = true;
112         }
113         return gCacheDir;
114     }
115 
resolveEntity(String publicId, String systemId)116     public InputSource resolveEntity(String publicId, String systemId) {
117         boolean aDebug = gDebug;
118         if ((System.getProperty("CLDR_DTD_CACHE_DEBUG") != null)
119             || "y".equals(System.getProperty("CLDR_DTD_CACHE_ADEBUG"))) {
120             aDebug = true;
121         }
122 
123         String theCache = getCacheDir();
124 
125         if (aDebug) {
126             System.out.println("CRE:  " + publicId + " | " + systemId + ", cache=" + theCache + ", override="
127                 + gOverrideDir);
128         }
129 
130         if (theCache != null) {
131             int i;
132 
133             if (systemId.startsWith("/")) {
134                 File xFile = new File(systemId);
135                 if (xFile.canRead()) {
136                     String newUrl;
137                     try {
138                         newUrl = xFile.toURI().toURL().toString();
139                         if (gDebug) System.err.println("CRE: redir to " + newUrl);
140 
141                         InputSource is = new InputSource(newUrl);
142                         is.setEncoding("UTF8");
143                         return is;
144                     } catch (MalformedURLException e) {
145                         // TODO Auto-generated catch block
146                         e.printStackTrace();
147                     }
148                 }
149             }
150             if (systemId.startsWith("file:") || !systemId.startsWith("http://")) {
151                 // File xFile = new File(systemId);
152                 // if(xFile.canRead()) {
153                 return new InputSource(systemId);
154                 // }
155                 // return null;
156             }
157             StringBuffer systemNew = new StringBuffer(systemId);
158             // char c = systemNew.charAt(0);
159             // if((c=='.')||(c=='/')) {
160             // return null;
161             // }
162 
163             for (i = 0; i < systemNew.length(); i++) {
164                 char c = systemNew.charAt(i);
165                 if (!Character.isLetterOrDigit(c) && (c != '.')) {
166                     systemNew.setCharAt(i, '_');
167                 }
168             }
169 
170             if (aDebug) {
171                 System.out.println(systemNew.toString());
172             }
173 
174             File aDir = new File(theCache);
175             if (!aDir.exists() || !aDir.isDirectory()) {
176                 // doesn't exist or isn't a directory:
177                 System.err
178                     .println("CachingEntityResolver: Warning:  Cache not used, Directory doesn't exist, Check the value of  property "
179                         + CLDR_DTD_CACHE + " :  " + theCache);
180                 return null;
181             }
182 
183             String newName = new String(systemNew);
184 
185             File t = new File(theCache, newName);
186             if (t.exists()) {
187                 if (aDebug) {
188                     System.out.println("Using existing: " + t.getPath());
189                 }
190             } else {
191 
192                 if (gOverrideDir != null) {
193                     int lastSlash = systemId.lastIndexOf('/');
194                     if (lastSlash != -1) {
195                         String shortName = systemId.substring(lastSlash + 1, systemId.length());
196                         File aFile = new File(gOverrideDir, shortName);
197                         if (aFile.exists()) {
198                             if (aDebug) {
199                                 System.err.println("overridden " + aFile.toString());
200                             }
201                             return new InputSource(aFile.getPath());
202                         }
203                     }
204                 }
205 
206                 if (aDebug) {
207                     System.out.println(t.getPath() + " doesn't exist. fetching.");
208                 }
209 
210                 try {
211                     BufferedReader r = new BufferedReader(
212                         new InputStreamReader(new java.net.URL(systemId).openStream()));
213                     BufferedWriter w = new BufferedWriter(new FileWriter(t.getPath()));
214                     String s;
215                     while ((s = r.readLine()) != null) {
216                         w.write(s);
217                         w.newLine();
218                     }
219                     r.close();
220                     w.close();
221                 } catch (Throwable th) {
222                     System.err.println(th.toString() + " trying to fetch " + t.getPath());
223 
224                     return null;
225                 }
226                 if (aDebug) {
227                     System.out.println(t.getPath() + " fetched.");
228                 }
229             }
230 
231             return new InputSource(t.getPath());
232         }
233         return null; // unhelpful
234     }
235 }