001 package railo.commons.io.res.type.s3; 002 003 import java.io.ByteArrayInputStream; 004 import java.io.File; 005 import java.io.IOException; 006 import java.io.InputStream; 007 import java.io.OutputStream; 008 009 import railo.commons.io.res.Resource; 010 import railo.commons.io.res.util.ResourceUtil; 011 import railo.runtime.engine.ThreadLocalPageContext; 012 013 public final class TemporaryStream extends OutputStream { 014 015 private static final int MAX_MEMORY = 1024*1024; 016 private static int index=1; 017 private static Resource tempFile; 018 019 private Resource persis; 020 private long count=0; 021 private OutputStream os; 022 public boolean memoryMode=true; 023 public boolean available=false; 024 025 /** 026 * Constructor of the class 027 */ 028 public TemporaryStream() { 029 do { 030 this.persis=getTempDirectory().getRealResource("temporary-stream-"+(index++)); 031 } 032 while(persis.exists()); 033 os=new java.io.ByteArrayOutputStream(); 034 } 035 036 /** 037 * @see java.io.OutputStream#write(int) 038 */ 039 public void write(int b) throws IOException { 040 count++; 041 check(); 042 os.write(b); 043 } 044 045 /** 046 * @see java.io.OutputStream#write(byte[], int, int) 047 */ 048 public void write(byte[] b, int off, int len) throws IOException { 049 count+=len; 050 check(); 051 os.write(b, off, len); 052 } 053 054 /** 055 * @see java.io.OutputStream#write(byte[]) 056 */ 057 public void write(byte[] b) throws IOException { 058 count+=b.length; 059 check(); 060 os.write(b); 061 } 062 063 private void check() throws IOException { 064 if(memoryMode && count>=MAX_MEMORY && os instanceof java.io.ByteArrayOutputStream) { 065 memoryMode=false; 066 OutputStream nos = persis.getOutputStream(); 067 nos.write(((java.io.ByteArrayOutputStream)os).toByteArray()); 068 os=nos; 069 } 070 } 071 072 073 /** 074 * @see java.io.OutputStream#close() 075 */ 076 public void close() throws IOException { 077 os.close(); 078 available=true; 079 } 080 081 /** 082 * @see java.io.OutputStream#flush() 083 */ 084 public void flush() throws IOException { 085 os.flush(); 086 } 087 088 public InputStream getInputStream() throws IOException { 089 return new InpuStreamWrap(this); 090 } 091 092 class InpuStreamWrap extends InputStream { 093 094 private TemporaryStream ts; 095 private InputStream is; 096 097 public InpuStreamWrap(TemporaryStream ts) throws IOException { 098 this.ts=ts; 099 if(ts.os instanceof java.io.ByteArrayOutputStream) { 100 is=new ByteArrayInputStream(((java.io.ByteArrayOutputStream)ts.os).toByteArray()); 101 } 102 else if(ts.available) { 103 ts.available=false; 104 try { 105 is=ts.persis.getInputStream(); 106 } catch (IOException e) { 107 ts.persis.delete(); 108 throw e; 109 } 110 } 111 else 112 throw new IOException("InputStream no longer available"); 113 } 114 115 /** 116 * @see java.io.InputStream#read() 117 */ 118 public int read() throws IOException { 119 return is.read(); 120 } 121 122 /** 123 * @see java.io.InputStream#available() 124 */ 125 public int available() throws IOException { 126 return is.available(); 127 } 128 129 /** 130 * @see java.io.InputStream#close() 131 */ 132 public void close() throws IOException { 133 ts.persis.delete(); 134 is.close(); 135 } 136 137 /** 138 * 139 * @see java.io.InputStream#mark(int) 140 */ 141 public synchronized void mark(int readlimit) { 142 is.mark(readlimit); 143 } 144 145 /** 146 * 147 * @see java.io.InputStream#markSupported() 148 */ 149 public boolean markSupported() { 150 return is.markSupported(); 151 } 152 153 /** 154 * 155 * @see java.io.InputStream#read(byte[], int, int) 156 */ 157 public int read(byte[] b, int off, int len) throws IOException { 158 return is.read(b, off, len); 159 } 160 161 /** 162 * 163 * @see java.io.InputStream#read(byte[]) 164 */ 165 public int read(byte[] b) throws IOException { 166 return is.read(b); 167 } 168 169 /** 170 * 171 * @see java.io.InputStream#reset() 172 */ 173 public synchronized void reset() throws IOException { 174 is.reset(); 175 } 176 177 /** 178 * 179 * @see java.io.InputStream#skip(long) 180 */ 181 public long skip(long n) throws IOException { 182 return is.skip(n); 183 } 184 } 185 186 public long length() { 187 return count; 188 } 189 190 public static Resource getTempDirectory() { 191 if(tempFile!=null) return tempFile; 192 String tmpStr = System.getProperty("java.io.tmpdir"); 193 if(tmpStr!=null) { 194 195 tempFile=ResourceUtil.toResourceNotExisting(ThreadLocalPageContext.get(), tmpStr); 196 //tempFile=CFMLEngineFactory.getInstance().getCastUtil().toResource(tmpStr,null); 197 198 if(tempFile!=null && tempFile.exists()) { 199 tempFile=getCanonicalResourceEL(tempFile); 200 return tempFile; 201 } 202 } 203 File tmp =null; 204 try { 205 tmp = File.createTempFile("a","a"); 206 tempFile=ResourceUtil.toResourceNotExisting(ThreadLocalPageContext.get(), tmp.getParent()); 207 //tempFile=CFMLEngineFactory.getInstance().getCastUtil().toResource(tmp.getParent(),null); 208 tempFile=getCanonicalResourceEL(tempFile); 209 } 210 catch(IOException ioe) {} 211 finally { 212 if(tmp!=null)tmp.delete(); 213 } 214 return tempFile; 215 } 216 217 private static Resource getCanonicalResourceEL(Resource res) { 218 try { 219 return res.getCanonicalResource(); 220 } catch (IOException e) { 221 return res.getAbsoluteResource(); 222 } 223 } 224 }