001 package railo.runtime.tag; 002 003 import java.io.IOException; 004 005 import javax.xml.parsers.FactoryConfigurationError; 006 007 import railo.runtime.converter.ConverterException; 008 import railo.runtime.converter.JSConverter; 009 import railo.runtime.converter.WDDXConverter; 010 import railo.runtime.exp.ApplicationException; 011 import railo.runtime.exp.ExpressionException; 012 import railo.runtime.exp.PageException; 013 import railo.runtime.ext.tag.TagImpl; 014 import railo.runtime.op.Caster; 015 016 /** 017 * Serializes and de-serializes CFML data structures to the XML-based WDDX format. 018 * Generates JavaScript statements to instantiate JavaScript objects equivalent to the contents of a 019 * WDDX packet or some CFML data structures. 020 * 021 * 022 * 023 **/ 024 public final class Wddx extends TagImpl { 025 026 /** The value to be processed. */ 027 private Object input; 028 029 /** Specifies the action taken by the cfwddx tag. */ 030 private String action; 031 032 /** The name of the variable to hold the output of the operation. This attribute is required for 033 ** action = 'WDDX2CFML'. For all other actions, if this attribute is not provided, the result of the 034 ** WDDX processing is outputted in the HTML stream. */ 035 private String output; 036 037 private boolean validate; 038 039 /** The name of the top-level JavaScript object created by the deserialization process. The object 040 ** created is an instance of the WddxRecordset object, explained in WddxRecordset Object. */ 041 private String toplevelvariable; 042 043 /** Indicates whether to output time-zone information when serializing CFML to WDDX. If time-zone 044 ** information is taken into account, the hour-minute offset, as represented in the ISO8601 format, is 045 ** calculated in the date-time output. If time-zone information is not taken into account, the local 046 ** time is output. The default is Yes. */ 047 private boolean usetimezoneinfo; 048 049 private boolean xmlConform; 050 051 /** 052 * @see javax.servlet.jsp.tagext.Tag#release() 053 */ 054 public void release() { 055 super.release(); 056 input=null; 057 action=null; 058 output=null; 059 validate=false; 060 toplevelvariable=null; 061 usetimezoneinfo=false; 062 xmlConform=false; 063 } 064 065 066 /** set the value input 067 * The value to be processed. 068 * @param input value to set 069 **/ 070 public void setInput(Object input) { 071 this.input=input; 072 } 073 074 /** set the value action 075 * Specifies the action taken by the cfwddx tag. 076 * @param action value to set 077 **/ 078 public void setAction(String action) { 079 this.action=action.toLowerCase(); 080 } 081 082 /** set the value output 083 * The name of the variable to hold the output of the operation. This attribute is required for 084 * action = 'WDDX2CFML'. For all other actions, if this attribute is not provided, the result of the 085 * WDDX processing is outputted in the HTML stream. 086 * @param output value to set 087 **/ 088 public void setOutput(String output) { 089 this.output=output; 090 } 091 092 /** set the value validate 093 * 094 * @param validate value to set 095 **/ 096 public void setValidate(boolean validate) { 097 this.validate=validate; 098 } 099 100 /** set the value toplevelvariable 101 * The name of the top-level JavaScript object created by the deserialization process. The object 102 * created is an instance of the WddxRecordset object, explained in WddxRecordset Object. 103 * @param toplevelvariable value to set 104 **/ 105 public void setToplevelvariable(String toplevelvariable) { 106 this.toplevelvariable=toplevelvariable; 107 } 108 109 /** set the value usetimezoneinfo 110 * Indicates whether to output time-zone information when serializing CFML to WDDX. If time-zone 111 * information is taken into account, the hour-minute offset, as represented in the ISO8601 format, is 112 * calculated in the date-time output. If time-zone information is not taken into account, the local 113 * time is output. The default is Yes. 114 * @param usetimezoneinfo value to set 115 **/ 116 public void setUsetimezoneinfo(boolean usetimezoneinfo) { 117 this.usetimezoneinfo=usetimezoneinfo; 118 } 119 120 /** 121 * sets if generated code is xml or wddx conform 122 * @param xmlConform 123 */ 124 public void setXmlconform(boolean xmlConform) { 125 this.xmlConform=xmlConform; 126 } 127 128 129 /** 130 * @see javax.servlet.jsp.tagext.Tag#doStartTag() 131 */ 132 public int doStartTag() throws PageException { 133 try { 134 doIt(); 135 136 } catch (Exception e) { 137 throw Caster.toPageException(e); 138 } 139 return SKIP_BODY; 140 } 141 private void doIt() throws ExpressionException, PageException, ConverterException, IOException, FactoryConfigurationError { 142 // cfml > wddx 143 if(action.equals("cfml2wddx")) { 144 if(output!=null) pageContext.setVariable(output,cfml2wddx(input)); 145 else pageContext.forceWrite(cfml2wddx(input)); 146 } 147 148 // wddx > cfml 149 else if(action.equals("wddx2cfml")) { 150 if(output==null) throw new ApplicationException("at tag cfwddx the attribute output is required if you set action==wddx2cfml"); 151 pageContext.setVariable(output,wddx2cfml(Caster.toString(input))); 152 } 153 154 // cfml > js 155 else if(action.equals("cfml2js")) { 156 if(output!=null) pageContext.setVariable(output,cfml2js(input)); 157 else pageContext.forceWrite(cfml2js(input)); 158 } 159 160 // wddx > js 161 else if(action.equals("wddx2js")) { 162 if(output!=null) pageContext.setVariable(output,wddx2js(Caster.toString(input))); 163 else pageContext.forceWrite(wddx2js(Caster.toString(input))); 164 } 165 166 167 else throw new ExpressionException("invalid attribute action for tag cfwddx, attributes are [cfml2wddx, wddx2cfml,cfml2js, wddx2js]."); 168 169 } 170 171 private String cfml2wddx(Object input) throws ConverterException { 172 WDDXConverter converter =new WDDXConverter(pageContext.getTimeZone(),xmlConform,true); 173 if(!usetimezoneinfo)converter.setTimeZone(null); 174 return converter.serialize(input); 175 } 176 private Object wddx2cfml(String input) throws ConverterException, IOException, FactoryConfigurationError { 177 WDDXConverter converter =new WDDXConverter(pageContext.getTimeZone(),xmlConform,true); 178 converter.setTimeZone(pageContext.getTimeZone()); 179 return converter.deserialize(input,validate); 180 } 181 private String cfml2js(Object input) throws ConverterException { 182 if(toplevelvariable==null)missingTopLevelVariable(); 183 JSConverter converter =new JSConverter(); 184 return converter.serialize(input,toplevelvariable); 185 } 186 private String wddx2js(String input) throws ConverterException, IOException, FactoryConfigurationError { 187 if(toplevelvariable==null)missingTopLevelVariable(); 188 JSConverter converter =new JSConverter(); 189 return converter.serialize(wddx2cfml(input),toplevelvariable); 190 } 191 192 193 private ApplicationException missingTopLevelVariable() { 194 return new ApplicationException("at tag cfwddx the attribute topLevelVariable is required if you set action equal wddx2js or cfml2js"); 195 } 196 197 198 /** 199 * @see javax.servlet.jsp.tagext.Tag#doEndTag() 200 */ 201 public int doEndTag() { 202 return EVAL_PAGE; 203 } 204 }