001    package railo.commons.io.res.type.compress;
002    
003    import java.io.IOException;
004    import java.io.InputStream;
005    import java.io.OutputStream;
006    
007    import railo.commons.io.res.Resource;
008    import railo.commons.io.res.ResourceProvider;
009    import railo.commons.io.res.util.ResourceSupport;
010    import railo.commons.io.res.util.ResourceUtil;
011    import railo.commons.lang.StringUtil;
012    
013    public final class CompressResource extends ResourceSupport {
014    
015            private final CompressResourceProvider provider;
016            private final Compress zip;
017            private final String path;
018            private final String name;
019            private final String parent;
020            private final boolean caseSensitive; 
021    
022            /**
023             * Constructor of the class
024             * @param provider
025             * @param zip
026             * @param path
027             * @param caseSensitive
028             */
029            CompressResource(CompressResourceProvider provider, Compress zip, String path, boolean caseSensitive) {
030                    if(StringUtil.isEmpty(path)) path="/";
031                    this.provider=provider;
032                    this.zip=zip; 
033                    this.path=path;
034                    String[] tmp = ResourceUtil.translatePathName(path);
035                    this.name=tmp[1];
036                    this.parent=tmp[0];
037                    this.caseSensitive=caseSensitive;
038            }
039    
040            /**
041             * @return return ram resource that contain the data
042             */
043            private Resource getRamResource() {
044                    return zip.getRamProviderResource(path);
045            }
046    
047            /**
048             * @see railo.commons.io.res.Resource#exists()
049             */
050            public boolean exists() {
051                    try {
052                            provider.read(this);
053                    } 
054                    catch (IOException e) {
055                            return false;
056                    }
057                    return getRamResource().exists();
058            }
059    
060            /**
061             * @see railo.commons.io.res.Resource#getInputStream()
062             */
063            public InputStream getInputStream() throws IOException {
064                    ResourceUtil.checkGetInputStreamOK(this);
065                    return getRamResource().getInputStream();
066            }
067    
068            /**
069             * @see railo.commons.io.res.Resource#getName()
070             */
071            public String getName() {
072                    return name;
073            }
074    
075            /**
076             * @see railo.commons.io.res.Resource#getParent()
077             */
078            public String getParent() {
079                    if(StringUtil.isEmpty(parent))return null;
080                    return provider.getScheme().concat("://").concat(zip.getCompressFile().getPath()).concat("!").concat(parent);
081            }
082    
083            /**
084             * @see railo.commons.io.res.Resource#getParentResource()
085             */
086            public Resource getParentResource() {
087                    if(StringUtil.isEmpty(parent))return null;
088                    return new CompressResource(provider,zip,parent,caseSensitive);
089            }
090    
091            /**
092             * @see railo.commons.io.res.Resource#getPath()
093             */
094            public String getPath() {
095                    return provider.getScheme().concat("://").concat(zip.getCompressFile().getPath()).concat("!").concat(path);
096            }
097    
098            /**
099             * @see railo.commons.io.res.Resource#getRealResource(java.lang.String)
100             */
101            public Resource getRealResource(String realpath) {
102                    realpath=ResourceUtil.merge(path, realpath);
103                    if(realpath.startsWith("../"))return null;
104                    return new CompressResource(provider,zip,realpath,caseSensitive);
105            }
106    
107            /**
108             * @see railo.commons.io.res.Resource#getResourceProvider()
109             */
110            public ResourceProvider getResourceProvider() {
111                    return provider;
112            }
113    
114            /**
115             * @see railo.commons.io.res.Resource#isAbsolute()
116             */
117            public boolean isAbsolute() {
118                    return getRamResource().isAbsolute();
119            }
120    
121            /**
122             * @see railo.commons.io.res.Resource#isDirectory()
123             */
124            public boolean isDirectory() {
125                    return getRamResource().isDirectory();
126            }
127    
128            /**
129             * @see railo.commons.io.res.Resource#isFile()
130             */
131            public boolean isFile() {
132                    return getRamResource().isFile();
133            }
134    
135            /**
136             * @see railo.commons.io.res.Resource#isReadable()
137             */
138            public boolean isReadable() {
139                    return getRamResource().isReadable();
140            }
141    
142            /**
143             * @see railo.commons.io.res.Resource#isWriteable()
144             */
145            public boolean isWriteable() {
146                    return getRamResource().isWriteable();
147            }
148    
149            /**
150             * @see railo.commons.io.res.Resource#lastModified()
151             */
152            public long lastModified() {
153                    return getRamResource().lastModified();
154            }
155    
156            /**
157             * @see railo.commons.io.res.Resource#length()
158             */
159            public long length() {
160                    return getRamResource().length();
161            }
162    
163            /**
164             *
165             * @see railo.commons.io.res.Resource#listResources()
166             */
167            public Resource[] listResources() {
168                    String[] names = list();
169                    if(names==null) return null;
170                    Resource[] children = new Resource[names.length];
171                    for(int i=0;i<children.length;i++) {
172                            children[i]=new CompressResource(provider,zip,path.concat("/").concat(names[i]),caseSensitive);
173                    }
174                    return children;
175            }
176            
177            /**
178             * @see railo.commons.io.res.util.ResourceSupport#list()
179             */
180            public String[] list() {
181                    return getRamResource().list();
182            }
183    
184            /**
185             * @see railo.commons.io.res.Resource#remove(boolean)
186             */
187            public void remove(boolean force) throws IOException {
188                    Resource rr = getRamResource();
189                    if(rr.getParent()==null) 
190                            throw new IOException("can't remove root resource ["+getPath()+"]");
191                    
192                    if(!rr.exists())
193                            throw new IOException("can't remove resource ["+getPath()+"],resource does not exists");
194                    
195                    Resource[] children = listResources();
196                    if(children!=null && children.length>0) {
197                            if(!force) {
198                                    throw new IOException("can't delete directory ["+getPath()+"], directory is not empty");
199                            }
200                            for(int i=0;i<children.length;i++) {
201                                    children[i].remove(true);
202                            }
203                    }
204                    rr.remove(force);
205            }
206    
207            /**
208             * @see railo.commons.io.res.Resource#setLastModified(long)
209             */
210            public boolean setLastModified(long time) {
211                    boolean lm = getRamResource().setLastModified(time);
212                    zip.synchronize(provider.async);
213                    return lm;
214            }
215            
216            /**
217             * @see railo.commons.io.res.Resource#createDirectory(boolean)
218             */
219            public void createDirectory(boolean createParentWhenNotExists) throws IOException {
220                    ResourceUtil.checkCreateDirectoryOK(this,createParentWhenNotExists);
221                    getRamResource().createDirectory(createParentWhenNotExists);
222                    zip.synchronize(provider.async);
223            }
224    
225            /**
226             * @see railo.commons.io.res.Resource#createFile(boolean)
227             */
228            public void createFile(boolean createParentWhenNotExists) throws IOException {
229                    ResourceUtil.checkCreateFileOK(this,createParentWhenNotExists);
230                    getRamResource().createFile(createParentWhenNotExists);
231                    zip.synchronize(provider.async);
232            }
233    
234            /**
235             * @see railo.commons.io.res.Resource#getOutputStream()
236             */
237            public OutputStream getOutputStream() throws IOException {
238                    ResourceUtil.checkGetOutputStreamOK(this);
239                    //Resource res = getRamResource();
240                    //Resource p = res.getParentResource();
241                    //if(p!=null && !p.exists())p.mkdirs();
242                    return new CompressOutputStreamSynchronizer(getRamResource().getOutputStream(),zip,provider.async);
243            }
244    
245            /**
246             * @see railo.commons.io.res.Resource#getOutputStream(boolean)
247             */
248            public OutputStream getOutputStream(boolean append) throws IOException {
249                    return new CompressOutputStreamSynchronizer(getRamResource().getOutputStream(append),zip,provider.async);
250            }
251    
252            /**
253             *
254             * @see railo.commons.io.res.Resource#getMode()
255             */
256            public int getMode() {
257                    return getRamResource().getMode();
258            }
259    
260            /**
261             *
262             * @see railo.commons.io.res.Resource#setMode(int)
263             */
264            public void setMode(int mode) throws IOException {
265                    getRamResource().setMode(mode);
266                    zip.synchronize(provider.async);
267                    
268            }
269    
270            /**
271             *
272             * @see railo.commons.io.res.Resource#setReadable(boolean)
273             */
274            public boolean setReadable(boolean value) {
275                    if(!isFile())return false;
276                    getRamResource().setReadable(value);
277                    zip.synchronize(provider.async);
278                    return true;
279            }
280    
281            /**
282             *
283             * @see railo.commons.io.res.Resource#setWritable(boolean)
284             */
285            public boolean setWritable(boolean value) {
286                    if(!isFile())return false;
287                    getRamResource().setWritable(value);
288                    zip.synchronize(provider.async);
289                    return true;
290            }
291    
292    }