gianugo     2003/07/28 04:28:22

  Modified:    src/java/org/apache/cocoon/transformation
                        SourceWritingTransformer.java
               src/documentation/xdocs/userdocs/transformers
                        sourcewriting-transformer.xml
               .        status.xml
  Log:
  Added delete capabilities to the SourceWritingTransformer, while solving
  a DOM bug(?) with new documents creation.
  
  Revision  Changes    Path
  1.5       +77 -9     
cocoon-2.1/src/java/org/apache/cocoon/transformation/SourceWritingTransformer.java
  
  Index: SourceWritingTransformer.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/java/org/apache/cocoon/transformation/SourceWritingTransformer.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SourceWritingTransformer.java     16 Mar 2003 17:49:15 -0000      1.4
  +++ SourceWritingTransformer.java     28 Jul 2003 11:28:20 -0000      1.5
  @@ -110,6 +110,12 @@
    *     <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>
    * </pre>
    *
    *
  @@ -248,6 +254,7 @@
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
    * @author <a href="mailto:[EMAIL PROTECTED]">Jeremy Quinn</a>
  + * @author <a href="mailto:[EMAIL PROTECTED]">Gianugo Rabellino</a>
    * @version CVS $Id$
    */
   public class SourceWritingTransformer
  @@ -262,6 +269,7 @@
       public static final String PATH_ELEMENT = "path";
       public static final String FRAGMENT_ELEMENT = "fragment";
       public static final String REPLACE_ELEMENT = "replace";
  +    public static final String DELETE_ELEMENT = "delete";
       public static final String SOURCE_ELEMENT = "source";
       public static final String REINSERT_ELEMENT = "reinsert";
       /** outgoing elements */
  @@ -281,6 +289,7 @@
       public static final String ACTION_NONE = "none";
       public static final String ACTION_NEW = "new";
       public static final String ACTION_OVER = "overwritten";
  +    public static final String ACTION_DELETE = "deleted";
       /** The current state */
       private static final int STATE_OUTSIDE  = 0;
       private static final int STATE_INSERT   = 1;
  @@ -290,6 +299,7 @@
       private static final int STATE_FILE     = 6;
       private static final int STATE_REINSERT = 7;
       private static final int STATE_WRITE    = 8;
  +    private static final int STATE_DELETE = 9;
       private int state;
       private int parent_state;
   
  @@ -366,15 +376,20 @@
               this.stack.push(attr.getValue(SERIALIZER_ATTRIBUTE));
               this.stack.push("END");
   
  +        // Element: delete
  +        } else if (this.state == STATE_OUTSIDE && 
name.equals(DELETE_ELEMENT)) {
  +            this.state = STATE_DELETE;
  +            this.parent_state = state;
  +            this.stack.push("END");
           // Element: file
           } else if (name.equals(SOURCE_ELEMENT)
  -                   && (this.state == STATE_INSERT || this.state == 
STATE_WRITE)) {
  +                   && (this.state == STATE_INSERT || this.state == 
STATE_WRITE || this.state == STATE_DELETE)) {
               this.state = STATE_FILE;
               this.startTextRecording();
   
           // Element: path
           } else if (name.equals(PATH_ELEMENT)
  -                   && (this.state == STATE_INSERT || this.state == 
STATE_WRITE)) {
  +                   && (this.state == STATE_INSERT || this.state == 
STATE_WRITE || this.state == STATE_DELETE)) {
               this.state = STATE_PATH;
               this.startTextRecording();
   
  @@ -386,7 +401,7 @@
   
           // Element: fragment
           } else if (name.equals(FRAGMENT_ELEMENT)
  -                   &&  (this.state == STATE_INSERT || this.state == 
STATE_WRITE)) {
  +                   &&  (this.state == STATE_INSERT || this.state == 
STATE_WRITE || this.state == STATE_DELETE)) {
               this.state = STATE_FRAGMENT;
               this.startRecording();
   
  @@ -466,6 +481,22 @@
   
               this.state = STATE_OUTSIDE;
   
  +        // Element: delete
  +        } else if (name.equals(DELETE_ELEMENT) && this.state == 
STATE_DELETE) {
  +            String sourceName = null;
  +            String tag;
  +            do {
  +                tag = (String)this.stack.pop();
  +                if (tag.equals("FILE")) {
  +                    sourceName = (String)this.stack.pop();
  +                } else if (tag.equals("FRAGMENT")) {
  +                    //Get rid of it
  +                    this.stack.pop();
  +                }
  +            } while ( !tag.equals("END"));
  +            
  +            this.deleteSource(sourceName);
  +            this.state = STATE_OUTSIDE;                       
           // Element: file
           } else if (name.equals(SOURCE_ELEMENT) == true && this.state == 
STATE_FILE) {
               this.state = this.parent_state;
  @@ -506,6 +537,34 @@
           }
       }
   
  +    /**
  +     * Deletes a source
  +     * @param sourceName
  +     */
  +    private void deleteSource(String systemID) throws ProcessingException, 
IOException, SAXException {
  +        try {
  +            Source source = resolver.resolveURI(systemID);            
  +            if ( ! (source instanceof ModifiableSource)) {
  +                throw new ProcessingException("Source '"+systemID+"' is not 
writeable.");
  +            }
  +            ModifiableSource ms = (ModifiableSource)source;
  +            ms.delete();
  +        } catch (SourceException se) {
  +            reportResult("none", 
  +                "delete", 
  +                "unable to delete Source:" + se.getMessage(), 
  +                systemID, 
  +                RESULT_FAILED,
  +                ACTION_DELETE);
  +        }
  +        reportResult("none", 
  +            "delete", 
  +            "source deleted successfully", 
  +            systemID, 
  +            RESULT_SUCCESS,
  +            ACTION_DELETE);
  +    }
  +
       public void recycle() {
           super.recycle();
       }
  @@ -647,7 +706,7 @@
                   // import the fragment
                   Node importNode = resource.importNode(fragment, true);
                   if ( path.equals("") ) {  // this is allowed in write
  -                    resource.appendChild(importNode);
  +                    resource.appendChild(importNode.getFirstChild());
                       message = "entire source overwritten";
   
                   } else {
  @@ -730,6 +789,19 @@
           String action = ACTION_NONE;
           if (!failed) { action = (exists) ? ACTION_OVER : ACTION_NEW; }
   
  +        this.reportResult(localSerializer, tagname, message, target, result, 
action);
  +
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("END insertFragment");
  +        }
  +    }
  +
  +    private void reportResult(String localSerializer, 
  +                                String tagname, 
  +                                String message, 
  +                                String target, 
  +                                String result, 
  +                                String action) throws SAXException {
           sendStartElementEvent(RESULT_ELEMENT);
               sendStartElementEvent(EXECUTION_ELEMENT);
                   sendTextEvent(result);
  @@ -752,10 +824,6 @@
                   sendEndElementEvent(SERIALIZER_ELEMENT);
               }
           sendEndElementEvent(RESULT_ELEMENT);
  -
  -        if (this.getLogger().isDebugEnabled() == true) {
  -            this.getLogger().debug("END insertFragment");
  -        }
       }
   
   
  
  
  
  1.2       +38 -2     
cocoon-2.1/src/documentation/xdocs/userdocs/transformers/sourcewriting-transformer.xml
  
  Index: sourcewriting-transformer.xml
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/documentation/xdocs/userdocs/transformers/sourcewriting-transformer.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- sourcewriting-transformer.xml     9 Mar 2003 00:08:27 -0000       1.1
  +++ sourcewriting-transformer.xml     28 Jul 2003 11:28:22 -0000      1.2
  @@ -13,7 +13,8 @@
        </header>
        <body>
                <s1 title="Source Writing Transformer">
  -                     <p>Diverts xml from a pipeline, writing it to a 
Source.</p>
  +                     <p>Diverts xml from a pipeline, writing it to a Source 
(or
  +      deleting it).</p>
                        <p>Thankfully, <code>FileSource</code> is no longer the 
only <code>Source</code> that currently implements <code>WritableSource</code>; 
there are implementations of WebDAV and Apache Slide WritableSources in the 
scratchpad. Hopefully further <code>ModifiableSource</code> implementations 
(XMLDB, CVS, Email, SQL, etc.) will be appear in the future.</p>
                        <ul>
                                <li>Name : write-source</li>
  @@ -39,10 +40,21 @@
                        [<source:replace/>]
                        [<source:reinsert/>]
                </source:insert>
  +
  +             <source:delete/>
  +                     <source:source/>
  +                     [<source:path/>] - Ignored
  +                     [<source:fragment/>] - Ignored
  +                     [<source:replace/>] - Ignored
  +                     [<source:reinsert/>] - Ignored
  +             </source:insert>
                                        ]]>
                                </source>
                        <p>In the namespace 
<code>xmlns:source="http://apache.org/cocoon/source/1.0";</code>.</p>
  -                     <p>The contents of the 
<code><![CDATA[<source:fragment/>]]></code> tag are written to the specified 
ModifiableSource when the document containing it is transformed by 
SourceWritingTransformer.</p>
  +                     <p>The contents of the 
<code><![CDATA[<source:fragment/>]]></code>
  +      tag are written to the specified ModifiableSource when the
  +      document containing it is transformed by SourceWritingTransformer
  +      (or deleted if you are using the <code>delete </code>instruction).</p>
                </s1>
                <s1 title="Definition">
                                <source>
  @@ -170,6 +182,16 @@
                                                <li>if 'reinsert' is specified 
and it does not exist, no action occurs.</li>
                                        </ul>
                        </s2>
  +      <s2 title="source:delete">
  +         <p>This instruction takes only a 
<code><![CDATA[<source:source/>]]></code>
  +         parameter (as a child tag) and deletes the corresponding
  +         source. All other <code>source:*</code> tags are ignored, if
  +         present: this allows for easy source-write instructions to be
  +         generated on the fly (e.g. by a stylesheet). Just change 
  +         <code>source:write</code> to <code>source:delete</code> and
  +         you're set.
  +         </p>
  +      </s2>
                </s1>
                
                <s1 title="Examples">
  @@ -251,6 +273,20 @@
                                        <p>This sample does not currently work, 
see the tests in the scratchpad at 
<code>http://localhost:8080/cocoon/mount/editor/tests</code>.</p>
                                        <note>You must have built Cocoon with 
the scratchpad included for this link to work.</note>
                        </s2>
  +                     <s2 title="Delete a source">
  +                                     <source>
  +                                             <![CDATA[
  + <page>
  +   ...
  +   <source:delete>
  +     <source:source>context://doc/editable/my.xml</source:source>
  +   <source:delete>
  +   ...
  + </page>
  +                                             ]]>
  +            </source>
  +
  +      </s2>
                        <s2 title="Sample of the output of these tags">
                                <p>This is the kind of information that the 
<code>SourceWritingTransformer</code> outputs to the pipeline, replacing the 
original <code>source:write</code> and <code>source:insert</code> tags</p>
                                        <source>
  
  
  
  1.96      +14 -1     cocoon-2.1/status.xml
  
  Index: status.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/status.xml,v
  retrieving revision 1.95
  retrieving revision 1.96
  diff -u -r1.95 -r1.96
  --- status.xml        20 Jul 2003 03:33:42 -0000      1.95
  +++ status.xml        28 Jul 2003 11:28:22 -0000      1.96
  @@ -189,6 +189,19 @@
     <changes>
   
    <release version="@version@" date="@date@">
  +  <action dev="GR" type="add">
  +    Added delete capabilities to the SourceWritingTransformer.
  +  </action>
  +  <action dev="GR" type="add" fixes-bug="21881" due-to="Guido Casper"
  +    due-to-email="[EMAIL PROTECTED]">
  +    Add a defaultContentType parameter to StreamGenerator, to comply
  +    with misbehaving clients.
  +  </action>  
  +  <action dev="GR" type="add" fixes-bug="21778" due-to="Guido Casper"
  +    due-to-email="[EMAIL PROTECTED]">
  +    Add a new set of WebDAV samples, with the capability of serving
  +    WebDAV content straight from Cocoon.
  +  </action>  
     <action dev="DC" type="fix" fixes-bug="21557" due-to="Conal Tuohy" 
due-to-email="[EMAIL PROTECTED]">
       Various fixes and enhancements to Lucene search. Propagate the lucene:*
       elements to the result tree and add "elapsed-time" attribute, so now
  
  
  

Reply via email to