1 16 package org.apache.cocoon.transformation; 17 18 import java.io.IOException ; 19 import java.util.Map ; 20 21 import org.apache.avalon.framework.parameters.Parameters; 22 import org.apache.cocoon.ProcessingException; 23 import org.apache.cocoon.components.source.InspectableSource; 24 import org.apache.cocoon.components.source.helpers.SourceProperty; 25 import org.apache.cocoon.environment.SourceResolver; 26 import org.apache.excalibur.source.Source; 27 import org.w3c.dom.Element ; 28 import org.w3c.dom.DocumentFragment ; 29 import org.w3c.dom.Node ; 30 import org.w3c.dom.NodeList ; 31 import org.xml.sax.Attributes ; 32 import org.xml.sax.SAXException ; 33 34 57 public class SourcePropsWritingTransformer extends AbstractSAXTransformer { 58 59 public static final String SPWT_URI = "http://apache.org/cocoon/propwrite/1.0"; 60 61 62 public static final String PATCH_ELEMENT = "patch"; 63 public static final String SOURCE_ELEMENT = "source"; 64 public static final String SET_ELEMENT = "set"; 65 public static final String REMOVE_ELEMENT = "remove"; 66 67 68 private static final int STATE_OUTSIDE = 0; 69 private static final int STATE_PATCH = 1; 70 private static final int STATE_SOURCE = 2; 71 private static final int STATE_SET = 3; 72 private static final int STATE_REMOVE = 4; 73 74 private int state; 75 76 80 public SourcePropsWritingTransformer() { 81 super.defaultNamespaceURI = SPWT_URI; 82 } 83 84 public void recycle() { 85 this.state = STATE_OUTSIDE; 86 super.recycle(); 87 } 88 89 98 public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) 99 throws ProcessingException, SAXException , IOException { 100 super.setup(resolver, objectModel, src, par); 101 this.state = STATE_OUTSIDE; 102 } 103 104 117 public void startTransformingElement(String uri, String name, String raw, Attributes attr) 118 throws SAXException , IOException , ProcessingException { 119 if (this.getLogger().isDebugEnabled()) { 120 this.getLogger().debug("BEGIN startTransformingElement uri=" + uri + 121 ", name=" + name + ", raw=" + raw + ", attr=" + attr); 122 } 123 if (this.state == STATE_OUTSIDE && name.equals(PATCH_ELEMENT)) { 125 this.state = STATE_PATCH; 126 this.stack.push("END"); 127 128 } else if (this.state == STATE_PATCH && name.equals(SOURCE_ELEMENT)) { 130 this.state = STATE_SOURCE; 131 this.startTextRecording(); 132 133 } else if (this.state == STATE_PATCH && name.equals(SET_ELEMENT)) { 135 this.state = STATE_SET; 136 this.startRecording(); 137 } else if (this.state == STATE_PATCH && name.equals(REMOVE_ELEMENT)) { 138 this.state = STATE_REMOVE; 139 this.startRecording(); 140 } else { 141 super.startTransformingElement(uri, name, raw, attr); 142 } 143 144 if (this.getLogger().isDebugEnabled() == true) { 145 this.getLogger().debug("END startTransformingElement"); 146 } 147 } 148 149 150 161 public void endTransformingElement(String uri, String name, String raw) 162 throws SAXException , IOException , ProcessingException { 163 if (this.getLogger().isDebugEnabled() == true) { 164 this.getLogger().debug("BEGIN endTransformingElement uri=" + uri + 165 ", name=" + name + 166 ", raw=" + raw); 167 } 168 169 if ((this.state == STATE_PATCH && name.equals(PATCH_ELEMENT))) { 171 this.state = STATE_OUTSIDE; 172 String sourceName = null; 173 String tag = null; 174 DocumentFragment setfrag = null; 175 DocumentFragment removefrag = null; 176 do { 177 tag = (String )this.stack.pop(); 178 if (tag.equals(SOURCE_ELEMENT)) { 179 sourceName = (String )this.stack.pop(); 180 } else if (tag.equals(SET_ELEMENT)) { 181 setfrag = (DocumentFragment )this.stack.pop(); 182 } else if (tag.equals(REMOVE_ELEMENT)) { 183 removefrag = (DocumentFragment )this.stack.pop(); 184 } 185 } while ( !tag.equals("END") ); 186 if (setfrag != null) { 187 NodeList list = setfrag.getChildNodes(); 188 Node node = null; 189 for (int i=0; i<list.getLength(); i++) { 190 node = list.item(i); 191 if (node instanceof Element ) { 192 this.setProperty(sourceName, (Element ) node); 193 } 194 } 195 } 196 if (removefrag != null) { 197 NodeList list = removefrag.getChildNodes(); 198 Node node = null; 199 for (int i=0; i<list.getLength(); i++) { 200 node = list.item(i); 201 if (node instanceof Element ) { 202 this.removeProperty(sourceName, (Element ) node); 203 } 204 } 205 } 206 207 } else if (this.state == STATE_SOURCE && name.equals(SOURCE_ELEMENT)) { 209 this.state = STATE_PATCH; 210 String sourceName = this.endTextRecording(); 211 this.stack.push(sourceName); 212 this.stack.push(SOURCE_ELEMENT); 213 214 } else if (this.state == STATE_SET && name.equals(SET_ELEMENT)) { 216 this.state = STATE_PATCH; 217 this.stack.push(this.endRecording()); 218 this.stack.push(SET_ELEMENT); 219 220 } else if (this.state == STATE_REMOVE && name.equals(REMOVE_ELEMENT)) { 222 this.state = STATE_PATCH; 223 this.stack.push(this.endRecording()); 224 this.stack.push(REMOVE_ELEMENT); 225 226 } else { 228 super.endTransformingElement(uri, name, raw); 229 } 230 231 if (this.getLogger().isDebugEnabled() == true) { 232 this.getLogger().debug("END endTransformingElement"); 233 } 234 } 235 236 private void setProperty(String src, Element element) 237 throws ProcessingException { 238 if (src != null && element != null) { 239 try { 240 Source source = this.resolver.resolveURI(src); 241 if (source instanceof InspectableSource) { 242 SourceProperty property = new SourceProperty(element); 243 ((InspectableSource)source).setSourceProperty(property); 244 245 } else { 246 getLogger().error("Cannot set properties on " + src + 247 ": not an inspectable source"); 248 } 249 } catch (Exception e) { 250 throw new ProcessingException("Error setting properties on "+src, e); 251 } 252 } else { 253 getLogger().error("Error setting properties on "+src); 254 } 255 } 256 257 private void removeProperty(String src, Element element) 258 throws ProcessingException { 259 260 if (src != null && element != null) { 261 try { 262 Source source = this.resolver.resolveURI(src); 263 if (source instanceof InspectableSource) { 264 ((InspectableSource)source).removeSourceProperty( 265 element.getNamespaceURI(),element.getLocalName()); 266 267 } else { 268 getLogger().error("Cannot remove properties on " + src + 269 ": not an inspectable source"); 270 } 271 } catch (Exception e) { 272 throw new ProcessingException("Error removing properties on "+src, e); 273 } 274 } else { 275 getLogger().error("Error removing properties on "+src); 276 } 277 } 278 } 279 | Popular Tags |