1 16 package org.apache.myfaces.wap.renderkit; 17 18 import javax.faces.render.ResponseStateManager; 19 20 import javax.faces.FacesException; 21 import javax.faces.application.StateManager; 22 import javax.faces.context.FacesContext; 23 import javax.faces.context.ResponseWriter; 24 import java.io.*; 25 import java.net.URLEncoder ; 26 import java.util.Map ; 27 import java.util.zip.GZIPInputStream ; 28 import java.util.zip.GZIPOutputStream ; 29 30 import org.apache.commons.codec.binary.Base64; 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 41 public class WmlResponseStateManagerImpl extends ResponseStateManager { 42 private static Log log = LogFactory.getLog(WmlResponseStateManagerImpl.class); 43 44 private static final String TREE_PARAM = "jsf_tree"; 45 private static final String STATE_PARAM = "jsf_state"; 46 private static final String VIEWID_PARAM = "jsf_viewid"; 47 private static final String BASE64_TREE_PARAM = "jsf_tree_64"; 48 private static final String BASE64_STATE_PARAM = "jsf_state_64"; 49 private static final String ZIP_CHARSET = "UTF-8"; 50 51 private static final String WML_POSTFIELD = "postfield"; 52 private static final String WML_POSTFIELD_NAME = "name"; 53 private static final String WML_POSTFIELD_VALUE = "value"; 54 55 public void writeState(FacesContext facescontext, StateManager.SerializedView serializedview) throws IOException { 56 ResponseWriter responseWriter = facescontext.getResponseWriter(); 57 Object treeStruct = serializedview.getStructure(); 58 Object compStates = serializedview.getState(); 59 60 if (treeStruct != null) { 61 if (treeStruct instanceof String ) { 62 responseWriter.startElement(WML_POSTFIELD, null); 63 responseWriter.writeAttribute(WML_POSTFIELD_NAME, TREE_PARAM, null); 64 responseWriter.writeAttribute(WML_POSTFIELD_VALUE, treeStruct, null); 65 responseWriter.endElement(WML_POSTFIELD); 66 } 67 else { 68 responseWriter.startElement(WML_POSTFIELD, null); 69 responseWriter.writeAttribute(WML_POSTFIELD_NAME, BASE64_TREE_PARAM, null); 70 responseWriter.writeAttribute(WML_POSTFIELD_VALUE, encode64(treeStruct), null); 71 responseWriter.endElement(WML_POSTFIELD); 72 } 73 } 74 else { 75 log.error("No tree structure to be saved in client response!"); 76 } 77 78 if (compStates != null) { 79 if (compStates instanceof String ) { 80 responseWriter.startElement(WML_POSTFIELD, null); 81 responseWriter.writeAttribute(WML_POSTFIELD_NAME, STATE_PARAM, null); 82 responseWriter.writeAttribute(WML_POSTFIELD_VALUE, compStates, null); 83 responseWriter.endElement(WML_POSTFIELD); 84 } 85 else { 86 responseWriter.startElement(WML_POSTFIELD, null); 87 responseWriter.writeAttribute(WML_POSTFIELD_NAME, BASE64_STATE_PARAM, null); 88 responseWriter.writeAttribute(WML_POSTFIELD_VALUE, encode64(compStates), null); 89 responseWriter.endElement(WML_POSTFIELD); 90 } 91 } 92 else { 93 log.error("No component states to be saved in client response!"); 94 } 95 96 responseWriter.startElement(WML_POSTFIELD, null); 97 responseWriter.writeAttribute(WML_POSTFIELD_NAME, VIEWID_PARAM, null); 98 responseWriter.writeAttribute(WML_POSTFIELD_VALUE, facescontext.getViewRoot().getViewId(), null); 99 responseWriter.endElement(WML_POSTFIELD); 100 } 101 102 private String encode64(Object obj) { 103 try { 104 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 105 OutputStream zos = new GZIPOutputStream (baos); 106 ObjectOutputStream oos = new ObjectOutputStream(zos); 107 oos.writeObject(obj); 108 oos.close(); 109 zos.close(); 110 baos.close(); 111 Base64 base64Codec = new Base64(); 112 return new String (base64Codec.encode( baos.toByteArray() ), ZIP_CHARSET); 113 } 114 catch (IOException e) { 115 log.fatal("Cannot encode Object with Base64", e); 116 throw new FacesException(e); 117 } 118 } 119 120 121 public Object getTreeStructureToRestore(FacesContext facescontext, String viewId) { 122 Map reqParamMap = facescontext.getExternalContext().getRequestParameterMap(); 123 Object param = reqParamMap.get(VIEWID_PARAM); 124 if (param == null || !param.equals(viewId)) { 125 return null; 127 } 128 129 param = reqParamMap.get(TREE_PARAM); 130 if (param != null) { 131 return param; 132 } 133 134 param = reqParamMap.get(BASE64_TREE_PARAM); 135 if (param != null) { 136 return decode64((String )param); 137 } 138 139 return null; 140 } 141 142 public Object getComponentStateToRestore(FacesContext facescontext) { 143 Map reqParamMap = facescontext.getExternalContext().getRequestParameterMap(); 144 Object param = reqParamMap.get(STATE_PARAM); 145 if (param != null) { 146 return param; 147 } 148 149 param = reqParamMap.get(BASE64_STATE_PARAM); 150 if (param != null) { 151 return decode64((String )param); 152 } 153 154 return null; 155 } 156 157 private Object decode64(String s) { 158 try { 159 Base64 base64Codec = new Base64(); 160 ByteArrayInputStream decodedStream = new ByteArrayInputStream( base64Codec.decode( s.getBytes(ZIP_CHARSET) ) ); 161 InputStream unzippedStream = new GZIPInputStream (decodedStream); 162 ObjectInputStream ois = new ObjectInputStream(unzippedStream); 163 Object obj = ois.readObject(); 164 ois.close(); 165 unzippedStream.close(); 166 decodedStream.close(); 167 return obj; 168 } 169 catch (IOException e) { 170 log.fatal("Cannot decode Object from Base64 String", e); 171 throw new FacesException(e); 172 } 173 catch (ClassNotFoundException e) { 174 log.fatal("Cannot decode Object from Base64 String", e); 175 throw new FacesException(e); 176 } 177 } 178 179 180 181 private void writeStateParam(ResponseWriter writer, String name, String value) throws IOException { 182 writer.write(name); 183 writer.write('='); 184 writer.write(URLEncoder.encode(value, writer.getCharacterEncoding())); 185 } 186 } 187 | Popular Tags |