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.retirement;
020
021import java.io.IOException;
022import java.io.OutputStream;
023
024import lucee.commons.io.res.Resource;
025
026public class RetireOutputStream extends OutputStream {
027        
028        private Resource res;
029        private boolean append;
030        private OutputStream os;
031        private long lastAccess=0;
032        private long retireRange;
033        private RetireListener listener;
034
035        /**
036         * 
037         * @param res
038         * @param append
039         * @param retireRange retire the stream after given time in minutes
040         */
041        public RetireOutputStream(Resource res, boolean append, int retireRangeInSeconds, RetireListener listener){
042                this.res=res;
043                this.append=append;
044                retireRange = retireRangeInSeconds>0?retireRangeInSeconds*1000:0;
045                this.listener=listener;
046        }
047
048        private OutputStream getOutputStream() throws IOException {
049                
050                if(os==null) {
051                        //print.e("start "+res);
052                        os=res.getOutputStream(append);
053                        RetireOutputStreamFactory.list.add(this);
054                        RetireOutputStreamFactory.startThread(retireRange);
055                }
056                lastAccess=System.currentTimeMillis();
057                return os;
058        }
059        
060        public boolean retire() throws IOException{
061                if(os==null || (lastAccess+retireRange)>System.currentTimeMillis()) {
062                        //print.e("not retire "+res);
063                        return false;
064                }
065                //print.e("retire "+res);
066                append=true;
067                close();
068                
069                return true;
070        }
071        private boolean retireNow() throws IOException{
072                if(os==null)return false;
073                append=true;
074                close();
075                return true;
076        }
077
078        @Override
079        public void close() throws IOException {
080                if(os!=null){
081                        if(listener!=null) listener.retire(this);
082                        try{
083                                os.close();
084                        }
085                        finally{
086                                RetireOutputStreamFactory.list.remove(this);
087                                os=null;
088                        }
089                }
090        }
091
092        @Override
093        public void flush() throws IOException {
094                if(os!=null){
095                        getOutputStream().flush();
096                        if(retireRange==0) retireNow();
097                }
098        }
099        
100        @Override
101        public void write(int b) throws IOException {
102                //print.e("write:"+((char)b));
103                getOutputStream().write(b);
104                if(retireRange==0) retireNow();
105        }
106
107        @Override
108        public void write(byte[] b) throws IOException {
109                //print.e("write.barr:"+b.length);
110                getOutputStream().write(b);
111                if(retireRange==0) retireNow();
112        }
113
114        @Override
115        public void write(byte[] b, int off, int len) throws IOException {
116                //print.e("write.barr:"+b.length+":"+off+":"+len);
117                getOutputStream().write(b, off, len);
118                if(retireRange==0) retireNow();
119        }
120
121}