1 32 33 package websphinx; 34 35 import java.io.*; 36 import java.net.URL ; 37 import java.net.MalformedURLException ; 38 import java.util.Vector ; 39 40 46 47 public class Mirror extends LinkTransformer { 49 String root; 50 52 Vector files = new Vector (); 53 56 boolean needRewrite = false; 57 58 String defaultFilename = "index.html"; 59 62 67 public Mirror (String directory) throws IOException { 68 super ((HTMLTransformer)null); 69 if (!directory.endsWith ("/")) 70 directory += "/"; 71 File rootFile = new File (directory); 72 if (!rootFile.isAbsolute ()) 73 rootFile = new File (rootFile.getAbsolutePath ()); 74 URL rootURL = Link.FileToURL (rootFile); 75 root = rootURL.toExternalForm (); 76 } 77 78 85 public String getDefaultFilename () { 86 return defaultFilename; 87 } 88 89 96 public synchronized void setDefaultFilename (String filename) { 97 defaultFilename = filename; 98 } 99 100 104 public synchronized int getPageCount () { 105 return files.size (); 106 } 107 108 public void write (Region region) throws IOException { 109 throw new IOException ("write(Region) not supported by Mirror"); 110 } 111 112 public void write (String string) throws IOException { 113 throw new IOException ("write(String) not supported by Mirror"); 114 } 115 116 122 public synchronized void writePage (Page page) throws IOException { 123 URL url = page.getURL (); 124 String local = toLocalFileURL (url); 125 URL localURL = new URL (local); 126 File localFile = Link.URLToFile (localURL); 127 128 File parent = new File (localFile.getParent ()); 129 if (parent != null) 130 Access.getAccess ().makeDir (parent); 131 132 MirrorTransformer out = new MirrorTransformer (this, localFile); 133 out.setBase (localURL); 134 out.setEmitBaseElement (getEmitBaseElement ()); 135 out.writePage (page); 136 out.close (); 137 138 needRewrite = !files.isEmpty (); 139 files.addElement (out); 140 } 141 142 146 public synchronized void close () throws IOException { 147 rewrite (); 148 } 149 150 153 public synchronized void rewrite () throws IOException { 154 if (needRewrite) { 155 for (int i=0, n = files.size (); i < n; ++i) { 156 RewritableLinkTransformer r = 157 (RewritableLinkTransformer)files.elementAt (i); 158 r.rewrite (); 159 } 160 needRewrite = false; 161 } 162 } 163 164 private String toLocalFileURL (URL remoteURL) { 167 if (isMapped (remoteURL)) 168 return lookup (null, remoteURL); 169 170 String remote = remoteURL.toExternalForm (); 171 URL remoteDirURL = Link.getDirectoryURL (remoteURL); 172 String remoteDir = remoteDirURL.toExternalForm(); 173 String remoteFile = (remote.length() > remoteDir.length()) ? encode (remote.substring (remoteDir.length())) : defaultFilename; 174 String localDir = toLocalDirURL (remoteDirURL); 175 String local = localDir + remoteFile; 176 177 map (remoteURL, local); 178 return local; 179 } 180 181 private String toLocalDirURL (URL remoteURL) { 184 if (isMapped (remoteURL)) 185 return lookupDir (null, remoteURL); 186 187 String remote = remoteURL.toExternalForm (); 188 String local; 189 URL remoteParentURL = Link.getParentURL (remoteURL); 190 191 if (remoteParentURL.equals (remoteURL)) { 192 String host = remoteURL.getHost (); 194 int port = remoteURL.getPort (); 195 local = root 196 + encode ((port != -1) ? host + ":" + port : host) 197 + '/'; 198 } 199 else { 200 String remoteParent = remoteParentURL.toExternalForm(); 201 String remoteFile = encode (remote.substring (remoteParent.length(), 202 remote.length()-1)); 203 String localDir = toLocalDirURL (remoteParentURL); 204 local = localDir + remoteFile + "/"; 205 } 206 207 map (remoteURL, local); 208 return local; 209 } 210 211 218 public synchronized void mapDir (URL url, String dir) throws MalformedURLException { 219 if (!dir.endsWith ("/")) 220 dir += "/"; 221 map (Link.getDirectoryURL (url), 222 Link.FileToURL (new File (dir + defaultFilename)) 223 .toString()); 224 } 225 226 234 public String lookupDir (URL base, URL url) { 235 String href = lookup (base, url); 236 int lastSlash = href.lastIndexOf ('/'); 237 return href.substring(0, lastSlash+1); 238 } 239 240 private static String canonicalDir (String dir) { 241 dir = dir.replace ('\\', '/'); 242 if (!dir.endsWith ("/")) 243 dir += "/"; 244 if (!dir.startsWith ("/")) 245 dir = "/" + dir; 246 return dir; 247 } 248 249 private static String encode (String component) { 250 char[] chars = component.toCharArray (); 251 252 for (int i=0; i<chars.length; ++i) 253 switch (chars[i]) { 254 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': 255 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': 256 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 257 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': 258 case 'Y': case 'Z': 259 260 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': 261 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': 262 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': 263 case 's': case 't': case 'u': case 'v': case 'w': case 'x': 264 case 'y': case 'z': 265 266 case '0': case '1': case '2': case '3': case '4': 267 case '5': case '6': case '7': case '8': case '9': 268 269 case '.': case '-': case '_': case '~': 270 271 break; 272 273 default: 274 chars[i] = '_'; 275 break; 276 } 277 278 return new String (chars); 279 } 280 281 285 public static void main (String [] args) throws Exception { 286 String directory = args[args.length-1]; 287 Mirror out = new Mirror (directory); 288 out.mapDir (new URL (args[0]), directory); 289 for (int i=0; i<args.length-1; ++i) { 290 Link link = new Link (args[i]); 291 Page page = new Page (link); 292 out.writePage (page); 293 } 294 out.close (); 295 } 296 297 } 298 299 class MirrorTransformer extends RewritableLinkTransformer { 300 Mirror mirror; 302 public MirrorTransformer (Mirror mirror, File file) throws IOException { 303 super (file.toString()); 304 this.mirror = mirror; 305 } 306 307 public String lookup (URL base, URL url) { 308 return mirror.lookup (base, url); 309 } 310 311 public void map (URL remoteURL, String href) { 312 mirror.map (remoteURL, href); 313 } 314 315 public void map (URL remoteURL, URL url) { 316 mirror.map (remoteURL, url); 317 } 318 319 public boolean isMapped (URL url) { 320 return mirror.isMapped (url); 321 } 322 } 323 324 | Popular Tags |