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                    
035                    if("/".equals(path)) {
036                            this.parent=null;
037                            this.name="";
038                    }
039                    else {
040                            String[] pn = ResourceUtil.translatePathName(path);
041                            this.parent=pn[0];
042                            this.name=pn[1];
043                    }
044                    
045                    this.caseSensitive=caseSensitive;
046            }
047    
048            /**
049             * @return return ram resource that contain the data
050             */
051            private Resource getRamResource() {
052                    return zip.getRamProviderResource(path);
053            }
054    
055            @Override
056            public boolean exists() {
057                    try {
058                            provider.read(this);
059                    } 
060                    catch (IOException e) {
061                            return false;
062                    }
063                    return getRamResource().exists();
064            }
065    
066            @Override
067            public InputStream getInputStream() throws IOException {
068                    ResourceUtil.checkGetInputStreamOK(this);
069                    return getRamResource().getInputStream();
070            }
071            
072            public Resource getCompressResource() {
073                    return zip.getCompressFile();
074            }
075            
076            public String getCompressPath() {
077                    return path;
078            }
079    
080            @Override
081            public String getName() {
082                    return name;
083            }
084    
085            @Override
086            public String getParent() {
087                    if(StringUtil.isEmpty(parent))return null;
088                    return provider.getScheme().concat("://").concat(zip.getCompressFile().getPath()).concat("!").concat(parent);
089            }
090    
091            @Override
092            public Resource getParentResource() {
093                    if(StringUtil.isEmpty(parent))return null;
094                    return new CompressResource(provider,zip,parent,caseSensitive);
095            }
096    
097            @Override
098            public String getPath() {
099                    return provider.getScheme().concat("://").concat(zip.getCompressFile().getPath()).concat("!").concat(path);
100            }
101    
102            @Override
103            public Resource getRealResource(String realpath) {
104                    realpath=ResourceUtil.merge(path, realpath);
105                    if(realpath.startsWith("../"))return null;
106                    return new CompressResource(provider,zip,realpath,caseSensitive);
107            }
108    
109            @Override
110            public ResourceProvider getResourceProvider() {
111                    return provider;
112            }
113    
114            @Override
115            public boolean isAbsolute() {
116                    return getRamResource().isAbsolute();
117            }
118    
119            @Override
120            public boolean isDirectory() {
121                    return getRamResource().isDirectory();
122            }
123    
124            @Override
125            public boolean isFile() {
126                    return getRamResource().isFile();
127            }
128    
129            @Override
130            public boolean isReadable() {
131                    return getRamResource().isReadable();
132            }
133    
134            @Override
135            public boolean isWriteable() {
136                    return getRamResource().isWriteable();
137            }
138    
139            @Override
140            public long lastModified() {
141                    return getRamResource().lastModified();
142            }
143    
144            @Override
145            public long length() {
146                    return getRamResource().length();
147            }
148    
149            @Override
150            public Resource[] listResources() {
151                    String[] names = list();
152                    if(names==null) return null;
153                    Resource[] children = new Resource[names.length];
154                    for(int i=0;i<children.length;i++) {
155                            children[i]=new CompressResource(provider,zip,path.concat("/").concat(names[i]),caseSensitive);
156                    }
157                    return children;
158            }
159            
160            @Override
161            public String[] list() {
162                    return getRamResource().list();
163            }
164    
165            @Override
166            public void remove(boolean force) throws IOException {
167                    Resource rr = getRamResource();
168                    if(rr.getParent()==null) 
169                            throw new IOException("can't remove root resource ["+getPath()+"]");
170                    
171                    if(!rr.exists())
172                            throw new IOException("can't remove resource ["+getPath()+"],resource does not exist");
173                    
174                    Resource[] children = listResources();
175                    if(children!=null && children.length>0) {
176                            if(!force) {
177                                    throw new IOException("can't delete directory ["+getPath()+"], directory is not empty");
178                            }
179                            for(int i=0;i<children.length;i++) {
180                                    children[i].remove(true);
181                            }
182                    }
183                    rr.remove(force);
184            }
185    
186            @Override
187            public boolean setLastModified(long time) {
188                    boolean lm = getRamResource().setLastModified(time);
189                    zip.synchronize(provider.async);
190                    return lm;
191            }
192            
193            @Override
194            public void createDirectory(boolean createParentWhenNotExists) throws IOException {
195                    ResourceUtil.checkCreateDirectoryOK(this,createParentWhenNotExists);
196                    getRamResource().createDirectory(createParentWhenNotExists);
197                    zip.synchronize(provider.async);
198            }
199    
200            @Override
201            public void createFile(boolean createParentWhenNotExists) throws IOException {
202                    ResourceUtil.checkCreateFileOK(this,createParentWhenNotExists);
203                    getRamResource().createFile(createParentWhenNotExists);
204                    zip.synchronize(provider.async);
205            }
206    
207            @Override
208            public OutputStream getOutputStream() throws IOException {
209                    ResourceUtil.checkGetOutputStreamOK(this);
210                    //Resource res = getRamResource();
211                    //Resource p = res.getParentResource();
212                    //if(p!=null && !p.exists())p.mkdirs();
213                    return new CompressOutputStreamSynchronizer(getRamResource().getOutputStream(),zip,provider.async);
214            }
215    
216            @Override
217            public OutputStream getOutputStream(boolean append) throws IOException {
218                    return new CompressOutputStreamSynchronizer(getRamResource().getOutputStream(append),zip,provider.async);
219            }
220    
221            @Override
222            public int getMode() {
223                    return getRamResource().getMode();
224            }
225    
226            @Override
227            public void setMode(int mode) throws IOException {
228                    getRamResource().setMode(mode);
229                    zip.synchronize(provider.async);
230                    
231            }
232    
233            @Override
234            public boolean setReadable(boolean value) {
235                    if(!isFile())return false;
236                    getRamResource().setReadable(value);
237                    zip.synchronize(provider.async);
238                    return true;
239            }
240    
241            @Override
242            public boolean setWritable(boolean value) {
243                    if(!isFile())return false;
244                    getRamResource().setWritable(value);
245                    zip.synchronize(provider.async);
246                    return true;
247            }
248    
249    }