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.runtime.converter;
020
021import java.util.Date;
022import java.util.Iterator;
023import java.util.Set;
024
025import lucee.aprint;
026import lucee.commons.lang.ParserString;
027import lucee.commons.lang.StringUtil;
028import lucee.runtime.op.Caster;
029import lucee.runtime.type.Struct;
030import lucee.runtime.type.StructImpl;
031import lucee.runtime.type.dt.DateTime;
032
033public class ClientScopeConverter {
034
035        public static Struct unserialize(String str) {
036                Struct sct=new StructImpl();
037                ParserString ps=new ParserString(str);
038                
039                StringBuilder sb=new StringBuilder();
040                String key=null;
041                while(!ps.isAfterLast()) {
042                        if(ps.isCurrent('#')) {
043                                if(ps.isNext('=')){
044                                        ps.next();
045                                        sb.append('=');
046                                }
047                                else if(ps.isNext('#')){
048                                        ps.next();
049                                        sb.append('#');
050                                }
051                                else {
052                                        sct.setEL(key, sb.toString());
053                                        sb=new StringBuilder();
054                                }
055                        }
056                        else if(ps.isCurrent('=')) {
057                                key=sb.toString();
058                                sb=new StringBuilder();
059                        }
060                        else sb.append(ps.getCurrent());
061                        ps.next();
062                }
063                
064                
065                if(!StringUtil.isEmpty(key) && !StringUtil.isEmpty(sb)) {
066                        sct.setEL(key, sb.toString());
067                }
068                return sct;
069                
070                /*
071                int index=0,last=0;
072                while((index=str.indexOf('#',last))!=-1) {
073                        outer:while(str.length()+1>index) {
074                                c=str.charAt(index+1);
075                                if(c=='#' || c=='=') {
076                                        last=index+1;
077                                        continue;
078                                }
079                        }
080                        _unserialize(str.substring(last,index));
081                        last=index+1;
082                }
083                _unserialize(str.substring(last));
084                */
085                
086        }
087
088
089
090        public static String serialize(Struct sct) throws ConverterException {
091                // TODO Auto-generated method stub
092                return serialize(sct,null);
093        }
094        
095        public static String serialize(Struct sct, Set ignoreSet) throws ConverterException {
096                StringBuilder sb=new StringBuilder();
097                Iterator it=sct.keyIterator();
098        boolean doIt=false;
099        Object oKey;
100        while(it.hasNext()) {
101                oKey=it.next();
102                if(ignoreSet!=null && ignoreSet.contains(oKey)) continue;
103            String key=Caster.toString(oKey,"");
104            if(doIt)sb.append('#');
105            doIt=true;
106            sb.append(escape(key));
107            sb.append('=');
108            sb.append(_serialize(sct.get(key,"")));
109        }
110        return sb.toString();
111        }
112
113        private static String escape(String str) {
114                int len=str.length();
115                StringBuilder sb=new StringBuilder();
116                char c;
117                for(int i=0;i<len;i++) {
118                        c=str.charAt(i);
119                        if(c=='=')              sb.append("#=");
120                        else if(c=='#') sb.append("##");
121                        else                    sb.append(c);
122                }
123                return sb.toString();
124        }
125
126        private static String _serialize(Object object) throws ConverterException {
127                
128                if(object==null) return "";
129                
130                // String
131                else if(object instanceof String) return escape(object.toString());
132                
133                // Number
134                else if(object instanceof Number) return Caster.toString(((Number)object));
135                
136                // Boolean
137                else if(object instanceof Boolean) return Caster.toString(((Boolean)object).booleanValue());
138                
139                // DateTime
140                else if(object instanceof DateTime) return Caster.toString(object,null);
141                
142                // Date
143                else if(object instanceof Date) return Caster.toString(object,null);
144                
145                throw new ConverterException("can't convert complex value "+Caster.toTypeName(object)+" to a simple value");
146        }
147
148        public static void main(String[] args) throws ConverterException {
149                Struct sct=new StructImpl();
150                sct.setEL("a", "b");
151                sct.setEL("pe#=ter", "ab##c");
152                sct.setEL("susi", Boolean.TRUE);
153                sct.setEL("peter", "abc");
154                sct.setEL("x", "");
155                
156                /*sct.setEL("abc=def", "abc");
157                sct.setEL("abc#def", "ab#=c");
158                */
159                String str;
160                aprint.out(sct);
161                aprint.out(str=ClientScopeConverter.serialize(sct));
162                aprint.out(ClientScopeConverter.unserialize(str));
163                //aprint.out(new ScriptConverter().serialize(sct));
164                
165                
166                
167        }
168
169}