org.apache.cocoon.transformation
Class SourceWritingTransformer

java.lang.Object
  extended byorg.apache.cocoon.util.AbstractLogEnabled
      extended byorg.apache.cocoon.xml.AbstractXMLProducer
          extended byorg.apache.cocoon.xml.AbstractXMLPipe
              extended byorg.apache.cocoon.transformation.AbstractTransformer
                  extended byorg.apache.cocoon.transformation.AbstractSAXTransformer
                      extended byorg.apache.cocoon.transformation.SourceWritingTransformer
All Implemented Interfaces:
Configurable, ContentHandler, Disposable, LexicalHandler, Poolable, Recyclable, Serviceable, org.apache.cocoon.sitemap.SitemapModelComponent, org.apache.cocoon.transformation.Transformer, org.apache.cocoon.xml.XMLConsumer, XMLConsumer, org.apache.cocoon.xml.XMLPipe, org.apache.cocoon.xml.XMLProducer

public class SourceWritingTransformer
extends org.apache.cocoon.transformation.AbstractSAXTransformer

This transformer allows you to output to a ModifiableSource.

Definition:

 <map:transformer     name="tofile"     src="org.apache.cocoon.transformation.SourceWritingTransformer">
   <!-- 'xml' is the default Serializer (if your Source needs one, like for instance FileSource) -->
   <map:parameter name="serializer" value="xml"/>
 </map:transformer/>
 

Invocation:

 <map:transform type="tofile">
   <map:parameter name="serializer" value="xml"/>   <!-- you can optionally override the serializer here -->
 </map:transform>
 

The Tags:

 <source:write create="[true]|false"> - replaces the entire content of an existing asset, if @create is 'true' (default), a new asset will be created if one does not already exist.
     <source:source>The System ID of the asset to be written to</source:source> - eg: "docs/blah.xml" or "context://blah.xml" etc.
     <source:path>[Optional] XPath to specify how your content is wrapped</source:path> - eg: "doc" (your content is placed inside a <doc/> root tag). NOTE: if this value is omitted, your content MUST have only ONE top-level node.
     <source:fragment>The XML Fragment to be written</source:fragment> - eg: "<foo><bar id="dogcow"/></foo>" or "<foo/><bar><dogcow/><bar/>" etc. NOTE: the second example type, can only be used when the <source:path/> tag has been specified.
 <source:write>

 <source:insert create="[true]|false" overwrite="[true]|false"> - inserts content into an existing asset, if @create is 'true' (default), a new asset will be created if one does not already exist. If @overwrite is set to 'true' the data is only inserted if the node specified by the 'replacePath' does not exists.
     <source:source>The System ID of the asset to be written to</source:source> - eg: "docs/blah.xml" or "context://blah.xml" etc.
     <source:path>XPath specifying the node into which the content is inserted</source:path> - eg: "doc" (your content is appended as the last child of the <doc/> root tag), or "doc/section[3]". NOTE: this tag is required in <source:insert/> unlike <source:write/> where it is optional.
     <source:replace>[Optional] XPath (relative to <source:path/>) to the node that is replaced by your new content</source:replace> - eg: "foo/bar/dogcow/@status='cut'" (is equivalent to this in XSLT: select="foo[bar/dogcow/@status='cut']").
     <source:reinsert>[Optional] The XPath (relative to <source:replace/>) to backup the overwritten node to</source:reinsert> - eg: "foo/versions" or "/doc/versions/foo". NOTE: If specified and a node is replaced, all children of this replaced node will be reinserted at the given path.
     <source:fragment>The XML Fragment to be written</source:fragment> - eg: "<foo><bar id="dogcow"/></foo>" or "<foo/><bar><dogcow/><bar/>" etc.
 <source:insert>

 <source:delete > - deletes an existing asset.
     <source:source>The System ID of the asset to be deleted</source:source> - eg: "docs/blah.xml" or "context://blah.xml" etc.
     <source:path>[Ignored] XPath to specify how your content is wrapped</source:path>
     <source:fragment>[Ignored]The XML Fragment to be written</source:fragment>
 <source:delete>
 

Input XML document example (write):

 <page>
   ...
   <source:write xmlns:source="http://apache.org/cocoon/source/1.0">
     <source:source>context://doc/editable/my.xml</source:source>
     <source:fragment><page>
       <title>Hello World</title>
       <content>
         <p>This is my first paragraph.</p>
       </content>
     </page></source:fragment>
   </source:write>
   ...
 </page>
 

Input XML document example (insert at end):

 <page>
   ...
   <source:insert xmlns:source="http://apache.org/cocoon/source/1.0">
     <source:source>context://doc/editable/my.xml</source:source>
     <source:path>page/content</source:path>
     <source:fragment>
       <p>This paragraph gets <emp>inserted</emp>.</p>
       <p>With this one, at the end of the content.</p>
     </source:fragment>
   </source:insert>
   ...
 </page>
 

Input XML document example (insert at beginning):

 <page>
   ...
   <source:insert>
     <source:source>context://doc/editable/my.xml</source:source>
     <source:path>page</source:path>
     <source:replace>content</source:replace>
     <source:reinsert>content</source:reinsert>
     <source:fragment>
       <content>
         <p>This new paragraph gets inserted <emp>before</emp> the other ones.</p>
       </content>
     </source:fragment>
    <source:insert>
   ...
 </page>
 

Input XML document example (replace):

 <page>
   ...
   <source:insert xmlns:source="http://apache.org/cocoon/source/1.0">
     <source:source>context://doc/editable/my.xml"</source:source>
     <source:path>page/content</source:path>
     <source:replace>p[1]</source:replace>
     <source:fragment>
       <p>This paragraph <emp>replaces</emp> the first paragraph.</p>
     </source:fragment>
   </source:insert>
   ...
 </page>
 

Output XML document example:

 <page>
   ...
   <sourceResult xmlns:source="http://apache.org/cocoon/source/1.0">
     <action>new|overwritten|none</action>
     <behaviour>write|insert<behaviour>
     <execution>success|failure</execution>
     <serializer>xml</serializer>
     <source>file:/source/specific/path/to/context/doc/editable/my.xml</source>
   </sourceResult>
   ...
 </page>
 
The XPath specification is very complicated. So here is an example for the sitemap:
 <page xmlns:source="http://apache.org/cocoon/source/1.0">
   ...
 <source:insert>
   <source:source>sitemap.xmap</source:source>
   <source:path>/*[namespace-uri()="http://apache.org/cocoon/sitemap/1.0" and local-name()="sitemap"]/*[namespace-uri()="http://apache.org/cocoon/sitemap/1.0" and local-name()="components"]/*[namespace-uri()="http://apache.org/cocoon/sitemap/1.0" and local-name()="generators"]</source:path>
   <source:fragment>
	  	<generator name="file" xmln="http://apache.org/cocoon/sitemap/1.0">
			<test/>
		</generator>
   </source:fragment>
   <source:replace>*[namespace-uri()="http://apache.org/cocoon/sitemap/1.0" and local-name()="generator" and attribute::name="file"]</source:replace>
 </source:insert>
   ...
 </page>
 

This insert replaces (if it exists) the file generator definition with a new one. As the sitemap uses namespaces the XPath for the generator is rather complicated. Due to this it is necessary that the node specified by path exists if namespaces are used! Otherwise a node with the name * would be created...

The create attribute of insert. If this is set to true (default is true), the file is created if it does not exists. If it is set to false, it is not created, making insert a real insert. create is only usable for files!

In addition the overwrite attribute is used to check if replacing is allowed. If overwrite is true (the default) the node is replaced. If it is false the node is not inserted if the replace node is available.

[JQ] - the way I understand this, looking at the code:

   if 'replace' is not specified, your 'fragment' is appended as a child of 'path'.
   if 'replace' is specified and it exists and 'overwrite' is true, your 'fragment' is inserted in 'path', before 'replace' and then 'replace' is deleted.
   if 'replace' is specified and it exists and 'overwrite' is false, no action occurs.
   if 'replace' is specified and it does not exist and 'overwrite' is true, your 'fragment' is appended as a child of 'path'.
   if 'replace' is specified and it does not exist and 'overwrite' is false, your 'fragment' is appended as a child of 'path'.
   if 'reinsert' is specified and it does not exist, no action occurs.
  

The <source:reinsert> option can be used to reinsert a replaced node at a given path in the new fragment. TODO: Use the serializer instead of the XMLUtils for inserting of fragments
TODO: Add a <source:before/> tag.

Version:
$Id: SourceWritingTransformer.html 1304280 2012-03-23 11:18:01Z ilgrosso $

Field Summary
static String ACTION_DELETE
           
static String ACTION_ELEMENT
           
static String ACTION_NEW
           
static String ACTION_NONE
           
static String ACTION_OVER
           
static String BEHAVIOUR_ELEMENT
           
protected  String configuredSerializerName
          The configured serializer name
static String CREATE_ATTRIBUTE
           
static String DEFAULT_SERIALIZER
           
static String DELETE_ELEMENT
           
static String EXECUTION_ELEMENT
           
static String FRAGMENT_ELEMENT
           
static String INSERT_ELEMENT
           
static String MESSAGE_ELEMENT
           
static String OVERWRITE_ATTRIBUTE
           
static String PATH_ELEMENT
           
static String REINSERT_ELEMENT
           
static String REPLACE_ELEMENT
           
static String RESULT_ELEMENT
          outgoing elements
static String RESULT_FAILED
          results
static String RESULT_SUCCESS
           
static String SERIALIZER_ATTRIBUTE
          main (write or insert) tag attributes
static String SERIALIZER_ELEMENT
           
static String SOURCE_ELEMENT
           
static String SWT_URI
           
static String WRITE_ELEMENT
          incoming elements
protected  XPathProcessor xpathProcessor
          The XPath processor
 
Fields inherited from class org.apache.cocoon.transformation.AbstractSAXTransformer
context, defaultNamespaceURI, EMPTY_ATTRIBUTES, ignoreEmptyCharacters, ignoreEventsCount, ignoreHooksCount, ignoreWhitespaces, manager, namespaceURI, objectModel, parameters, recorderStack, removeOurNamespacePrefixes, request, resolver, response, source, stack
 
Fields inherited from class org.apache.cocoon.xml.AbstractXMLProducer
contentHandler, EMPTY_CONTENT_HANDLER, lexicalHandler, xmlConsumer
 
Fields inherited from interface org.apache.cocoon.transformation.Transformer
ROLE
 
Constructor Summary
SourceWritingTransformer()
          Constructor.
 
Method Summary
 void configure(Configuration configuration)
          Get the current Configuration instance used by this Configurable.
 void dispose()
           
 void endTransformingElement(String uri, String name, String raw)
          Receive notification of the end of an element.
protected  void insertFragment(String systemID, String path, DocumentFragment fragment, String replacePath, boolean create, boolean overwrite, String reinsertPath, String localSerializer, String tagname)
          Insert a fragment into a file.
 void service(ServiceManager manager)
           
 void setup(org.apache.cocoon.environment.SourceResolver resolver, Map objectModel, String src, Parameters par)
          Get the Parameter called "serializer" from the Transformer invocation.
 void startTransformingElement(String uri, String name, String raw, Attributes attr)
          Receive notification of the beginning of an element.
 
Methods inherited from class org.apache.cocoon.transformation.AbstractSAXTransformer
addRecorder, characters, comment, endCDATA, endDocument, endDTD, endElement, endEntity, endParametersRecording, endParametersRecording, endPrefixMapping, endRecording, endSAXRecording, endSerializedXMLRecording, endTextRecording, findPrefixMapping, getMutableAttributes, ignorableWhitespace, processingInstruction, recycle, removeRecorder, sendEndElementEvent, sendEndElementEventNS, sendEndPrefixMapping, sendEvents, sendParametersEvents, sendStartElementEvent, sendStartElementEvent, sendStartElementEventNS, sendStartElementEventNS, sendStartPrefixMapping, sendTextEvent, setDocumentLocator, setupTransforming, skippedEntity, startCDATA, startDocument, startDTD, startElement, startEntity, startParametersRecording, startPrefixMapping, startRecording, startSAXRecording, startSerializedXMLRecording, startTextRecording
 
Methods inherited from class org.apache.cocoon.xml.AbstractXMLProducer
setConsumer, setContentHandler, setLexicalHandler
 
Methods inherited from class org.apache.cocoon.util.AbstractLogEnabled
getLogger, setLogger
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface org.apache.cocoon.xml.XMLProducer
setConsumer
 

Field Detail

SWT_URI

public static final String SWT_URI
See Also:
Constant Field Values

DEFAULT_SERIALIZER

public static final String DEFAULT_SERIALIZER
See Also:
Constant Field Values

WRITE_ELEMENT

public static final String WRITE_ELEMENT
incoming elements

See Also:
Constant Field Values

INSERT_ELEMENT

public static final String INSERT_ELEMENT
See Also:
Constant Field Values

PATH_ELEMENT

public static final String PATH_ELEMENT
See Also:
Constant Field Values

FRAGMENT_ELEMENT

public static final String FRAGMENT_ELEMENT
See Also:
Constant Field Values

REPLACE_ELEMENT

public static final String REPLACE_ELEMENT
See Also:
Constant Field Values

DELETE_ELEMENT

public static final String DELETE_ELEMENT
See Also:
Constant Field Values

SOURCE_ELEMENT

public static final String SOURCE_ELEMENT
See Also:
Constant Field Values

REINSERT_ELEMENT

public static final String REINSERT_ELEMENT
See Also:
Constant Field Values

RESULT_ELEMENT

public static final String RESULT_ELEMENT
outgoing elements

See Also:
Constant Field Values

EXECUTION_ELEMENT

public static final String EXECUTION_ELEMENT
See Also:
Constant Field Values

BEHAVIOUR_ELEMENT

public static final String BEHAVIOUR_ELEMENT
See Also:
Constant Field Values

ACTION_ELEMENT

public static final String ACTION_ELEMENT
See Also:
Constant Field Values

MESSAGE_ELEMENT

public static final String MESSAGE_ELEMENT
See Also:
Constant Field Values

SERIALIZER_ELEMENT

public static final String SERIALIZER_ELEMENT
See Also:
Constant Field Values

SERIALIZER_ATTRIBUTE

public static final String SERIALIZER_ATTRIBUTE
main (write or insert) tag attributes

See Also:
Constant Field Values

CREATE_ATTRIBUTE

public static final String CREATE_ATTRIBUTE
See Also:
Constant Field Values

OVERWRITE_ATTRIBUTE

public static final String OVERWRITE_ATTRIBUTE
See Also:
Constant Field Values

RESULT_FAILED

public static final String RESULT_FAILED
results

See Also:
Constant Field Values

RESULT_SUCCESS

public static final String RESULT_SUCCESS
See Also:
Constant Field Values

ACTION_NONE

public static final String ACTION_NONE
See Also:
Constant Field Values

ACTION_NEW

public static final String ACTION_NEW
See Also:
Constant Field Values

ACTION_OVER

public static final String ACTION_OVER
See Also:
Constant Field Values

ACTION_DELETE

public static final String ACTION_DELETE
See Also:
Constant Field Values

configuredSerializerName

protected String configuredSerializerName
The configured serializer name


xpathProcessor

protected XPathProcessor xpathProcessor
The XPath processor

Constructor Detail

SourceWritingTransformer

public SourceWritingTransformer()
Constructor. Set the namespace.

Method Detail

configure

public void configure(Configuration configuration)
               throws ConfigurationException
Get the current Configuration instance used by this Configurable.

Throws:
ConfigurationException

setup

public void setup(org.apache.cocoon.environment.SourceResolver resolver,
                  Map objectModel,
                  String src,
                  Parameters par)
           throws org.apache.cocoon.ProcessingException,
                  SAXException,
                  IOException
Get the Parameter called "serializer" from the Transformer invocation.

Throws:
org.apache.cocoon.ProcessingException
SAXException
IOException

startTransformingElement

public void startTransformingElement(String uri,
                                     String name,
                                     String raw,
                                     Attributes attr)
                              throws SAXException,
                                     IOException,
                                     org.apache.cocoon.ProcessingException
Receive notification of the beginning of an element.

Parameters:
uri - The Namespace URI, or the empty string if the element has no Namespace URI or if Namespace processing is not being performed.
name - The local name (without prefix), or the empty string if Namespace processing is not being performed.
raw - The raw XML 1.0 name (with prefix), or the empty string if raw names are not available.
attr - The attributes attached to the element. If there are no attributes, it shall be an empty Attributes object.
Throws:
SAXException
IOException
org.apache.cocoon.ProcessingException

endTransformingElement

public void endTransformingElement(String uri,
                                   String name,
                                   String raw)
                            throws SAXException,
                                   IOException,
                                   org.apache.cocoon.ProcessingException
Receive notification of the end of an element.

Parameters:
uri - The Namespace URI, or the empty string if the element has no Namespace URI or if Namespace processing is not being performed.
name - The local name (without prefix), or the empty string if Namespace processing is not being performed.
raw - The raw XML 1.0 name (with prefix), or the empty string if raw names are not available.
Throws:
SAXException
IOException
org.apache.cocoon.ProcessingException

insertFragment

protected void insertFragment(String systemID,
                              String path,
                              DocumentFragment fragment,
                              String replacePath,
                              boolean create,
                              boolean overwrite,
                              String reinsertPath,
                              String localSerializer,
                              String tagname)
                       throws SAXException,
                              IOException,
                              org.apache.cocoon.ProcessingException
Insert a fragment into a file. The file is loaded by the resource connector.

Parameters:
systemID - The name of the xml file.
path - The XPath specifying the node under which the data is inserted
fragment - The data to be inserted.
replacePath - Optional XPath relative to path. This path can specify a node which will be removed if it exists. So insertFragment can be used as a replace utility.
create - If the file does not exists and this is set to false nothing is inserted. If it is set to true the file is created and the data is inserted.
overwrite - If this is set to true the data is only inserted if the node specified by the replacePath does not exists.
reinsertPath - If specified and a node is replaced , all children of this replaced node will be reinserted at the given path.
localSerializer - The serializer used to serialize the XML
tagname - The name of the tag that triggered me 'insert' or 'write'
Throws:
SAXException
IOException
org.apache.cocoon.ProcessingException

service

public void service(ServiceManager manager)
             throws ServiceException
Throws:
ServiceException

dispose

public void dispose()


Copyright 1999-2008 The Apache Software Foundation. All Rights Reserved.