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.commons.io.res;
020import java.io.IOException;
021import java.io.InputStream;
022import java.io.OutputStream;
023import java.io.Serializable;
024
025import lucee.commons.io.res.filter.ResourceFilter;
026import lucee.commons.io.res.filter.ResourceNameFilter;
027
028
029/**
030 * a Resource handle connection to different resources in a abstract form
031 */
032public interface Resource extends Serializable {
033        
034
035        public static final short ATTRIBUTE_HIDDEN=1; 
036    public static final short ATTRIBUTE_SYSTEM=2; 
037    public static final short ATTRIBUTE_ARCHIVE=4; 
038        
039        /**
040     * Tests whether the application can read the resource denoted by this
041     * abstract pathname.
042     *
043     * @return  <code>true</code> if and only if the resource specified by this
044     *          abstract pathname exists <em>and</em> can be read by the
045     *          application; <code>false</code> otherwise
046     *
047     */
048        public abstract boolean isReadable();
049        
050        /**
051     * Tests whether the application can read the resource denoted by this
052     * abstract pathname.
053     *
054     * @return  <code>true</code> if and only if the resource specified by this
055     *          abstract pathname exists <em>and</em> can be read by the
056     *          application; <code>false</code> otherwise
057     * @deprecated use instead <code>#isReadable()</code>
058     */
059        public abstract boolean canRead();
060
061    /**
062     * Tests whether the application can modify the resource denoted by this
063     * abstract pathname.
064     *
065     * @return  <code>true</code> if and only if the resource system actually
066     *          contains a resource denoted by this abstract pathname <em>and</em>
067     *          the application is allowed to write to the resource;
068     *          <code>false</code> otherwise.
069     *
070     */
071        public abstract boolean isWriteable();
072
073    /**
074     * Tests whether the application can modify the resource denoted by this
075     * abstract pathname.
076     *
077     * @return  <code>true</code> if and only if the resource system actually
078     *          contains a resource denoted by this abstract pathname <em>and</em>
079     *          the application is allowed to write to the resource;
080     *          <code>false</code> otherwise.
081     * @deprecated use instead <code>#isWriteable()</code>
082     */
083        public abstract boolean canWrite();
084
085
086    /**
087     * Deletes the resource denoted by this abstract pathname.  If
088     * this pathname denotes a directory, then the directory must be empty, 
089     * when argument "force" is set to false, when argument "force" is set to true,
090     * also the children of the directory will be deleted.
091     * @param force 
092     *
093     * @throws  IOException
094     *          if the file doesn't exists or can't delete
095     */
096        public abstract void remove(boolean force) throws IOException;
097
098        /**
099     * Deletes the resource denoted by this abstract pathname.  If
100     * this pathname denotes a directory, then the directory must be empty, 
101     * when argument "force" is set to false, when argument "force" is set to true,
102     * also the children oif the directory will be deleted.
103     *
104     * @throws  IOException
105     *          if the file doesn't exists or can't delete
106     *@deprecated replaced with method remove(boolean)
107     */
108        public boolean delete();
109        
110        /**
111     * Tests whether the resource denoted by this abstract pathname
112     * exists.
113     *
114     * @return  <code>true</code> if and only if the resource denoted
115     *          by this abstract pathname exists; <code>false</code> otherwise
116     */
117        public abstract boolean exists();
118
119    /**
120     * Returns the absolute form of this abstract pathname.  
121     *
122     * @return  The absolute abstract pathname denoting the same resource  as this abstract pathname
123     */
124        public abstract Resource getAbsoluteResource();
125
126    /**
127     * Returns the absolute pathname string of this abstract pathname.
128     *
129     * <p> If this abstract pathname is already absolute, then the pathname
130     * string is simply returned as if by the <code>{@link #getPath}</code>
131     * method.  
132     *
133     * @return  The absolute pathname string denoting the same resource as this abstract pathname
134     *
135     */
136        public abstract String getAbsolutePath();
137
138    /**
139     * Returns the canonical form of this abstract pathname.  
140     *
141     * @return  The canonical pathname string denoting the same resource as this abstract pathname
142     *
143     * @throws  IOException
144     *          If an I/O error occurs, which is possible because the
145     *          construction of the canonical pathname may require
146     *          filesystem queries
147     *
148     */
149        public abstract Resource getCanonicalResource() throws IOException;
150
151        /**
152     * Returns the canonical pathname string of this abstract pathname.
153     *
154     * <p> A canonical pathname is both absolute and unique.  The precise
155     * definition of canonical form is system-dependent.  This method first
156     * converts this pathname to absolute form if necessary, as if by invoking the
157     * {@link #getAbsolutePath} method, and then maps it to its unique form in a
158     * system-dependent way.  This typically involves removing redundant names
159     * such as <tt>"."</tt> and <tt>".."</tt> from the pathname.
160     *
161     * <p> Every pathname that denotes an existing file or directory has a
162     * unique canonical form.  Every pathname that denotes a nonexistent resource 
163     * also has a unique canonical form.  The canonical form of
164     * the pathname of a nonexistent file or directory may be different from
165     * the canonical form of the same pathname after the resource is
166     * created.  Similarly, the canonical form of the pathname of an existing
167     * resource may be different from the canonical form of the same
168     * pathname after the resource is deleted.
169     *
170     * @return  The canonical pathname string denoting the same file or
171     *          directory as this abstract pathname
172     *
173     * @throws  IOException
174     *          If an I/O error occurs, which is possible because the
175     *          construction of the canonical pathname may require
176     *          filesystem queries
177     *
178     */
179    public abstract String getCanonicalPath() throws IOException;
180
181    /**
182     * Returns the name of the resource denoted by this abstract
183     * pathname.  This is just the last name in the pathname's name
184     * sequence.  If the pathname's name sequence is empty, then the empty
185     * string is returned.
186     *
187     * @return  The name of the resource denoted by this abstract
188     *          pathname, or the empty string if this pathname's name sequence
189     *          is empty
190     */
191        public abstract String getName();
192        
193    /**
194     * Returns the pathname string of this abstract pathname's parent, or
195     * <code>null</code> if this pathname does not name a parent directory.
196     *
197     * <p> The <em>parent</em> of an abstract pathname consists of the
198     * pathname's prefix, if any, and each name in the pathname's name
199     * sequence except for the last.  If the name sequence is empty then
200     * the pathname does not name a parent directory.
201     *
202     * @return  The pathname string of the parent directory named by this
203     *          abstract pathname, or <code>null</code> if this pathname
204     *          does not name a parent
205     */
206        public abstract String getParent();
207        
208    /**
209     * Returns the abstract pathname of this abstract pathname's parent,
210     * or <code>null</code> if this pathname does not name a parent
211     * directory.
212     *
213     * <p> The <em>parent</em> of an abstract pathname consists of the
214     * pathname's prefix, if any, and each name in the pathname's name
215     * sequence except for the last.  If the name sequence is empty then
216     * the pathname does not name a parent directory.
217     *
218     * @return  The abstract pathname of the parent directory named by this
219     *          abstract pathname, or <code>null</code> if this pathname
220     *          does not name a parent
221     *
222     */
223        public abstract Resource getParentResource();
224
225        /**
226         * returns a resource  path that is relative to the current resource
227         * @param relpath
228         * @return relative resource path to the current
229         */
230        public String getReal(String relpath);
231        
232        /**
233         * returns a resource that is relative to the current resource
234         * @param relpath
235         * @return relative resource to the current
236         */
237        public Resource getRealResource(String relpath);
238
239        /**
240     * Converts this abstract pathname into a pathname string.  
241     *
242     * @return  The string form of this abstract pathname
243     */
244        public abstract String getPath();
245
246        /**
247     * Tests whether this abstract pathname is absolute. 
248     *
249     * @return  <code>true</code> if this abstract pathname is absolute,
250     *          <code>false</code> otherwise
251     */
252    public abstract boolean isAbsolute();
253
254    /**
255     * Tests whether the resource denoted by this abstract pathname is a
256     * directory.
257     *
258     * @return <code>true</code> if and only if the file denoted by this
259     *          abstract pathname exists <em>and</em> is a directory;
260     *          <code>false</code> otherwise
261     */
262    public abstract boolean isDirectory();
263
264    /**
265     * Tests whether the file denoted by this abstract pathname is a normal
266     * file.  A file is <em>normal</em> if it is not a directory and, in
267     * addition, satisfies other system-dependent criteria.  Any non-directory
268     * file created by a Java application is guaranteed to be a normal file.
269     *
270     * @return  <code>true</code> if and only if the file denoted by this
271     *          abstract pathname exists <em>and</em> is a normal file;
272     *          <code>false</code> otherwise
273     */
274    public abstract boolean isFile();
275
276    /**
277     * Tests whether the resource named by this abstract pathname is a hidden
278     * resource. 
279     *
280     * @return  <code>true</code> if and only if the file denoted by this
281     *          abstract pathname is hidden
282     * @deprecated use instead <code>{@link #getAttribute(short)}</code>
283         */
284    public abstract boolean isHidden();
285    
286    /**
287     * Tests whether the resource named by this abstract pathname is a archive
288     * resource. 
289     *
290     * @return  <code>true</code> if and only if the file denoted by this
291     *          abstract pathname is a archive
292     * @deprecated use instead <code>{@link #getAttribute(short)}</code>
293         */
294    public abstract boolean isArchive();
295    
296    /**
297     * Tests whether the resource named by this abstract pathname is a system
298     * resource. 
299     *
300     * @return  <code>true</code> if and only if the file denoted by this
301     *          abstract pathname is a system resource
302     * @deprecated use instead <code>{@link #getAttribute(short)}</code>
303         */
304    public abstract boolean isSystem();
305
306    /**
307     * Returns the time that the resource denoted by this abstract pathname was
308     * last modified.
309     *
310     * @return  A <code>long</code> value representing the time the file was
311     *          last modified, measured in milliseconds since the epoch
312     *          (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
313     *          file does not exist or if an I/O error occurs
314     *
315     */
316    public abstract long lastModified();
317
318    /**
319     * Returns the length of the resource denoted by this abstract pathname.
320     * The return value is unspecified if this pathname denotes a directory.
321     *
322     * @return  The length, in bytes, of the resource denoted by this abstract
323     *          pathname, or <code>0L</code> if the resource does not exist
324     *
325     */
326    public abstract long length();
327
328    /**
329     * Returns an array of strings naming the files and directories in the
330     * directory denoted by this abstract pathname.
331     *
332     * <p> If this abstract pathname does not denote a directory, then this
333     * method returns <code>null</code>.  Otherwise an array of strings is
334     * returned, one for each file or directory in the directory.  Names
335     * denoting the directory itself and the directory's parent directory are
336     * not included in the result.  Each string is a file name rather than a
337     * complete path.
338     *
339     * <p> There is no guarantee that the name strings in the resulting array
340     * will appear in any specific order; they are not, in particular,
341     * guaranteed to appear in alphabetical order.
342     *
343     * @return  An array of strings naming the files and directories in the
344     *          directory denoted by this abstract pathname.  The array will be
345     *          empty if the directory is empty.  Returns <code>null</code> if
346     *          this abstract pathname does not denote a directory, or if an
347     *          I/O error occurs.
348     */
349    public abstract String[] list();
350
351    /**
352     * Returns an array of strings naming the files and directories in the
353     * directory denoted by this abstract pathname that satisfy the specified
354     * filter.  The behavior of this method is the same as that of the
355     * <code>{@link #list()}</code> method, except that the strings in the
356     * returned array must satisfy the filter.  If the given
357     * <code>filter</code> is <code>null</code> then all names are accepted.
358     * Otherwise, a name satisfies the filter if and only if the value
359     * <code>true</code> results when the <code>{@link
360     * ResourceNameFilter#accept}</code> method of the filter is invoked on this
361     * abstract pathname and the name of a file or directory in the directory
362     * that it denotes.
363     *
364     * @param  filter  A resourcename filter
365     *
366     * @return  An array of strings naming the files and directories in the
367     *          directory denoted by this abstract pathname that were accepted
368     *          by the given <code>filter</code>.  The array will be empty if
369     *          the directory is empty or if no names were accepted by the
370     *          filter.  Returns <code>null</code> if this abstract pathname
371     *          does not denote a directory, or if an I/O error occurs.
372     *
373     */
374    public abstract String[] list(ResourceNameFilter filter);
375        
376        public abstract String[] list(ResourceFilter filter);
377
378        /**
379     * Returns an array of abstract pathnames denoting the files in the
380     * directory denoted by this abstract pathname.
381     *
382     * <p> If this abstract pathname does not denote a directory, then this
383     * method returns <code>null</code>.  Otherwise an array of
384     * <code>File</code> objects is returned, one for each file or directory in
385     * the directory.   Therefore if this pathname
386     * is absolute then each resulting pathname is absolute; if this pathname
387     * is relative then each resulting pathname will be relative to the same
388     * directory.
389     *
390     * <p> There is no guarantee that the name strings in the resulting array
391     * will appear in any specific order; they are not, in particular,
392     * guaranteed to appear in alphabetical order.
393     *
394     * @return  An array of abstract pathnames denoting the files and
395     *          directories in the directory denoted by this abstract
396     *          pathname.  The array will be empty if the directory is
397     *          empty.  Returns <code>null</code> if this abstract pathname
398     *          does not denote a directory, or if an I/O error occurs.
399     */
400    public abstract Resource[] listResources();
401
402    /**
403     * Returns an array of abstract pathnames denoting the files and
404     * directories in the directory denoted by this abstract pathname that
405     * satisfy the specified filter.  The behavior of this method is the
406     * same as that of the <code>{@link #listResources()}</code> method, except
407     * that the pathnames in the returned array must satisfy the filter.
408     * If the given <code>filter</code> is <code>null</code> then all
409     * pathnames are accepted.  Otherwise, a pathname satisfies the filter
410     * if and only if the value <code>true</code> results when the
411     * <code>{@link ResourceFilter#accept(Resource)}</code> method of
412     * the filter is invoked on the pathname.
413     *
414     * @param  filter  A resource filter
415     *
416     * @return  An array of abstract pathnames denoting the files and
417     *          directories in the directory denoted by this abstract
418     *          pathname.  The array will be empty if the directory is
419     *          empty.  Returns <code>null</code> if this abstract pathname
420     *          does not denote a directory, or if an I/O error occurs.
421     *          
422     */
423    
424    public abstract Resource[] listResources(ResourceFilter filter);
425
426        /**
427     * Returns an array of abstract pathnames denoting the files and
428     * directories in the directory denoted by this abstract pathname that
429     * satisfy the specified filter.  The behavior of this method is the
430     * same as that of the <code>{@link #listResources()}</code> method, except
431     * that the pathnames in the returned array must satisfy the filter.
432     * If the given <code>filter</code> is <code>null</code> then all
433     * pathnames are accepted.  Otherwise, a pathname satisfies the filter
434     * if and only if the value <code>true</code> results when the
435     * <code>{@link ResourceNameFilter#accept}</code> method of the filter is
436     * invoked on this abstract pathname and the name of a file or
437     * directory in the directory that it denotes.
438     *
439     * @param  filter  A resourcename filter
440     *
441     * @return  An array of abstract pathnames denoting the files and
442     *          directories in the directory denoted by this abstract
443     *          pathname.  The array will be empty if the directory is
444     *          empty.  Returns <code>null</code> if this abstract pathname
445     *          does not denote a directory, or if an I/O error occurs.
446     *          
447     */
448    public abstract Resource[] listResources(ResourceNameFilter filter);
449
450    
451    /**
452     * Move/renames the file denoted by this abstract pathname.
453     * 
454     * <p> Many aspects of the behavior of this method are inherently
455     * platform-dependent: The rename operation might not be able to move a
456     * file from one filesystem to another, it might not be atomic, and it
457     * might not succeed if a file with the destination abstract pathname
458     * already exists. 
459     *
460     * @param  dest  The new abstract pathname for the named file
461     * @return has successfull renamed or not
462     * 
463     * @deprecated use instead <code>#moveTo(Resource)</code>
464     */ 
465    public boolean renameTo(Resource dest);
466    
467    
468    /**
469     * Move/renames the file denoted by this abstract pathname.
470     * 
471     * <p> Many aspects of the behavior of this method are inherently
472     * platform-dependent: The rename operation might not be able to move a
473     * file from one filesystem to another, it might not be atomic, and it
474     * might not succeed if a file with the destination abstract pathname
475     * already exists. 
476     *
477     * @param  dest  The new abstract pathname for the named file
478     * @throws IOException throwed when operation not done sucessfull
479     * 
480     *
481     */
482    public abstract void moveTo(Resource dest) throws IOException;
483        
484
485    /**
486     * Sets the last-modified time of the file or directory named by this
487     * abstract pathname.
488     *
489     * <p> All platforms support file-modification times to the nearest second,
490     * but some provide more precision.  The argument will be truncated to fit
491     * the supported precision.  If the operation succeeds and no intervening
492     * operations on the file take place, then the next invocation of the
493     * <code>{@link #lastModified}</code> method will return the (possibly
494     * truncated) <code>time</code> argument that was passed to this method.
495     *
496     * @param  time  The new last-modified time, measured in milliseconds since
497     *               the epoch (00:00:00 GMT, January 1, 1970)
498     *
499     * @return <code>true</code> if and only if the operation succeeded;
500     *          <code>false</code> otherwise
501     *
502     *
503     */
504    public abstract boolean setLastModified(long time);
505
506    /**
507     * Marks the file or directory named by this abstract pathname so that
508     * only read operations are allowed.  After invoking this method the file
509     * or directory is guaranteed not to change until it is either deleted or
510     * marked to allow write access.  Whether or not a read-only file or
511     * directory may be deleted depends upon the underlying system.
512     *
513     * @return <code>true</code> if and only if the operation succeeded;
514     *          <code>false</code> otherwise
515     * @deprecated use instead <code>{@link #setWritable(boolean)}</code>
516     *
517     */
518    public boolean setReadOnly();
519    
520    //public void setWritable(boolean value) throws IOException;
521    public boolean setWritable(boolean writable);
522    
523    //public void setReadable(boolean value) throws IOException;
524    public boolean setReadable(boolean readable);
525    
526        /**
527     * Creates a new, empty file named by this abstract pathname if
528     * and only if a file with this name does not yet exist.  The check for the
529     * existence of the file and the creation of the file if it does not exist
530     * are a single operation that is atomic with respect to all other
531     * filesystem activities that might affect the file.
532     *
533     * @return  <code>true</code> if the named file does not exist and was
534     *          successfully created; <code>false</code> if the named file
535     *          already exists
536     *
537     * @throws  IOException
538     *          If an I/O error occurred
539     * @deprecated use instead <code>#createFile(boolean)</code>
540     */
541    public boolean createNewFile();
542        
543    /**
544     * Creates a new, empty file named by this abstract pathname if
545     * and only if a file with this name does not yet exist.  The check for the
546     * existence of the file and the creation of the file if it does not exist
547     * are a single operation that is atomic with respect to all other
548     * filesystem activities that might affect the file.
549     * @param createParentWhenNotExists 
550     *
551     *
552     * @throws  IOException
553     *          If an I/O error occurred
554     */
555    public void createFile(boolean createParentWhenNotExists) throws IOException;
556
557        
558        
559        /**
560     * Creates the directory named by this abstract pathname.
561     *
562     * @return  <code>true</code> if and only if the directory was
563     *          created; <code>false</code> otherwise
564     * @deprecated use <code>#createDirectory(boolean)</code>
565     */
566    public boolean mkdir();
567
568    /**
569     * Creates the directory named by this abstract pathname, including any
570     * necessary but nonexistent parent directories.  Note that if this
571     * operation fails it may have succeeded in creating some of the necessary
572     * parent directories.
573     *
574     * @return  <code>true</code> if and only if the directory was created,
575     *          along with all necessary parent directories; <code>false</code>
576     *          otherwise
577     * @deprecated use <code>#createDirectory(boolean)</code>
578     */
579    public boolean mkdirs();
580        
581        
582    /**
583     * Creates the directory named by this abstract pathname, including any
584     * necessary but nonexistent parent directories if flag "createParentWhenNotExists" is set to true.  
585     * Note that if this operation fails it may have succeeded in creating some of the necessary
586     * parent directories.
587     * @param createParentWhenNotExists throws Exception when can't create directory
588     * @throws IOException 
589     *
590     */
591    public void createDirectory(boolean createParentWhenNotExists) throws IOException;
592
593        public InputStream getInputStream() throws IOException;
594
595        public OutputStream getOutputStream() throws IOException;
596        
597        /**
598         * copy current resource data to given resource
599         * @param res
600         * @throws IOException
601         */
602        public void copyTo(Resource res,boolean append) throws IOException;
603        
604        /**
605         * copy data of given resource to current
606         * @param res
607         * @throws IOException
608         */
609        public void copyFrom(Resource res,boolean append) throws IOException;
610
611        public OutputStream getOutputStream(boolean append) throws IOException;
612
613        public abstract ResourceProvider getResourceProvider();
614        
615        public int getMode();
616        
617        public void setMode(int mode) throws IOException;
618
619        /**
620         * sets hidden attribute of the resource
621         * @param value 
622         * @throws IOException throwed when no access to change the value or the resource doesn't exists
623         * @deprecated use instead <code>{@link #setAttribute(short, boolean)}</code>
624         */
625        public void setHidden(boolean value) throws IOException;
626        
627        /**
628         * sets system attribute of the resource
629         * @param value 
630         * @throws IOException throwed when no access to change the value or the resource doesn't exists
631         * @deprecated use instead <code>{@link #setAttribute(short, boolean)}</code>
632         */
633        public void setSystem(boolean value) throws IOException;        
634        
635        /**
636         * sets archive attribute of the resource
637         * @param value 
638         * @throws IOException throwed when no access to change the value or the resource doesn't exists
639         * @deprecated use instead <code>{@link #setAttribute(short, boolean)}</code>
640         */
641        public void setArchive(boolean value) throws IOException;
642        
643        
644
645    /** 
646     * sets a attribute on the resource if supported otherwise it will ign 
647     * @param attribute wich attrbute (Resource.ATTRIBUTE_*) 
648     * @param value 
649     * @throws IOException throwed when no access to change the value, 
650     * when attributes are not supported  or 
651     * the resource doesn't exists 
652     */ 
653    public void setAttribute(short attribute, boolean value) throws IOException; 
654    
655    /** 
656     * return value of a specific attribute 
657     * @param attribute 
658     * @return value of the attribute 
659     * @throws IOException throwed when attributes are not supported  or 
660     * the resource doesn't exists 
661     */ 
662    public boolean getAttribute(short attribute); 
663}