001    package railo.runtime.functions.file;
002    
003    import java.io.IOException;
004    import java.util.Date;
005    import java.util.Iterator;
006    
007    import railo.commons.io.res.Resource;
008    import railo.commons.lang.StringUtil;
009    import railo.runtime.PageContext;
010    import railo.runtime.dump.DumpData;
011    import railo.runtime.dump.DumpProperties;
012    import railo.runtime.exp.ExpressionException;
013    import railo.runtime.exp.PageException;
014    import railo.runtime.exp.PageRuntimeException;
015    import railo.runtime.type.Collection;
016    import railo.runtime.type.KeyImpl;
017    import railo.runtime.type.Struct;
018    import railo.runtime.type.StructImpl;
019    import railo.runtime.type.dt.DateTime;
020    import railo.runtime.type.dt.DateTimeImpl;
021    import railo.runtime.type.util.StructSupport;
022    
023    public abstract class FileStreamWrapper extends StructSupport implements Struct {
024    
025            public static final String STATE_OPEN = "open";
026            public static final String STATE_CLOSE = "close";
027            
028            protected Resource res;
029            private String status=STATE_OPEN;
030            private Struct info;
031            private long lastModifed;
032            private long length;
033            
034            
035            public FileStreamWrapper(Resource res) {
036                    this.res=res;
037                    this.lastModifed=System.currentTimeMillis();
038                    this.length=res.length();
039            }
040    
041            public final String getFilename() {
042                    return res.getName();
043            }
044    
045            public final String getLabel(){
046                    return StringUtil.ucFirst(res.getResourceProvider().getScheme())+": "+getFilename();
047            }
048            
049            
050            public final String getFilepath() {
051                    return res.getAbsolutePath();
052            }
053            
054    
055            public final String getStatus() {
056                    return status;
057            }
058    
059            public final void setStatus(String status) {
060                    this.status=status;
061            }
062            
063            public final Date getLastmodified() {
064                    return new DateTimeImpl(lastModifed,false);
065            }
066            
067            public Object getMetadata() {
068                    return info();
069            }
070            
071            public Struct info() {
072                    if(info==null) {
073                            info=new StructImpl();
074                            info.setEL("mode", getMode());
075                            info.setEL(KeyImpl.NAME, res.getName());
076                            info.setEL(KeyImpl.PATH, res.getParent());
077                            info.setEL("status", getStatus());
078                            info.setEL(KeyImpl.SIZE, getSize()+" bytes");
079                            info.setEL("lastmodified", getLastmodified());
080                    }
081                    
082                    return info;
083            }
084            
085            public boolean isEndOfFile() {
086                    return false;
087            }
088            
089            public long getSize() {
090                    return length;
091            }
092            
093            
094            public void write(Object obj) throws IOException {
095                    throw notSupported("write");
096            }
097    
098            public String readLine() throws IOException {
099                    throw notSupported("readLine");
100            }
101            
102            public Object read(int len) throws IOException{
103                    throw notSupported("read");
104            }
105            
106            public abstract String getMode();
107            public abstract void close() throws IOException;
108            
109            private IOException notSupported(String method) {
110                    return new IOException(method+" can't be called when the file is opened in ["+getMode()+"] mode");
111            }
112    
113            public Resource getResource() {
114                    return res;
115            }
116    
117            /**
118             *
119             * @see java.lang.Object#toString()
120             */
121            public String toString() {
122                    return res.getAbsolutePath();
123            }
124    
125            /**
126             *
127             * @see railo.runtime.type.Collection#clear()
128             */
129            public void clear() {
130                    throw new RuntimeException("can't clear struct, struct is readonly");
131                    
132            }
133            
134            /**
135             * @see railo.runtime.type.Collection#containsKey(railo.runtime.type.Collection.Key)
136             */
137            public boolean containsKey(Key key) {
138                    return info().containsKey(key);
139            }
140    
141            /**
142             * @see railo.runtime.type.Collection#duplicate(boolean)
143             */
144            public Collection duplicate(boolean deepCopy) {
145                    throw new RuntimeException("can't duplicate File Object, Object depends on File Stream");
146            }
147            
148            
149            /**
150             *
151             * @see railo.runtime.type.Collection#get(railo.runtime.type.Collection.Key)
152             */
153            public Object get(Key key) throws PageException {
154                    return info().get(key);
155            }
156    
157            /**
158             *
159             * @see railo.runtime.type.Collection#get(railo.runtime.type.Collection.Key, java.lang.Object)
160             */
161            public Object get(Key key, Object defaultValue) {
162                    return info().get(key, defaultValue);
163            }
164    
165            /**
166             * @see railo.runtime.type.Collection#keys()
167             */
168            public Key[] keys() {
169                    return info.keys();
170            }
171    
172            /**
173             *
174             * @see railo.runtime.type.Collection#keysAsString()
175             */
176            public String[] keysAsString() {
177                    return info().keysAsString();
178            }
179    
180            public Object remove(Key key) throws PageException {
181                    throw new PageRuntimeException("can't remove key ["+key.getString()+"] from struct, struct is readonly");
182            }
183    
184            /**
185             *
186             * @see railo.runtime.type.Collection#removeEL(railo.runtime.type.Collection.Key)
187             */
188            public Object removeEL(Key key) {
189                    throw new PageRuntimeException("can't remove key ["+key.getString()+"] from struct, struct is readonly");
190            }
191    
192            /**
193             *
194             * @see railo.runtime.type.Collection#set(railo.runtime.type.Collection.Key, java.lang.Object)
195             */
196            public Object set(Key key, Object value) throws PageException {
197                    throw new ExpressionException("can't set key ["+key.getString()+"] to struct, struct is readonly");
198            }
199    
200            /**
201             * @see railo.runtime.type.Collection#setEL(railo.runtime.type.Collection.Key, java.lang.Object)
202             */
203            public Object setEL(Key key, Object value) {
204                    throw new PageRuntimeException("can't set key ["+key.getString()+"] to struct, struct is readonly");
205            }
206    
207            /**
208             * @see railo.runtime.type.Collection#size()
209             */
210            public int size() {
211                    return info().size();
212            }
213    
214            /**
215             * @see railo.runtime.dump.Dumpable#toDumpData(railo.runtime.PageContext, int)
216             */
217            public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
218                    return info().toDumpData(pageContext, maxlevel,dp);
219            }
220    
221            /**
222             * @see railo.runtime.type.Iteratorable#keyIterator()
223             */
224            public Iterator keyIterator() {
225                    return info().keyIterator();
226            }
227    
228            /**
229             * @see railo.runtime.op.Castable#castToBooleanValue()
230             */
231            public boolean castToBooleanValue() throws PageException {
232                    return info().castToBooleanValue();
233            }
234        
235        /**
236         * @see railo.runtime.op.Castable#castToBoolean(java.lang.Boolean)
237         */
238        public Boolean castToBoolean(Boolean defaultValue) {
239            return info().castToBoolean(defaultValue);
240        }
241    
242            /**
243             * @see railo.runtime.op.Castable#castToDateTime()
244             */
245            public DateTime castToDateTime() throws PageException {
246                    return info().castToDateTime();
247            }
248        
249        /**
250         * @see railo.runtime.op.Castable#castToDateTime(railo.runtime.type.dt.DateTime)
251         */
252        public DateTime castToDateTime(DateTime defaultValue) {
253            return info().castToDateTime(defaultValue);
254        }
255    
256            /**
257             * @see railo.runtime.op.Castable#castToDoubleValue()
258             */
259            public double castToDoubleValue() throws PageException {
260                    return info().castToDoubleValue();
261            }
262        
263        /**
264         * @see railo.runtime.op.Castable#castToDoubleValue(double)
265         */
266        public double castToDoubleValue(double defaultValue) {
267            return info().castToDoubleValue(defaultValue); 
268        }
269    
270            /**
271             *
272             * @see railo.runtime.op.Castable#castToString()
273             */
274            public String castToString() throws PageException {
275                    return info().castToString();
276            }
277            /**
278             * @see railo.runtime.type.util.StructSupport#castToString(java.lang.String)
279             */
280            public String castToString(String defaultValue) {
281                    return info().castToString(defaultValue);
282            }
283    
284            /**
285             *
286             * @see railo.runtime.op.Castable#compareTo(java.lang.String)
287             */
288            public int compareTo(String str) throws PageException {
289                    return info().compareTo(str);
290            }
291    
292            /**
293             *
294             * @see railo.runtime.op.Castable#compareTo(boolean)
295             */
296            public int compareTo(boolean b) throws PageException {
297                    return info().compareTo(b);
298            }
299    
300            /**
301             * @see railo.runtime.op.Castable#compareTo(double)
302             */
303            public int compareTo(double d) throws PageException {
304                    return info().compareTo(d);
305            }
306    
307            /**
308             * @see railo.runtime.op.Castable#compareTo(railo.runtime.type.dt.DateTime)
309             */
310            public int compareTo(DateTime dt) throws PageException {
311                    return info.compareTo(dt);
312            }
313    
314            /**
315             * @see java.util.Map#containsValue(java.lang.Object)
316             */
317            public boolean containsValue(Object value) {
318                    return info().containsValue(value);
319            }
320    
321            /**
322             * @see java.util.Map#values()
323             */
324            public java.util.Collection values() {
325                    return info().values();
326            }
327    
328            public abstract void skip(int len) throws PageException;
329    
330            public abstract void seek(long pos) throws PageException;
331    }