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.type.compress;
020
021import java.io.IOException;
022import java.util.Map;
023
024import lucee.commons.io.res.Resource;
025import lucee.commons.io.res.ResourceProvider;
026import lucee.commons.io.res.ResourceProviderPro;
027import lucee.commons.io.res.Resources;
028import lucee.commons.io.res.util.ResourceLockImpl;
029import lucee.commons.io.res.util.ResourceUtil;
030import lucee.commons.lang.SizeOf;
031import lucee.commons.lang.StringUtil;
032import lucee.runtime.PageContext;
033import lucee.runtime.engine.ThreadLocalPageContext;
034import lucee.runtime.op.Caster;
035import lucee.runtime.type.Sizeable;
036
037public abstract class CompressResourceProvider implements ResourceProviderPro,Sizeable {
038        
039        private static final long serialVersionUID = 5930090603192203086L;
040        
041        private Resources resources;
042        protected String scheme=null;
043        protected boolean caseSensitive=true;
044        boolean async=true; 
045        private long lockTimeout=10000;
046        private final ResourceLockImpl lock=new ResourceLockImpl(lockTimeout,caseSensitive);
047        private Map arguments;
048
049        @Override
050        public ResourceProvider init(String scheme, Map arguments) {
051                if(!StringUtil.isEmpty(scheme))this.scheme=scheme;
052                if(arguments!=null) {
053                        this.arguments=arguments;
054                        // case-sensitive
055                        String strCaseSensitive=(String) arguments.get("case-sensitive");
056                        if(strCaseSensitive!=null) {
057                                caseSensitive=Caster.toBooleanValue(strCaseSensitive,true);
058                        }
059                        
060                        // sync
061                        String strASync=(String) arguments.get("asynchronus");
062                        if(strASync==null)strASync=(String) arguments.get("async");
063                        if(strASync!=null) {
064                                async=Caster.toBooleanValue(strASync,true);
065                        }
066                        
067                        // lock-timeout
068                        String strTimeout = (String) arguments.get("lock-timeout");
069                        if(strTimeout!=null) {
070                                lockTimeout=Caster.toLongValue(arguments.get("lock-timeout"),lockTimeout);
071                        }
072                }
073                lock.setLockTimeout(lockTimeout);
074                lock.setCaseSensitive(caseSensitive);
075                
076                return this;
077        }
078        
079        public ResourceProvider init(String scheme, boolean caseSensitive, boolean async) {
080                if(!StringUtil.isEmpty(scheme))this.scheme=scheme;
081                this.caseSensitive=caseSensitive;
082                this.async=async;
083                return this;
084        }
085
086        @Override
087        public Resource getResource(String path) { 
088                path=ResourceUtil.removeScheme(scheme,path);
089                int index=path.lastIndexOf('!');
090                if(index!=-1) {
091                        
092                        Resource file = toResource(path.substring(0,index));//resources.getResource(path.substring(0,index));
093                        return new CompressResource(this,getCompress(file),path.substring(index+1),caseSensitive);
094                }
095                Resource file = toResource(path);//resources.getResource(path);
096                return new CompressResource(this,getCompress(file),"/",caseSensitive);
097        }
098        
099        private Resource toResource(String path) {
100                PageContext pc = ThreadLocalPageContext.get();
101                if(pc!=null) {
102                        return ResourceUtil.toResourceNotExisting(ThreadLocalPageContext.get(), path,true,false);
103                }
104                return resources.getResource(path);
105        }
106
107        public abstract Compress getCompress(Resource file);
108
109        @Override
110        public String getScheme() {
111                return scheme;
112        }
113
114
115
116        public void setResources(Resources resources) {
117                this.resources=resources;
118        }
119
120        @Override
121        public void lock(Resource res) throws IOException {
122                lock.lock(res);
123        }
124
125        @Override
126        public void unlock(Resource res) {
127                lock.unlock(res);
128        }
129
130        @Override
131        public void read(Resource res) throws IOException {
132                lock.read(res);
133        }
134
135        @Override
136        public Map getArguments() {
137                return arguments;
138        }
139        
140        /*public static void main(String[] args) throws IOException {
141                Resources rs=ResourcesImpl.getGlobal();
142                rs.registerResourceProvider(new ZipResourceProvider().init("zip", null));
143                rs.registerResourceProvider(new RamResourceProvider().init("ram", null));
144                
145                
146                Resource ra = rs.getResource("zip:///Users/mic/temp/test/ras111.zip!/dd/");
147                print.ln(ra);
148                print.ln(ra.getParent());
149                
150                ra = rs.getResource("ram:///dd/");
151                print.ln(ra);
152                print.ln(ra.getParent());
153                
154                
155                Resource org = rs.getResource("/Users/mic/temp/test/org.zip"); 
156                Resource trg = rs.getResource("/Users/mic/temp/test/trg.zip"); 
157                Resource ras = rs.getResource("/Users/mic/temp/test/ras.zip"); 
158                
159                ResourceUtil.copy(org, ras);
160                
161                
162                
163                Resource res1 = rs.getResource("zip:///Users/mic/temp/test/rasx.zip!/dd"); 
164                Resource res2 = rs.getResource("zip:///Users/mic/temp/test/ras.zip!/ddd"+Math.random()+".txt"); 
165
166                res1.mkdirs();
167                res2.createNewFile();
168                ResourceUtil.copy(ras, trg);
169                print.ln("copy");
170                
171                //Resource org2 = rs.getResource("/Users/mic/temp/test/org.zip"); 
172                Resource luceetmp = rs.getResource("/Users/mic/temp/luceetmp/");
173                Resource trg2 = rs.getResource("zip:///Users/mic/temp/luceetmp.zip!");
174                trg2.delete();
175                long start=System.currentTimeMillis();
176                ResourceUtil.copyRecursive(luceetmp, trg2);
177                
178                print.ln("ende "+(System.currentTimeMillis()-start));
179                
180                //print(res3);
181                
182                
183        }
184
185        private static void print(Resource r) {
186                
187                print.ln("****************************************");
188                print.ln(r);
189                if(r==null) return;
190                print.ln("path:"+r.getPath());
191                print.ln("name:"+r.getName());
192                print.ln("parent:"+r.getParent());
193                print.ln("parent-res:"+r.getParentResource());
194                print.ln("exists:"+r.exists());
195                print.ln("isDirectory:"+r.isDirectory());
196                print.ln("isFile:"+r.isFile());
197                print.ln("lastModified:"+r.lastModified());
198                if(r.isFile()) {
199                        //print.ln("->"+IOUtil.toString(r.getI nputStream(),null)+"<-");
200                }
201                if(r.isDirectory()) {
202                        print.ln(" - children");
203                        String[] children = r.list();
204                        Resource[] ch2 = r.listResources();
205                        for(int i=0;i<children.length;i++) {
206                                print.ln("   - "+children[i]);
207                                print.ln("   - "+ch2[i]);
208                        }
209                }
210        }*/
211
212        
213        @Override
214        public long sizeOf() {
215                return SizeOf.size(lock);
216        }
217        
218        @Override
219        public char getSeparator() {
220                return '/';
221        }
222}