1 16 package org.apache.cocoon.components.source; 17 18 import java.io.File ; 19 import java.io.FileInputStream ; 20 import java.io.FileNotFoundException ; 21 import java.io.FileOutputStream ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.io.OutputStream ; 25 import java.net.MalformedURLException ; 26 import java.util.ConcurrentModificationException ; 27 28 import org.apache.avalon.framework.component.ComponentManager; 29 import org.apache.cocoon.ProcessingException; 30 import org.apache.cocoon.ResourceNotFoundException; 31 32 39 public class FileSource extends AbstractStreamWriteableSource 40 implements org.apache.cocoon.environment.WriteableSource { 41 42 43 protected File file; 44 45 46 private String systemId; 47 48 49 private boolean isHTMLContent; 50 51 54 public FileSource(String url, ComponentManager manager) { 55 56 super(manager); 57 58 if (!url.startsWith("file:")) { 59 throw new IllegalArgumentException ("Malformed url for a file source : " + url); 60 } 61 62 if (url.endsWith(".htm") || url.endsWith(".html")) { 63 this.isHTMLContent = true; 64 } 65 66 this.file = new File (url.substring(5)); } 68 69 public boolean exists() { 70 return this.file.exists(); 71 } 72 73 76 protected boolean isHTMLContent() { 77 return this.isHTMLContent; 78 } 79 80 83 public String getSystemId() { 84 if (this.systemId == null) { 85 try { 86 this.systemId = this.file.toURL().toExternalForm(); 87 } catch(MalformedURLException mue) { 88 this.systemId = "file:" + this.file.getPath(); 90 } 91 } 92 return this.systemId; 93 } 94 95 98 public InputStream getInputStream() throws IOException , ProcessingException { 99 try { 100 return new FileInputStream (this.file); 101 } catch (FileNotFoundException e) { 102 throw new ResourceNotFoundException("Resource not found " 103 + getSystemId(), e); 104 } 105 } 106 107 public long getLastModified() { 108 return this.file.lastModified(); 109 } 110 111 public long getContentLength() { 112 return this.file.length(); 113 } 114 115 124 public OutputStream getOutputStream() throws IOException , ProcessingException { 125 126 File tmpFile = new File (this.file.getPath() + ".tmp"); 129 130 tmpFile.getParentFile().mkdirs(); 132 133 if (this.file.exists() && !this.file.canWrite()) { 135 throw new IOException ("Cannot write to file " + this.file.getPath()); 136 } 137 138 if (!tmpFile.createNewFile()) { 140 throw new ConcurrentModificationException ("File " + this.file.getPath() + 141 " is already being written by another thread"); 142 } 143 144 return new FileSourceOutputStream(tmpFile); 146 } 147 148 152 public boolean canCancel(OutputStream stream) { 153 if (stream instanceof FileSourceOutputStream) { 154 FileSourceOutputStream fsos = (FileSourceOutputStream)stream; 155 if (fsos.getSource() == this) { 156 return fsos.canCancel(); 157 } 158 } 159 160 throw new IllegalArgumentException ("The stream is not associated to this source"); 162 } 163 164 167 public void cancel(OutputStream stream) throws Exception { 168 if (stream instanceof FileSourceOutputStream) { 169 FileSourceOutputStream fsos = (FileSourceOutputStream)stream; 170 if (fsos.getSource() == this) { 171 fsos.cancel(); 172 return; 173 } 174 } 175 176 throw new IllegalArgumentException ("The stream is not associated to this source"); 178 } 179 180 184 private class FileSourceOutputStream extends FileOutputStream { 185 186 private File tmpFile; 187 private boolean isClosed = false; 188 189 public FileSourceOutputStream(File tmpFile) throws IOException { 190 super(tmpFile); 191 this.tmpFile = tmpFile; 192 } 193 194 public FileSource getSource() { 195 return FileSource.this; 196 } 197 198 public void close() throws IOException { 199 super.close(); 200 201 try { 202 if (FileSource.this.file.exists()) { 204 FileSource.this.file.delete(); 205 } 206 tmpFile.renameTo(FileSource.this.file); 208 209 } finally { 210 if (tmpFile.exists()) { 213 tmpFile.delete(); 214 } 215 this.isClosed = true; 216 } 217 } 218 219 public boolean canCancel() { 220 return !this.isClosed; 221 } 222 223 public void cancel() throws Exception { 224 if (this.isClosed) { 225 throw new IllegalStateException ("Cannot cancel : outputstrem is already closed"); 226 } 227 228 this.isClosed = true; 229 super.close(); 230 this.tmpFile.delete(); 231 } 232 233 public void finalize() { 234 if (!this.isClosed && tmpFile.exists()) { 235 tmpFile.delete(); 237 } 238 } 239 } 240 } 241 | Popular Tags |