1 16 package org.directwebremoting.convert; 17 18 import java.lang.reflect.Modifier ; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.Map ; 22 import java.util.StringTokenizer ; 23 24 import org.directwebremoting.dwrp.ParseUtil; 25 import org.directwebremoting.dwrp.ProtocolConstants; 26 import org.directwebremoting.dwrp.ObjectOutboundVariable; 27 import org.directwebremoting.extend.Converter; 28 import org.directwebremoting.extend.ConverterManager; 29 import org.directwebremoting.extend.InboundContext; 30 import org.directwebremoting.extend.InboundVariable; 31 import org.directwebremoting.extend.MarshallException; 32 import org.directwebremoting.extend.OutboundContext; 33 import org.directwebremoting.extend.OutboundVariable; 34 import org.directwebremoting.extend.TypeHintContext; 35 import org.directwebremoting.util.JavascriptUtil; 36 import org.directwebremoting.util.LocalUtil; 37 import org.directwebremoting.util.Logger; 38 import org.directwebremoting.util.Messages; 39 40 45 public class MapConverter implements Converter 46 { 47 50 public void setConverterManager(ConverterManager newConfig) 51 { 52 this.config = newConfig; 53 } 54 55 58 public Object convertInbound(Class paramType, InboundVariable iv, InboundContext inctx) throws MarshallException 59 { 60 String value = iv.getValue(); 61 62 if (value.trim().equals(ProtocolConstants.INBOUND_NULL)) 64 { 65 return null; 66 } 67 68 if (!value.startsWith(ProtocolConstants.INBOUND_MAP_START)) 69 { 70 throw new IllegalArgumentException (Messages.getString("MapConverter.FormatError", ProtocolConstants.INBOUND_MAP_START)); 71 } 72 73 if (!value.endsWith(ProtocolConstants.INBOUND_MAP_END)) 74 { 75 throw new IllegalArgumentException (Messages.getString("MapConverter.FormatError", ProtocolConstants.INBOUND_MAP_END)); 76 } 77 78 value = value.substring(1, value.length() - 1); 79 80 try 81 { 82 Map map; 85 86 if (!paramType.isInterface() && !Modifier.isAbstract(paramType.getModifiers())) 88 { 89 map = (Map ) paramType.newInstance(); 94 } 95 else 96 { 97 map = new HashMap (); 98 } 99 100 TypeHintContext thc = inctx.getCurrentTypeHintContext(); 102 103 TypeHintContext keyThc = thc.createChildContext(0); 104 Class keyType = keyThc.getExtraTypeInfo(); 105 106 TypeHintContext valThc = thc.createChildContext(1); 107 Class valType = valThc.getExtraTypeInfo(); 108 109 inctx.addConverted(iv, paramType, map); 112 InboundContext incx = iv.getLookup(); 113 114 StringTokenizer st = new StringTokenizer (value, ","); 116 int size = st.countTokens(); 117 for (int i = 0; i < size; i++) 118 { 119 String token = st.nextToken(); 120 if (token.trim().length() == 0) 121 { 122 continue; 123 } 124 125 int colonpos = token.indexOf(ProtocolConstants.INBOUND_MAP_ENTRY); 126 if (colonpos == -1) 127 { 128 throw new MarshallException(paramType, Messages.getString("MapConverter.MissingSeparator", ProtocolConstants.INBOUND_MAP_ENTRY, token)); 129 } 130 131 String valStr = token.substring(colonpos + 1).trim(); 134 String [] splitIv = ParseUtil.splitInbound(valStr); 135 String splitIvValue = splitIv[LocalUtil.INBOUND_INDEX_VALUE]; 136 String splitIvType = splitIv[LocalUtil.INBOUND_INDEX_TYPE]; 137 InboundVariable valIv = new InboundVariable(incx, null, splitIvType, splitIvValue); 138 Object val = config.convertInbound(valType, valIv, inctx, valThc); 139 140 String keyStr = token.substring(0, colonpos).trim(); 144 InboundVariable keyIv = new InboundVariable(incx, null, ProtocolConstants.TYPE_STRING, keyStr); 147 Object key = config.convertInbound(keyType, keyIv, inctx, keyThc); 148 149 map.put(key, val); 150 } 151 152 return map; 153 } 154 catch (MarshallException ex) 155 { 156 throw ex; 157 } 158 catch (Exception ex) 159 { 160 throw new MarshallException(paramType, ex); 161 } 162 } 163 164 167 public OutboundVariable convertOutbound(Object data, OutboundContext outctx) throws MarshallException 168 { 169 Map ovs = (Map ) LocalUtil.classNewInstance("OrderedConvertOutbound", "java.util.LinkedHashMap", Map .class); 171 if (ovs == null) 172 { 173 ovs = new HashMap (); 174 } 175 176 ObjectOutboundVariable ov = new ObjectOutboundVariable(outctx); 177 outctx.put(data, ov); 178 179 Map map = (Map ) data; 182 for (Iterator it = map.entrySet().iterator(); it.hasNext();) 183 { 184 Map.Entry entry = (Map.Entry ) it.next(); 185 Object key = entry.getKey(); 186 Object value = entry.getValue(); 187 188 if (!(key instanceof String ) && !sentNonStringWarning) 190 { 191 log.warn("--Javascript does not support non string keys. Converting '" + key.getClass().getName() + "' using toString()"); 192 sentNonStringWarning = true; 193 } 194 195 String outkey = JavascriptUtil.escapeJavaScript(key.toString()); 196 197 201 OutboundVariable nested = config.convertOutbound(value, outctx); 202 203 ovs.put(outkey, nested); 204 } 205 206 ov.init(ovs, null); 207 208 return ov; 209 } 210 211 214 private static boolean sentNonStringWarning = false; 215 216 219 private ConverterManager config = null; 220 221 224 private static final Logger log = Logger.getLogger(MapConverter.class); 225 } 226 | Popular Tags |