1 16 package org.apache.cocoon.webapps.session.transformation; 17 18 import java.io.ByteArrayInputStream ; 19 import java.io.IOException ; 20 import java.util.Map ; 21 import java.util.Properties ; 22 23 import javax.xml.transform.OutputKeys ; 24 25 import org.apache.avalon.framework.configuration.Configuration; 26 import org.apache.avalon.framework.configuration.ConfigurationException; 27 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 28 import org.apache.avalon.framework.configuration.SAXConfigurationHandler; 29 import org.apache.cocoon.ProcessingException; 30 import org.apache.cocoon.acting.ValidatorActionResult; 31 import org.apache.cocoon.components.source.SourceUtil; 32 import org.apache.cocoon.environment.Session; 33 import org.apache.cocoon.webapps.session.SessionConstants; 34 import org.apache.cocoon.xml.XMLUtils; 35 import org.apache.excalibur.source.Source; 36 import org.apache.excalibur.source.SourceException; 37 import org.apache.excalibur.source.SourceParameters; 38 import org.w3c.dom.DocumentFragment ; 39 import org.w3c.dom.Node ; 40 import org.xml.sax.Attributes ; 41 import org.xml.sax.SAXException ; 42 import org.xml.sax.helpers.AttributesImpl ; 43 44 55 public class SessionPostTransformer extends SessionPreTransformer { 56 57 public static final String DELETECONTEXT_ELEMENT = "deletecontext"; 58 public static final String DELETECONTEXT_NAME_ATTRIBUTE = "name"; 59 60 public static final String SETXML_ELEMENT = "setxml"; 61 public static final String SETXML_CONTEXT_ATTRIBUTE = "context"; 62 public static final String SETXML_PATH_ATTRIBUTE = "path"; 63 64 public static final String APPENDXML_ELEMENT = "appendxml"; 65 public static final String APPENDXML_CONTEXT_ATTRIBUTE = "context"; 66 public static final String APPENDXML_PATH_ATTRIBUTE = "path"; 67 68 public static final String REMOVEXML_ELEMENT = "removexml"; 69 public static final String REMOVEXML_CONTEXT_ATTRIBUTE = "context"; 70 public static final String REMOVEXML_PATH_ATTRIBUTE = "path"; 71 72 public static final String MERGEXML_ELEMENT = "mergexml"; 73 public static final String MERGEXML_CONTEXT_ATTRIBUTE = "context"; 74 public static final String MERGEXML_PATH_ATTRIBUTE = "path"; 75 76 public static final String SAVECONTEXT_ELEMENT = "savexml"; 77 public static final String SAVECONTEXT_CONTEXT_ATTRIBUTE = "context"; 78 public static final String SAVECONTEXT_PATH_ATTRIBUTE = "path"; 80 public static final String INPUTXML_ELEMENT = "inputxml"; 81 public static final String INPUTXML_CONTEXT_ATTRIBUTE = "context"; 82 public static final String INPUTXML_PATH_ATTRIBUTE = "path"; 83 public static final String INPUTXML_NAME_ATTRIBUTE = "name"; 84 public static final String INPUTXML_TYPE_ATTRIBUTE = "type"; public static final String INPUTXML_VALIDATIONRESULT_ATTRIBUTE = "valresult"; 86 87 88 public static final String FORM_ELEMENT = "form"; 89 90 91 public static final String FORM_ACTION_ELEMENT = "action"; 92 93 94 public static final String FORM_CONTENT_ELEMENT = "content"; 95 96 97 public static final String FORM_VALIDATION_ELEMENT = "validate"; 98 public static final String FORM_VALIDATION_SOURCE_ATTRIBUTE = "src"; 99 public static final String FORM_VALIDATESET_ELEMENT = "constraint-set"; 100 101 102 private static final int STATE_OUTSIDE = 0; 103 104 private static final int STATE_FORM = 1; 105 106 107 private int state; 108 109 110 private String formName; 111 112 113 private Map validationResultMap; 114 115 public void setupTransforming() throws ProcessingException, SAXException , IOException { 116 super.setupTransforming(); 117 this.state = STATE_OUTSIDE; 118 this.formName = null; 119 } 120 121 127 public void startTransformingElement(String uri, String name, String raw, Attributes attr) 128 throws ProcessingException, IOException , SAXException { 129 if (this.getLogger().isDebugEnabled()) { 130 this.getLogger().debug("BEGIN startTransformingElement uri=" + uri + ", name=" + name 131 + ", raw=" + raw + ", attr=" + attr); 132 } 133 if (name.equals(DELETECONTEXT_ELEMENT)) { 134 this.getContextManager().deleteContext(attr.getValue(DELETECONTEXT_NAME_ATTRIBUTE)); 135 136 } else if (name.equals(SETXML_ELEMENT)) { 137 this.startRecording(); 138 stack.push(attr.getValue(SETXML_CONTEXT_ATTRIBUTE)); 139 stack.push(attr.getValue(SETXML_PATH_ATTRIBUTE)); 140 141 } else if (name.equals(MERGEXML_ELEMENT)) { 143 this.startRecording(); 144 stack.push(attr.getValue(MERGEXML_CONTEXT_ATTRIBUTE)); 145 stack.push(attr.getValue(MERGEXML_PATH_ATTRIBUTE)); 146 147 } else if (name.equals(APPENDXML_ELEMENT)) { 149 this.startRecording(); 150 stack.push(attr.getValue(APPENDXML_CONTEXT_ATTRIBUTE)); 151 stack.push(attr.getValue(APPENDXML_PATH_ATTRIBUTE)); 152 153 } else if (name.equals(REMOVEXML_ELEMENT)) { 155 this.startTextRecording(); 156 stack.push(attr.getValue(REMOVEXML_CONTEXT_ATTRIBUTE)); 157 stack.push(attr.getValue(REMOVEXML_PATH_ATTRIBUTE)); 158 159 } else if (name.equals(SAVECONTEXT_ELEMENT)) { 160 this.startParametersRecording(); 161 stack.push(attr.getValue(SAVECONTEXT_CONTEXT_ATTRIBUTE)); 162 if (attr.getValue(SAVECONTEXT_PATH_ATTRIBUTE) != null) { 163 stack.push(attr.getValue(SAVECONTEXT_PATH_ATTRIBUTE)); 164 } else { 165 stack.push("/"); 166 } 167 168 } else if (name.equals(INPUTXML_ELEMENT)) { 170 stack.push(attr.getValue(INPUTXML_CONTEXT_ATTRIBUTE)); 171 String fieldname = attr.getValue(INPUTXML_NAME_ATTRIBUTE); 172 stack.push(fieldname); 173 stack.push(attr.getValue(INPUTXML_PATH_ATTRIBUTE)); 174 175 AttributesImpl newattr = new AttributesImpl (); 176 newattr.addAttribute("", INPUTXML_NAME_ATTRIBUTE, INPUTXML_NAME_ATTRIBUTE, "CDATA", fieldname); 177 if (attr.getValue(INPUTXML_TYPE_ATTRIBUTE) != null) { 178 newattr.addAttribute("", INPUTXML_TYPE_ATTRIBUTE, INPUTXML_TYPE_ATTRIBUTE, "CDATA", 179 attr.getValue(INPUTXML_TYPE_ATTRIBUTE)); 180 } 181 182 ValidatorActionResult validationResult = null; 183 if (validationResultMap != null && validationResultMap.get(fieldname) != null) { 184 validationResult = (ValidatorActionResult)validationResultMap.get(fieldname); 185 newattr.addAttribute("", INPUTXML_VALIDATIONRESULT_ATTRIBUTE, 186 INPUTXML_VALIDATIONRESULT_ATTRIBUTE,"CDATA", validationResult.toString()); 187 } 188 189 super.startTransformingElement("", name, name, newattr); this.startRecording(); 191 192 } else if (name.equals(FORM_ELEMENT) && this.state == STATE_OUTSIDE) { 194 String formName = attr.getValue("name"); 195 if (formName == null) { 196 throw new ProcessingException("The name attribute of the form element is required."); 197 } 198 this.stack.push(new Integer (this.state)); 199 this.state = STATE_FORM; 200 this.stack.push(new AttributesImpl (attr)); 201 202 } else if (name.equals(FORM_ACTION_ELEMENT) && this.state == STATE_FORM) { 204 this.startTextRecording(); 205 206 } else if (name.equals(FORM_CONTENT_ELEMENT) && this.state == STATE_FORM) { 208 validationResultMap = (Map )this.getSessionManager().getSession(true) 210 .getAttribute(this.formName + "validation-result"); 211 212 } else if (name.equals(FORM_VALIDATION_ELEMENT) && this.state == STATE_FORM) { 214 this.startRecording(); 215 if (attr.getValue(FORM_VALIDATION_SOURCE_ATTRIBUTE) != null) { 216 stack.push(attr.getValue(FORM_VALIDATION_SOURCE_ATTRIBUTE)); 217 } else { 218 stack.push("EMPTY"); 219 } 220 221 } else { 222 super.startTransformingElement(uri, name, raw, attr); 223 } 224 if (this.getLogger().isDebugEnabled()) { 225 this.getLogger().debug("END startTransformingElement"); 226 } 227 } 228 229 public void endTransformingElement(String uri, String name, String raw) 230 throws ProcessingException, IOException , SAXException { 231 if (this.getLogger().isDebugEnabled()) { 232 this.getLogger().debug("BEGIN endTransformingElement uri=" + uri + ", name=" + name + ", raw=" + raw); 233 } 234 if (name.equals(DELETECONTEXT_ELEMENT)) { 235 237 } else if (name.equals(SETXML_ELEMENT)) { 239 String path = (String )stack.pop(); 240 String contextName = (String )stack.pop(); 241 this.getSessionManager().setContextFragment(contextName, path, this.endRecording()); 242 243 } else if (name.equals(MERGEXML_ELEMENT)) { 245 String path = (String )stack.pop(); 246 String contextName = (String )stack.pop(); 247 this.getSessionManager().mergeContextFragment(contextName, path, this.endRecording()); 248 249 } else if (name.equals(APPENDXML_ELEMENT)) { 251 String path = (String )stack.pop(); 252 String contextName = (String )stack.pop(); 253 this.getSessionManager().appendContextFragment(contextName, path, this.endRecording()); 254 255 } else if (name.equals(REMOVEXML_ELEMENT)) { 257 String path = (String )stack.pop(); 258 String contextName = (String )stack.pop(); 259 endTextRecording(); 261 this.getSessionManager().removeContextFragment(contextName, path); 262 263 } else if (name.equals(SAVECONTEXT_ELEMENT)) { 265 String path = (String )stack.pop(); 266 String contextName = (String )stack.pop(); 267 SourceParameters pars = this.endParametersRecording((SourceParameters)null); 268 pars.setSingleParameterValue("contextname", contextName); 269 pars.setSingleParameterValue("path", path); 270 271 this.getContextManager().getContext(contextName).saveXML(path, pars); 272 273 } else if (name.equals(INPUTXML_ELEMENT)) { 275 String path = (String )this.stack.pop(); 276 String fieldname = (String )this.stack.pop(); 277 String contextname = (String )this.stack.pop(); 278 DocumentFragment defaultFragment = this.endRecording(); 279 280 if (this.formName == null) { 281 throw new ProcessingException("The inputxml must be contained inside a form."); 282 } 283 DocumentFragment value = this.getFormManager().registerInputField(contextname, path, 284 fieldname, formName); 285 if (value == null) { 286 value = defaultFragment; 287 } 288 this.sendEvents(value); 289 super.endTransformingElement("", name, name); 290 291 } else if (name.equals(FORM_ELEMENT) && this.state == STATE_FORM) { 293 this.state = ((Integer )this.stack.pop()).intValue(); 294 this.sendEndElementEvent("form"); 295 this.formName = null; 296 297 } else if (name.equals(FORM_ACTION_ELEMENT) && this.state == STATE_FORM) { 299 String action = this.endTextRecording(); 300 AttributesImpl a = (AttributesImpl )this.stack.pop(); 301 this.formName = a.getValue("name"); 302 boolean hasPars = (action.indexOf("?") != -1); 303 action = this.response.encodeURL(action + (hasPars ? '&' : '?') 304 + SessionConstants.SESSION_FORM_PARAMETER + '=' + this.formName); 305 a.addAttribute("", "action", "action", "CDATA", action); 306 if (a.getValue("method") == null) { 307 a.addAttribute("", "method", "method", "CDATA", "POST"); 308 } 309 this.sendStartElementEvent("form", a); 310 311 } else if (name.equals(FORM_CONTENT_ELEMENT) && this.state == STATE_FORM) { 313 315 } else if (name.equals(FORM_VALIDATION_ELEMENT) && this.state == STATE_FORM) { 317 if (this.formName == null) { 318 throw new ProcessingException("The validate element must be contained inside a form."); 319 } 320 DocumentFragment validationDoc = this.endRecording(); 321 String source = (String )stack.pop(); 322 if (!source.equals("EMPTY")) { 323 try { 326 Source resource = this.resolver.resolveURI(source); 327 SAXConfigurationHandler saxBuilder = new SAXConfigurationHandler(); 328 SourceUtil.parse(this.manager, resource, saxBuilder); 329 330 Configuration conf = saxBuilder.getConfiguration(); 331 Session session = this.getSessionManager().getSession(true); 332 session.setAttribute(this.formName, conf); 333 334 if (validationDoc != null) { 335 validationDoc.normalize(); 337 Node validationNode = validationDoc.getFirstChild(); 338 while (validationNode.getNodeType() != Node.ELEMENT_NODE) { 339 validationNode = validationNode.getNextSibling(); 340 if (validationNode == null) { 341 break; 342 } 343 } 344 if (validationNode != null && validationNode.getNodeType() == Node.ELEMENT_NODE 345 && validationNode.getNodeName().equals(FORM_VALIDATESET_ELEMENT)) { 346 Properties props = XMLUtils.createPropertiesForXML(false); 347 props.put(OutputKeys.ENCODING, "ISO-8859-1"); 348 String validationXML = XMLUtils.serializeNode(validationNode, props); 349 DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); 350 conf = builder.build(new ByteArrayInputStream (validationXML.getBytes())); 351 session.setAttribute(this.formName + "constraint-set", conf); 352 } 353 } 354 355 } catch (SourceException se) { 356 throw new ProcessingException("Cannot resolve" + source, se); 357 } catch (ConfigurationException ce) { 358 throw new ProcessingException("Error building Configuration out of constraint-set element", ce); 359 } 360 361 } else if (validationDoc != null) { 362 try { 364 validationDoc.normalize(); 365 Node validationNode = validationDoc.getFirstChild(); 366 while (validationNode.getNodeType() != Node.ELEMENT_NODE) { 367 validationNode = validationNode.getNextSibling(); 368 if (validationNode == null) { 369 break; 370 } 371 } 372 if (validationNode != null && validationNode.getNodeType() == Node.ELEMENT_NODE 373 && validationNode.getNodeName().equals("root")) { 374 Properties props = XMLUtils.createPropertiesForXML(false); 375 props.put(OutputKeys.ENCODING, "ISO-8859-1"); 376 String validationXML = XMLUtils.serializeNode(validationNode, props); 377 DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); 378 Configuration conf = builder.build(new ByteArrayInputStream (validationXML.getBytes())); 379 Session session = this.getSessionManager().getSession(true); 380 session.setAttribute(this.formName, conf); 381 session.setAttribute(this.formName + "constraint-set", conf.getChildren("constraint-set")[0]); 383 384 } 385 } catch (ConfigurationException ce) { 386 throw new ProcessingException("Error building Configuration out of validation XML", ce); 387 } 388 } 389 390 } else { 391 super.endTransformingElement(uri, name, raw); 392 } 393 if (this.getLogger().isDebugEnabled()) { 394 this.getLogger().debug("END endTransformingElement"); 395 } 396 } 397 } 398 | Popular Tags |