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}