001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.functions.file; 020 021import java.io.IOException; 022import java.util.Date; 023import java.util.Iterator; 024 025import lucee.commons.io.res.Resource; 026import lucee.commons.lang.StringUtil; 027import lucee.runtime.PageContext; 028import lucee.runtime.dump.DumpData; 029import lucee.runtime.dump.DumpProperties; 030import lucee.runtime.exp.ExpressionException; 031import lucee.runtime.exp.PageException; 032import lucee.runtime.exp.PageRuntimeException; 033import lucee.runtime.type.Collection; 034import lucee.runtime.type.Struct; 035import lucee.runtime.type.StructImpl; 036import lucee.runtime.type.dt.DateTime; 037import lucee.runtime.type.dt.DateTimeImpl; 038import lucee.runtime.type.util.KeyConstants; 039import lucee.runtime.type.util.StructSupport; 040 041public abstract class FileStreamWrapper extends StructSupport implements Struct { 042 043 public static final String STATE_OPEN = "open"; 044 public static final String STATE_CLOSE = "close"; 045 046 protected Resource res; 047 private String status=STATE_OPEN; 048 private Struct info; 049 private long lastModifed; 050 private long length; 051 052 053 public FileStreamWrapper(Resource res) { 054 this.res=res; 055 this.lastModifed=System.currentTimeMillis(); 056 this.length=res.length(); 057 } 058 059 public final String getFilename() { 060 return res.getName(); 061 } 062 063 public final String getLabel(){ 064 return StringUtil.ucFirst(res.getResourceProvider().getScheme())+": "+getFilename(); 065 } 066 067 068 public final String getFilepath() { 069 return res.getAbsolutePath(); 070 } 071 072 073 public final String getStatus() { 074 return status; 075 } 076 077 public final void setStatus(String status) { 078 this.status=status; 079 } 080 081 public final Date getLastmodified() { 082 return new DateTimeImpl(lastModifed,false); 083 } 084 085 public Object getMetadata() { 086 return info(); 087 } 088 089 public Struct info() { 090 if(info==null) { 091 info=new StructImpl(); 092 info.setEL(KeyConstants._mode, getMode()); 093 info.setEL(KeyConstants._name, res.getName()); 094 info.setEL(KeyConstants._path, res.getParent()); 095 info.setEL(KeyConstants._status, getStatus()); 096 info.setEL(KeyConstants._size, getSize()+" bytes"); 097 info.setEL(KeyConstants._lastmodified, getLastmodified()); 098 } 099 100 return info; 101 } 102 103 public boolean isEndOfFile() { 104 return false; 105 } 106 107 public long getSize() { 108 return length; 109 } 110 111 112 public void write(Object obj) throws IOException { 113 throw notSupported("write"); 114 } 115 116 public String readLine() throws IOException { 117 throw notSupported("readLine"); 118 } 119 120 public Object read(int len) throws IOException{ 121 throw notSupported("read"); 122 } 123 124 public abstract String getMode(); 125 public abstract void close() throws IOException; 126 127 private IOException notSupported(String method) { 128 return new IOException(method+" can't be called when the file is opened in ["+getMode()+"] mode"); 129 } 130 131 public Resource getResource() { 132 return res; 133 } 134 135 @Override 136 public String toString() { 137 return res.getAbsolutePath(); 138 } 139 140 @Override 141 public void clear() { 142 throw new RuntimeException("can't clear struct, struct is readonly"); 143 144 } 145 146 @Override 147 public boolean containsKey(Key key) { 148 return info().containsKey(key); 149 } 150 151 @Override 152 public Collection duplicate(boolean deepCopy) { 153 throw new RuntimeException("can't duplicate File Object, Object depends on File Stream"); 154 } 155 156 157 @Override 158 public Object get(Key key) throws PageException { 159 return info().get(key); 160 } 161 162 @Override 163 public Object get(Key key, Object defaultValue) { 164 return info().get(key, defaultValue); 165 } 166 167 @Override 168 public Key[] keys() { 169 return info().keys(); 170 } 171 172 public Object remove(Key key) throws PageException { 173 throw new PageRuntimeException("can't remove key ["+key.getString()+"] from struct, struct is readonly"); 174 } 175 176 @Override 177 public Object removeEL(Key key) { 178 throw new PageRuntimeException("can't remove key ["+key.getString()+"] from struct, struct is readonly"); 179 } 180 181 @Override 182 public Object set(Key key, Object value) throws PageException { 183 throw new ExpressionException("can't set key ["+key.getString()+"] to struct, struct is readonly"); 184 } 185 186 @Override 187 public Object setEL(Key key, Object value) { 188 throw new PageRuntimeException("can't set key ["+key.getString()+"] to struct, struct is readonly"); 189 } 190 191 @Override 192 public int size() { 193 return info().size(); 194 } 195 196 @Override 197 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) { 198 return info().toDumpData(pageContext, maxlevel,dp); 199 } 200 201 @Override 202 public Iterator<Collection.Key> keyIterator() { 203 return info().keyIterator(); 204 } 205 206 @Override 207 public Iterator<String> keysAsStringIterator() { 208 return info().keysAsStringIterator(); 209 } 210 211 @Override 212 public Iterator<Entry<Key, Object>> entryIterator() { 213 return info().entryIterator(); 214 } 215 216 @Override 217 public Iterator<Object> valueIterator() { 218 return info().valueIterator(); 219 } 220 221 @Override 222 public boolean castToBooleanValue() throws PageException { 223 return info().castToBooleanValue(); 224 } 225 226 @Override 227 public Boolean castToBoolean(Boolean defaultValue) { 228 return info().castToBoolean(defaultValue); 229 } 230 231 @Override 232 public DateTime castToDateTime() throws PageException { 233 return info().castToDateTime(); 234 } 235 236 @Override 237 public DateTime castToDateTime(DateTime defaultValue) { 238 return info().castToDateTime(defaultValue); 239 } 240 241 @Override 242 public double castToDoubleValue() throws PageException { 243 return info().castToDoubleValue(); 244 } 245 246 @Override 247 public double castToDoubleValue(double defaultValue) { 248 return info().castToDoubleValue(defaultValue); 249 } 250 251 @Override 252 public String castToString() throws PageException { 253 return info().castToString(); 254 } 255 @Override 256 public String castToString(String defaultValue) { 257 return info().castToString(defaultValue); 258 } 259 260 @Override 261 public int compareTo(String str) throws PageException { 262 return info().compareTo(str); 263 } 264 265 @Override 266 public int compareTo(boolean b) throws PageException { 267 return info().compareTo(b); 268 } 269 270 @Override 271 public int compareTo(double d) throws PageException { 272 return info().compareTo(d); 273 } 274 275 @Override 276 public int compareTo(DateTime dt) throws PageException { 277 return info.compareTo(dt); 278 } 279 280 @Override 281 public boolean containsValue(Object value) { 282 return info().containsValue(value); 283 } 284 285 @Override 286 public java.util.Collection values() { 287 return info().values(); 288 } 289 290 public abstract void skip(int len) throws PageException; 291 292 public abstract void seek(long pos) throws PageException; 293}