cziegeler    02/05/07 01:17:46

  Modified:    src/documentation/xdocs/plan to-avalon.xml
               src/scratchpad/src/org/apache/cocoon/transformation
                        SourceWritingTransformer.java
  Log:
  Start merging SourceWritingTransformer and InsertTransformer
  
  Revision  Changes    Path
  1.3       +8 -8      xml-cocoon2/src/documentation/xdocs/plan/to-avalon.xml
  
  Index: to-avalon.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/src/documentation/xdocs/plan/to-avalon.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- to-avalon.xml     9 Apr 2002 06:37:55 -0000       1.2
  +++ to-avalon.xml     7 May 2002 08:17:46 -0000       1.3
  @@ -30,7 +30,7 @@
      <li>XMLFragment</li>
      <li>Parser (done)</li>
      <li>XMLSerializer/XMLDeserializer</li>
  -   <li>XSLTProcessor</li>
  +   <li>XSLTProcessor (done)</li>
     </ul>
   
     <p>Everything dealing with Source objects. (This is the part
  @@ -38,11 +38,11 @@
     </p>
   
     <ul>
  -   <li>SourceResolver</li>
  -   <li>SourceHandler</li>
  -   <li>SourceFactory</li>
  -   <li>Source</li>
  -   <li>ModifiableSource</li>
  +   <li>SourceResolver (done)</li>
  +   <li>SourceHandler (done)</li>
  +   <li>SourceFactory (done)</li>
  +   <li>Source (done)</li>
  +   <li>ModifiableSource (done)</li>
     </ul>
   
     <p>List of Implementations:</p>
  @@ -50,8 +50,8 @@
      <li>AbstractXMLConsumer</li>
      <li>JaxpParser, XercesParser (done)</li>
      <li>XMLByteStreamCompiler/XMLByteStreamInterpreter</li>
  -   <li>Everything dealing with Source objects</li>
  -   <li>XSLTProcessorImpl</li>
  +   <li>Everything dealing with Source objects (done)</li>
  +   <li>XSLTProcessorImpl (done)</li>
      <li><link href="catalog.html">Entity Catalogs </link>
          - the entity resolver (done)</li>
     </ul>
  
  
  
  1.4       +525 -347  
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/transformation/SourceWritingTransformer.java
  
  Index: SourceWritingTransformer.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/transformation/SourceWritingTransformer.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SourceWritingTransformer.java     22 Mar 2002 13:14:55 -0000      1.3
  +++ SourceWritingTransformer.java     7 May 2002 08:17:46 -0000       1.4
  @@ -63,16 +63,22 @@
   import org.apache.cocoon.serialization.Serializer;
   import org.apache.cocoon.caching.CacheValidity;
   import org.apache.cocoon.caching.Cacheable;
  -import org.apache.cocoon.environment.Source;
   import org.apache.cocoon.environment.SourceResolver;
   import org.apache.cocoon.environment.WriteableSource;
   import org.apache.cocoon.ProcessingException;
   import org.apache.cocoon.ResourceNotFoundException;
  +import org.apache.cocoon.webapps.session.connector.ResourceConnector;
  +import org.apache.cocoon.webapps.session.transformation.AbstractSessionTransformer;
  +import org.apache.cocoon.webapps.session.xml.XMLUtil;
   import org.apache.cocoon.xml.XMLConsumer;
  +import org.apache.cocoon.xml.XMLUtils;
  +import org.apache.excalibur.source.Source;
  +import org.apache.excalibur.source.SourceException;
  +import org.w3c.dom.*;
   import org.xml.sax.Attributes;
   import org.xml.sax.SAXException;
   import org.xml.sax.helpers.AttributesImpl;
  -import java.lang.SecurityException;
  +import java.io.File;
   import java.io.IOException;
   import java.io.OutputStream;
   import java.util.Map;
  @@ -119,11 +125,80 @@
    * &lt;/page&gt;
    * </pre>
    *
  + * <P>Inserting of XML fragments:</p>
  + * This implementation allows the inserting of an xml fragment into a
  + * source.
  + *
  + * <pre>
  + * &lt;page xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
  + *   ...
  + * &lt;source:insert&gt;
  + *   &lt;source:source&gt;The SRC&lt;/source:source&gt;
  + *   &lt;source:path&gt;XPath denoting the position to insert&lt;/source:path&gt;
  + *   &lt;source:fragment&gt;the xml fragment&lt;/source:fragment&gt;
  + * &lt;/source:insert&gt;
  + *   ...
  + * &lt;/page&gt;
  + * </pre>
  + *
  + * By default, the fragment is always inserted (added). It is possible to specify
  + * a node (by an XPath) which will be replaced if it exists.
  + * <pre>
  + * &lt;page xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
  + *   ...
  + * &lt;source:insert&gt;
  + *   &lt;source:source&gt;The SRC&lt;/source:source&gt;
  + *   &lt;source:path&gt;XPath denoting the position to insert&lt;/source:path&gt;
  + *   &lt;source:fragment&gt;the xml fragment&lt;/source:fragment&gt;
  + *   &lt;source:replace&gt;XPath denoting a criteria for which node will be 
replaced&lt;/source:replace>
  + * &lt;/source:insert&gt;
  + *   ...
  + * &lt;/page&gt;
  + * </pre>
  + *
  + * The information for <code>replace</code> has to be relative to path, but can
  + *  specify a subnode of the node the be replaced.
  + *
  + * The XPath specification is very complicated. So here is an example for the 
sitemap:
  + * <pre>
  + * &lt;page xmlns:source="http://apache.org/cocoon/source/1.0"&gt;
  + *   ...
  + * &lt;source:insert&gt;
  + *   &lt;source:source&gt;sitemap.xmap&lt;/source:source&gt;
  + *   &lt;source:path&gt;/*[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"]&lt;/source:path&gt;
  + *   &lt;source:fragment&gt;
  + *           <generator name="file" xmln="http://apache.org/cocoon/sitemap/1.0";>
  + *                   <test/>
  + *           </generator>
  + *   &lt;/source:fragment&gt;
  + *   &lt;source:replace&gt;*[namespace-uri()="http://apache.org/cocoon/sitemap/1.0"; 
and local-name()="generator" and attribute::name="file"]&lt;/source:replace&gt;
  + * &lt;/source:insert&gt;
  + *   ...
  + * &lt;/page&gt;
  + * </pre>
  + *
  + * 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.
  + *
  + * The &lt;session:reinsert&gt; option can be used to
  + * reinsert a replaced node at a given path in the new fragment.
  + *
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Carsten Ziegeler</a>
    * @author <a href="mailto:[EMAIL PROTECTED]";>Jeremy Quinn</a>
    *
    */
  -public class SourceWritingTransformer extends AbstractTransformer
  -    implements Disposable, Configurable, Composable {
  +public class SourceWritingTransformer
  +    extends AbstractSessionTransformer {
   
       private static String SWT_URI = "http://apache.org/cocoon/source/1.0";;
       private static String SWT_ELEMENT = "write";
  @@ -137,12 +212,33 @@
       private static String SWT_ACTION_NEW = "new";
       private static String SWT_ACTION_OVER = "overwritten";
   
  +    public static final String INSERT_ELEMENT = "insert";
  +    public static final String INSERT_CREATE_ATTRIBUTE = "create";
  +    public static final String INSERT_OVERWRITE_ATTRIBUTE = "overwrite";
   
  -    /** The <code>SourceResolver</code> */
  -    protected SourceResolver sourceResolver;
  +    public static final String PATH_ELEMENT = "path";
   
  -    /** The current <code>ComponentManager</code>. */
  -    protected ComponentManager manager = null;
  +    public static final String FRAGMENT_ELEMENT = "fragment";
  +
  +    public static final String REPLACE_ELEMENT = "replace";
  +
  +    public static final String FILE_ELEMENT = "file";
  +
  +    public static final String REINSERT_ELEMENT = "reinsert";
  +
  +    /** The current state */
  +    private static final int STATE_OUTSIDE  = 0;
  +    private static final int STATE_INSERT   = 1;
  +    private static final int STATE_RESOURCE = 2;
  +    private static final int STATE_PATH     = 3;
  +    private static final int STATE_FRAGMENT = 4;
  +    private static final int STATE_REPLACE  = 5;
  +    private static final int STATE_FILE     = 6;
  +    private static final int STATE_REINSERT = 7;
  +    private int state;
  +
  +    /** The configured serializer name */
  +    protected String configuredSerializerName;
   
       /** The ContentHandler instance */
       protected XMLConsumer ch;                   // is XMLConsumer suitable for this 
purpose?
  @@ -169,38 +265,28 @@
       /** Does the file exist, before we try to make it? */
       private boolean exists = false;
   
  -    /** True when inside &lt;write&gt; element. */
  -    private boolean processing;
  -
  -             /** the Source. */
  +    /** the Source. */
       private Source source = null;
   
  -             /** the WritableSource. */
  +        /** the WritableSource. */
       private WriteableSource wsource = null;
  -    
  -    
  -    public void WriteableSourceTransformer() {
  -    }
  -
   
       /**
  -     * Set the current <code>ComponentManager</code> instance used by this
  -     * <code>Composable</code>.
  +     * Constructor
  +     * Set the namespace
        */
  -    public void compose(ComponentManager manager) throws ComponentException {
  -       this.manager=manager; // We need this later to get the Serializer, if it is 
required
  +    public SourceWritingTransformer() {
  +        this.namespaceURI = SWT_URI;
       }
   
       /**
        * Get the current <code>Configuration</code> instance used by this
        * <code>Configurable</code>.
        */
  -    public void configure(Configuration configuration) throws 
ConfigurationException {
  -                     try {
  -                             this.serializer_name = 
configuration.getChild(SWT_SERIALIZER_ATTRIBUTE).getValue();
  -                     } catch (Exception e) {
  -                             getLogger().debug("Configuration - no serializer yet");
  -                     }
  +    public void configure(Configuration configuration)
  +    throws ConfigurationException {
  +        super.configure( configuration );
  +        this.configuredSerializerName = 
configuration.getChild(SWT_SERIALIZER_ATTRIBUTE).getValue(null);
       }
   
       /**
  @@ -209,37 +295,12 @@
        */
       public void setup(SourceResolver resolver, Map objectModel, String src, 
Parameters par)
       throws ProcessingException, SAXException, IOException {
  -                     this.sourceResolver = resolver; // save it for later, when we 
know the filepath to save to
  -                     this.serializer_name = 
par.getParameter(SWT_SERIALIZER_ATTRIBUTE, this.serializer_name);
  -                     if (this.serializer_name != null)
  -                             getLogger().debug("Setup, using serializer: " + 
this.serializer_name);
  -    }
  -
  -    /**
  -     * Begin the scope of a prefix-URI Namespace mapping.
  -     *
  -     * @param prefix The Namespace prefix being declared.
  -     * @param uri The Namespace URI the prefix is mapped to.
  -     */
  -    public void startPrefixMapping(String prefix, String uri) throws SAXException {
  -                     if (!this.processing) {
  -                             super.startPrefixMapping(prefix,uri);
  -                     } else if (this.ch != null){
  -                             this.ch.startPrefixMapping(prefix, uri);
  -                     }
  -    }
  -
  -    /**
  -     * End the scope of a prefix-URI mapping.
  -     *
  -     * @param prefix The prefix that was being mapping.
  -     */
  -    public void endPrefixMapping(String prefix) throws SAXException {
  -                     if (!this.processing) {
  -                             super.endPrefixMapping(prefix);
  -                     } else if (this.ch != null){
  -                             this.ch.endPrefixMapping(prefix);
  -                     }
  +        super.setup(resolver, objectModel, src, par);
  +        this.serializer_name = par.getParameter(SWT_SERIALIZER_ATTRIBUTE, 
this.configuredSerializerName);
  +        if (this.serializer_name != null && this.getLogger().isDebugEnabled() ) {
  +            this.getLogger().debug("Setup, using serializer: " + 
this.serializer_name);
  +        }
  +        this.state = STATE_OUTSIDE;
       }
   
       /**
  @@ -255,65 +316,121 @@
        * @param a The attributes attached to the element. If there are no
        *          attributes, it shall be an empty Attributes object.
        */
  -    public void startElement(String uri, String loc, String raw, Attributes a)
  -    throws SAXException {
  -                     if (!this.processing) {
  -                             if (SWT_URI.equals(uri) && SWT_ELEMENT.equals(loc)) {
  -                                     getLogger().debug("start processing 
xmlns:source");
  -                                     this.failed = false;
  -                                     this.message = null;
  -                                     this.target = "";
  -
  -                                     // look for the Source
  -                                     String src = a.getValue("",SWT_SRC_ATTRIBUTE);
  -                                     try {
  -                                             this.message = "The src attribute 
could not be resolved";
  -                                             this.source = 
this.sourceResolver.resolve(src);
  -                                             this.target = 
this.source.getSystemId();
  -                                             
  -                                             this.message = "The src attribute 
doesn't resolve to a writeable source";
  -                                             this.wsource = 
(WriteableSource)this.source;
  -                                             this.exists = this.wsource.exists();
  -                                             
  -                                             // has a Serializer been specified?
  -                                             String local_serializer = 
a.getValue("",SWT_SERIALIZER_ATTRIBUTE);
  -                                             if (local_serializer != null) 
this.serializer_name = local_serializer;
  -                                             if (this.serializer_name != null) {
  -                                                     // Lookup the Serializer
  -                                                     this.message = "that 
Serializer does not exist";
  -                                                     ComponentSelector selector = 
(ComponentSelector)manager.lookup(Serializer.ROLE + "Selector");
  -                                                     this.ch = 
(Serializer)selector.select(this.serializer_name);
  -                                                     this.message = "Could not open 
the source for writing";
  -                                                     this.os = 
this.wsource.getOutputStream();
  -                                                     this.message = "could not 
write the file";
  -                                                     
((Serializer)this.ch).setOutputStream(this.os);                 // Is there a way to 
avoid this casting?
  -                                                     this.isSerializer = true;
  -                                             } else {
  -                                                     this.message = "could not get 
a ContentHandler";
  -                                                     this.ch = 
(XMLConsumer)wsource.getContentHandler();
  -                                             }
  -                                     } catch (Exception e) {
  -                                             getLogger().warn("failed, " + 
this.message, e);
  -                                             this.failed = true;
  -                                             try {
  -                                                     this.wsource.cancel(this.ch);
  -                                             } catch (Exception e2) {
  -                                                     getLogger().warn("failed to 
cancel: " + this.target, e2);
  -                                                     this.message += " and failed 
to cancel";
  -                                             }
  -                                     }
  -                                     // start the document
  -                                     if (!this.failed) {
  -                                             this.ch.startDocument();
  -                                     }                                              
 
  -                                     this.processing = true;
  -                                     getLogger().debug("Processing Started");
  -                             } else {
  -                                     super.startElement(uri,loc,raw,a);
  -                             }
  -                     } else if (this.ch != null){
  -                             this.ch.startElement(uri,loc,raw,a);
  -                     }
  +    public void startTransformingElement(String uri, String name, String raw, 
Attributes attr)
  +    throws SAXException, IOException, ProcessingException {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("BEGIN startTransformingElement uri=" + uri +
  +                              ", name=" + name + ", raw=" + raw + ", attr=" + attr);
  +        }
  +        // Element: insert
  +        if (name.equals(INSERT_ELEMENT)
  +            && this.state == STATE_OUTSIDE) {
  +            state = STATE_INSERT;
  +            if (attr.getValue(INSERT_CREATE_ATTRIBUTE) != null
  +                && attr.getValue(INSERT_CREATE_ATTRIBUTE).equals("false")) {
  +                stack.push("false");
  +            } else {
  +                stack.push("true");
  +            }
  +            if (attr.getValue(INSERT_OVERWRITE_ATTRIBUTE) != null
  +                && attr.getValue(INSERT_OVERWRITE_ATTRIBUTE).equals("false")) {
  +                stack.push("false");
  +            } else {
  +                stack.push("true");
  +            }
  +            stack.push("INSERT");
  +
  +
  +        // Element: file
  +        } else if (name.equals(FILE_ELEMENT)
  +                   && this.state == STATE_INSERT) {
  +            state = STATE_FILE;
  +            this.startTextRecording();
  +
  +        // Element: path
  +        } else if (name.equals(PATH_ELEMENT)
  +                   && this.state == STATE_INSERT) {
  +            state = STATE_PATH;
  +            this.startTextRecording();
  +
  +        // Element: replace
  +        } else if (name.equals(REPLACE_ELEMENT)
  +                   && this.state == STATE_INSERT) {
  +            state = STATE_REPLACE;
  +            this.startTextRecording();
  +
  +        // Element: fragment
  +        } else if (name.equals(FRAGMENT_ELEMENT)
  +                   && this.state == STATE_INSERT) {
  +            state = STATE_FRAGMENT;
  +            this.startRecording();
  +
  +        // Element: reinsert
  +        } else if (name.equals(REINSERT_ELEMENT)
  +                   && this.state == STATE_INSERT) {
  +            state = STATE_REINSERT;
  +            this.startTextRecording();
  +
  +        } else if (name.equals(SWT_ELEMENT)) {
  +            this.failed = false;
  +            this.message = null;
  +            this.target = "";
  +
  +            // look for the Source
  +            String src = attr.getValue("",SWT_SRC_ATTRIBUTE);
  +            try {
  +                this.message = "The src attribute could not be resolved";
  +                this.source = this.resolver.resolveURI(src);
  +                this.target = this.source.getSystemId();
  +
  +                this.message = "The src attribute doesn't resolve to a writeable 
source";
  +                this.wsource = (WriteableSource)this.source;
  +                this.exists = this.wsource.exists();
  +
  +                // has a Serializer been specified?
  +                String local_serializer = 
attr.getValue("",SWT_SERIALIZER_ATTRIBUTE);
  +                if (local_serializer != null) this.serializer_name = 
local_serializer;
  +                if (this.serializer_name != null) {
  +                    // Lookup the Serializer
  +                    this.message = "that Serializer does not exist";
  +                    ComponentSelector selector = null;
  +                    try {
  +                        selector = 
(ComponentSelector)manager.lookup(Serializer.ROLE + "Selector");
  +                        this.ch = (Serializer)selector.select(this.serializer_name);
  +                        this.message = "Could not open the source for writing";
  +                        this.os = this.wsource.getOutputStream();
  +                        this.message = "could not write the file";
  +                        ((Serializer)this.ch).setOutputStream(this.os);             
         // Is there a way to avoid this casting?
  +                        this.isSerializer = true;
  +                    } finally {
  +                        this.manager.release( selector );
  +                    }
  +                } else {
  +                    this.message = "could not get a ContentHandler";
  +                    this.ch = (XMLConsumer)wsource.getContentHandler();
  +                }
  +                this.addRecorder( this.ch );
  +                this.startDocument();
  +                this.sendStartPrefixMapping();
  +
  +            } catch (Exception e) {
  +                getLogger().warn("failed, " + this.message, e);
  +                this.failed = true;
  +                try {
  +                    this.wsource.cancel(this.ch);
  +                } catch (Exception e2) {
  +                    getLogger().warn("failed to cancel: " + this.target, e2);
  +                    this.message += " and failed to cancel";
  +                }
  +            }
  +        // default
  +        } else {
  +            super.startTransformingElement(uri, name, raw, attr);
  +        }
  +
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("END startTransformingElement");
  +        }
       }
   
   
  @@ -328,239 +445,300 @@
        * @param raw The raw XML 1.0 name (with prefix), or the empty string if
        *            raw names are not available.
        */
  -    public void endElement(String uri, String loc, String raw)
  -    throws SAXException {
  -                     if (!this.processing) {
  -                             super.endElement(uri,loc,raw);
  -                     } else {
  -                             if (SWT_URI.equals(uri) && SWT_ELEMENT.equals(loc)){
  -                                     if (!this.failed) {
  -                                             this.ch.endDocument();
  -                                     }
  -                                     this.processing = false;
  -                                     getLogger().debug("Processing Ended");
  -                                     // close the OutputStream
  -                                     try {
  -                                             if (this.os != null) {
  -                                                     this.os.close();
  -                                                     this.os = null;
  -                                             }
  -                                             
  -                                     } catch(Exception e) {
  -                                             getLogger().warn("Failed to close 
source", e);
  -                                             this.message = "Failed to close 
source";
  -                                             this.failed = true;
  -                                             try {
  -                                                     this.message = "Failed to 
cancel source";
  -                                                     this.wsource.cancel(this.ch);
  -                                             } catch (Exception e2) {
  -                                                     getLogger().warn("failed to 
cancel: " + this.target, e2);
  -                                             }
  -                                     } finally {
  -                                             if (this.source != null) {
  -                                                     this.source.recycle();
  -                                             }
  -                                     }
  -                                     if (!this.failed) {
  -                                             this.wsource = null;
  -                                     }
  -                                     
  -                                     // Report result
  -                                     String result = (this.failed) ? 
SWT_RESULT_FAILED : SWT_RESULT_SUCCESS;
  -                                     String action = SWT_ACTION_NONE;
  -                                     if (!this.failed){
  -                                             if (this.exists) {
  -                                                     action = SWT_ACTION_OVER;
  -                                             } else {
  -                                                     action = SWT_ACTION_NEW;
  -                                             }
  -                                     }
  -                                     AttributesImpl attrs = new AttributesImpl();
  -                                     attrs.addAttribute(null, SWT_SRC_ATTRIBUTE, 
SWT_SRC_ATTRIBUTE, "CDATA", this.target);
  -                                     attrs.addAttribute(null, SWT_ACTION_ATTRIBUTE, 
SWT_ACTION_ATTRIBUTE, "CDATA", action);
  -                                     attrs.addAttribute(null, SWT_RESULT_ATTRIBUTE, 
SWT_RESULT_ATTRIBUTE, "CDATA", result);
  -                                     if (this.serializer_name != null) 
attrs.addAttribute(null, SWT_SERIALIZER_ATTRIBUTE, SWT_SERIALIZER_ATTRIBUTE, "CDATA", 
this.serializer_name);
  -                                     super.startElement(uri, loc, raw, attrs);
  -                                     if (this.message != null && this.failed == 
true) super.characters(this.message.toCharArray(), 0, this.message.length());
  -                                     super.endElement(uri, loc, raw);
  -                                     getLogger().debug("Source Written");
  -                             } else if (this.ch != null){
  -                                     this.ch.endElement(uri, loc, raw);
  -                             }
  -                     }
  -    }
  -
  -    /**
  -     * Receive notification of character data.
  -     *
  -     * @param c The characters from the XML document.
  -     * @param start The start position in the array.
  -     * @param len The number of characters to read from the array.
  -     */
  -    public void characters(char c[], int start, int len) throws SAXException {
  -                     if (!this.processing) {
  -                             super.characters(c,start,len);
  -                     } else if (this.ch != null){
  -                             this.ch.characters(c,start,len);
  -                     }
  -    }
  -
  -    /**
  -     * Receive notification of ignorable whitespace in element content.
  -     *
  -     * @param c The characters from the XML document.
  -     * @param start The start position in the array.
  -     * @param len The number of characters to read from the array.
  -     */
  -    public void ignorableWhitespace(char c[], int start, int len) throws 
SAXException {
  -                     if (!this.processing) {
  -                             super.ignorableWhitespace(c,start,len);
  -                     } else if (this.ch != null){
  -                             this.ch.ignorableWhitespace(c,start,len);
  -                     }
  -    }
  -
  -    /**
  -     * Receive notification of a processing instruction.
  -     *
  -     * @param target The processing instruction target.
  -     * @param data The processing instruction data, or null if none was
  -     *             supplied.
  -     */
  -    public void processingInstruction(String target, String data) throws 
SAXException {
  -                     if (!this.processing) {
  -                             super.processingInstruction(target,data);
  -                     } else if (this.ch != null){
  -                             this.ch.processingInstruction(target,data);
  -                     }
  -    }
  -
  -    /**
  -     * Receive notification of a skipped entity.
  -     *
  -     * @param name The name of the skipped entity.  If it is a  parameter
  -     *             entity, the name will begin with '%'.
  -     */
  -    public void skippedEntity(String name) throws SAXException {
  -                     if (!this.processing) {
  -                             super.skippedEntity(name);
  -                     } else if (this.ch != null){
  -                             this.ch.skippedEntity(name);
  -                     }
  -    }
  -
  -    /**
  -     * Report the start of DTD declarations, if any.
  -     *
  -     * @param name The document type name.
  -     * @param publicId The declared public identifier for the external DTD
  -     *                 subset, or null if none was declared.
  -     * @param systemId The declared system identifier for the external DTD
  -     *                 subset, or null if none was declared.
  -     */
  -                     public void startDTD(String name, String publicId, String 
systemId) throws SAXException {
  -                             if (!this.processing)
  -                                     super.startDTD(name,publicId,systemId);
  -    }
  -
  -    /**
  -     * Report the end of DTD declarations.
  -     */
  -    public void endDTD() throws SAXException {
  -                     if (!this.processing)
  -                             super.endDTD();
  -    }
  -
  -    /**
  -     * Report the beginning of an entity.
  -     *
  -     * @param name The name of the entity. If it is a parameter entity, the
  -     *             name will begin with '%'.
  -     */
  -    public void startEntity(String name) throws SAXException {
  -                     if (!this.processing) {
  -                             super.startEntity(name);
  -                     } else if (this.ch != null){
  -                             this.ch.startEntity(name);
  -                     }
  -    }
  -
  -    /**
  -     * Report the end of an entity.
  -     *
  -     * @param name The name of the entity that is ending.
  -     */
  -    public void endEntity(String name) throws SAXException {
  -                     if (!this.processing) {
  -                             super.endEntity(name);
  -                     } else if (this.ch != null){
  -                             this.ch.endEntity(name);
  -                     }
  -    }
  -
  -    /**
  -     * Report the start of a CDATA section.
  -     */
  -    public void startCDATA() throws SAXException {
  -                     if (!this.processing) {
  -                             super.startCDATA();
  -                     } else if (this.ch != null){
  -                             this.ch.startCDATA();
  -                     }
  -    }
  -
  -    /**
  -     * Report the end of a CDATA section.
  -     */
  -    public void endCDATA() throws SAXException {
  -                     if (!this.processing) {
  -                             super.endCDATA();
  -                     } else if (this.ch != null){
  -                             this.ch.endCDATA();
  -                     }
  -    }
  -
  -    /**
  -     * Report an XML comment anywhere in the document.
  -     *
  -     * @param ch An array holding the characters in the comment.
  -     * @param start The starting position in the array.
  -     * @param len The number of characters to use from the array.
  -     */
  -    public void comment(char ch[], int start, int len) throws SAXException {
  -                     if (!this.processing) {
  -                             super.comment(ch,start,len);
  -                     } else if (this.ch != null){
  -                             this.ch.comment(ch,start,len);
  -                     }
  +    public void endTransformingElement(String uri, String name, String raw)
  +    throws SAXException, IOException, ProcessingException {
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("BEGIN endTransformingElement uri=" + uri +
  +                              ", name=" + name +
  +                              ", raw=" + raw);
  +        }
  +        if (name.equals(INSERT_ELEMENT) == true && this.state == STATE_INSERT) {
  +            state = STATE_OUTSIDE;
  +
  +            // get the information from the stack
  +            String tag;
  +            String     fileName        = null;
  +            DocumentFragment fragment  = null;
  +            String     path            = null;
  +            String     replacePath     = null;
  +            String     reinsert        = null;
  +            do {
  +                tag = (String)stack.pop();
  +                if (tag.equals("PATH") == true) {
  +                    path = (String)stack.pop();
  +                } else if (tag.equals("FILE") == true) {
  +                    fileName = (String)stack.pop();
  +                } else if (tag.equals("FRAGMENT") == true) {
  +                    fragment = (DocumentFragment)stack.pop();
  +                } else if (tag.equals("REPLACE") == true) {
  +                    replacePath = (String)stack.pop();
  +                } else if (tag.equals("REINSERT") == true) {
  +                    reinsert = (String)stack.pop();
  +                }
  +            } while (tag.equals("INSERT") == false);
  +            final boolean overwrite = stack.pop().equals("true");
  +            final boolean create = stack.pop().equals("true");
  +
  +            /**this.insertFragment(fileName,
  +                                    path,
  +                                    fragment,
  +                                    replacePath,
  +                                    create,
  +                                    overwrite,
  +                                    reinsert);
  +             */
  +        // Element: file
  +        } else if (name.equals(FILE_ELEMENT) == true && this.state == STATE_FILE) {
  +            state = STATE_INSERT;
  +            stack.push(this.endTextRecording());
  +            stack.push("FILE");
  +
  +        // Element: path
  +        } else if (name.equals(PATH_ELEMENT) == true && this.state == STATE_PATH) {
  +            state = STATE_INSERT;
  +            stack.push(this.endTextRecording());
  +            stack.push("PATH");
  +
  +        // Element: replace
  +        } else if (name.equals(REPLACE_ELEMENT) == true && this.state == 
STATE_REPLACE) {
  +            state = STATE_INSERT;
  +            stack.push(this.endTextRecording());
  +            stack.push("REPLACE");
  +
  +        // Element: fragment
  +        } else if (name.equals(FRAGMENT_ELEMENT) == true && this.state == 
STATE_FRAGMENT) {
  +            state = STATE_INSERT;
  +            stack.push(this.endRecording());
  +            stack.push("FRAGMENT");
  +
  +        // Element: reinsert
  +        } else if (name.equals(REINSERT_ELEMENT) == true
  +                   && this.state == STATE_REINSERT) {
  +            state = STATE_INSERT;
  +            stack.push(this.endTextRecording());
  +            stack.push("REINSERT");
  +
  +        } else if (name.equals(SWT_ELEMENT)) {
  +            if (!this.failed) {
  +                this.sendEndPrefixMapping();
  +                this.endDocument();
  +                this.removeRecorder();
  +                // close the OutputStream
  +                try {
  +                    if (this.os != null) {
  +                        this.os.close();
  +                        this.os = null;
  +                    }
  +
  +                } catch(Exception e) {
  +                    getLogger().warn("Failed to close source", e);
  +                    this.message = "Failed to close source";
  +                    this.failed = true;
  +                    try {
  +                        this.message = "Failed to cancel source";
  +                        this.wsource.cancel(this.ch);
  +                    } catch (Exception e2) {
  +                        getLogger().warn("failed to cancel: " + this.target, e2);
  +                    }
  +                } finally {
  +                    if (this.source != null) {
  +                        this.resolver.release( this.source );
  +                        this.source = null;
  +                    }
  +                }
  +                if (!this.failed) {
  +                    this.wsource = null;
  +                }
  +
  +                // Report result
  +                String result = (this.failed) ? SWT_RESULT_FAILED : 
SWT_RESULT_SUCCESS;
  +                String action = SWT_ACTION_NONE;
  +                if (!this.failed){
  +                    if (this.exists) {
  +                        action = SWT_ACTION_OVER;
  +                    } else {
  +                        action = SWT_ACTION_NEW;
  +                    }
  +                }
  +                AttributesImpl attrs = new AttributesImpl();
  +                attrs.addAttribute(null, SWT_SRC_ATTRIBUTE, SWT_SRC_ATTRIBUTE, 
"CDATA", this.target);
  +                attrs.addAttribute(null, SWT_ACTION_ATTRIBUTE, 
SWT_ACTION_ATTRIBUTE, "CDATA", action);
  +                attrs.addAttribute(null, SWT_RESULT_ATTRIBUTE, 
SWT_RESULT_ATTRIBUTE, "CDATA", result);
  +                if (this.serializer_name != null) attrs.addAttribute(null, 
SWT_SERIALIZER_ATTRIBUTE, SWT_SERIALIZER_ATTRIBUTE, "CDATA", this.serializer_name);
  +                super.startElement(uri, name, raw, attrs);
  +                if (this.message != null && this.failed == true) 
super.characters(this.message.toCharArray(), 0, this.message.length());
  +                super.endElement(uri, name, raw);
  +                getLogger().debug("Source Written");
  +            }
  +        // default
  +        } else {
  +            super.endTransformingElement(uri, name, raw);
  +        }
  +
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("END endTransformingElement");
  +        }
       }
   
       public void recycle() {
  -     if (this.wsource != null) {
  -                             getLogger().error("cancelled by recycle() method");
  -                             if (this.os != null) {
  -                                     try {
  -                                             this.wsource.cancel(this.os);
  -                                     } catch (Exception e) {
  -                                             getLogger().error("failed to cancel in 
recycle() method: OutputStream");
  -                                     }
  -                             } else if (this.ch != null) {
  -                                     try {
  -                                             this.wsource.cancel(this.ch);
  -                                     } catch (Exception e) {
  -                                             getLogger().error("failed to cancel in 
recycle() method: ContentHandler");
  -                                     }
  -                             }
  -     }
  -
  -                     if (isSerializer) this.manager.release((Component)this.ch);
  -      this.sourceResolver = null;
  +        if (this.wsource != null) {
  +            getLogger().error("cancelled by recycle() method");
  +            if (this.os != null) {
  +                try {
  +                    this.wsource.cancel(this.os);
  +                } catch (Exception e) {
  +                    getLogger().error("failed to cancel in recycle() method: 
OutputStream");
  +                }
  +            } else if (this.ch != null) {
  +                try {
  +                    this.wsource.cancel(this.ch);
  +                } catch (Exception e) {
  +                    getLogger().error("failed to cancel in recycle() method: 
ContentHandler");
  +                }
  +            }
  +        }
  +        if (this.source != null) {
  +            this.resolver.release( this.source );
  +            this.source = null;
  +        }
  +
  +        if (isSerializer) this.manager.release((Component)this.ch);
  +        this.ch = null;
  +        super.recycle();
  +    }
  +
  +    /**
  +     * Insert a fragment into a file.
  +     * The file is loaded by the resource connector.
  +     *
  +     * @param fileName The name of the xml file.
  +     * @param path   The XPath specifying the node under which the data is inserted
  +     * @param fragment The data to be inserted.
  +     * @param replacePath Optional XPath relative to <CODE>path</CODE>. This path
  +     *                    can specify a node which will be removed if it exists.
  +     *                    So insertFragment can be used as a replace utility.
  +     * @param create      If the file does not exists and this is set to
  +     *                    <CODE>false</CODE> nothing is inserted. If it is set
  +     *                    to <CODE>true</CODE> the file is created and the data
  +     *                    is inserted.
  +     * @param overwrite   If this is set to <CODE>true</CODE> the data is only
  +     *                    inserted if the node specified by the 
<CODE>replacePath</CODE>
  +     *                    does not exists.
  +     * @param reinsertPath If specified and a node is replaced , all children of
  +     *                     this replaced node will be reinserted at the given path.
  +     */
  +    public void insertFragment(String fileName,
  +                               String path,
  +                               DocumentFragment fragment,
  +                               String replacePath,
  +                               boolean create,
  +                               boolean overwrite,
  +                               String  reinsertPath)
  +    throws SAXException, IOException, ProcessingException {
  +        // no sync req
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("BEGIN insertFragment fileName="+fileName+
  +                ", path="+path+
  +                ", replace="+replacePath+
  +                ", create="+create+
  +                ", overwrite="+overwrite+
  +                ", resinsert="+reinsertPath+
  +                ", fragment="+(fragment == null ? "null" : 
XMLUtils.serializeNodeToXML(fragment)));
  +        }
  +        // test parameter
  +        if (fileName == null) {
  +            throw new ProcessingException("insertFragment: file name is required.");
  +        }
  +        if (path == null) {
  +            throw new ProcessingException("insertFragment: path is required.");
  +        }
  +        if (fragment == null) {
  +            throw new ProcessingException("insertFragment: fragment is required.");
  +        }
  +
  +        Source fileSource = null;
  +        String systemId = null;
  +        try {
  +            fileSource = this.resolver.resolveURI( fileName );
  +            systemId = fileSource.getSystemId();
  +            if (systemId.startsWith("file:") == false) {
  +                throw new ProcessingException("insertFragment: this is not a file: 
" + systemId);
  +            }
  +        } catch (SourceException se) {
  +            throw new ProcessingException("Error during resolving.", se);
  +        } finally {
  +            if (fileSource != null) this.resolver.release(fileSource);
  +        }
  +        if (path.startsWith("/") == true) path = path.substring(1);
  +
  +        File file = new File(systemId.substring(5));
  +        DocumentFragment resource = null;
  +        if (file.exists() == true) {
  +            resource = 
this.getResourceConnector().loadXML(ResourceConnector.RESOURCE_TYPE_FILE, null,
  +                                                           fileName, null);
  +
  +            // import the fragment
  +            Node importNode = resource.getOwnerDocument().importNode(fragment, 
true);
  +
  +            // get the node
  +            Node parent = XMLUtil.selectSingleNode(resource, path);
  +
  +            // replace?
  +            if (replacePath != null) {
  +                try {
  +                    Node replaceNode = XMLUtil.getSingleNode(parent, replacePath);
  +
  +                    // now get the parent of this node until it is the parent node 
for insertion
  +                    while (replaceNode != null && 
replaceNode.getParentNode().equals(parent) == false) {
  +                       replaceNode = replaceNode.getParentNode();
  +                    }
  +                    if (replaceNode != null) {
  +                        if (overwrite == true) {
  +                            parent.replaceChild(importNode, replaceNode);
  +                            if (reinsertPath != null) {
  +                                Node insertAt = XMLUtil.getSingleNode(importNode, 
reinsertPath);
  +                                if (insertAt != null) {
  +                                    while (replaceNode.hasChildNodes() == true) {
  +                                        
insertAt.appendChild(replaceNode.getFirstChild());
  +                                    }
  +                                }
  +                            }
  +                        }
  +                    } else {
  +                        parent.appendChild(importNode);
  +                    }
  +                } catch (javax.xml.transform.TransformerException sax) {
  +                    throw new ProcessingException("TransformerException: " + sax, 
sax);
  +                }
  +            } else { // no replace
  +                parent.appendChild(importNode);
  +            }
  +        } else {
  +            if (create == true) {
  +                Document doc = XMLUtil.createDocument();
  +                resource = doc.createDocumentFragment();
  +                // import the fragment
  +                Node importNode = resource.getOwnerDocument().importNode(fragment, 
true);
  +                // get the node
  +                Node parent = XMLUtil.selectSingleNode(resource, path);
  +                // add fragment
  +                parent.appendChild(importNode);
  +            }
  +        }
  +
  +        if (resource != null) {
  +            // finally: save resource
  +            resource.normalize();
  +            
this.getResourceConnector().saveXML(ResourceConnector.RESOURCE_TYPE_FILE, null,
  +                                                fileName, null,
  +                                                resource);
  +        }
  +
  +        if (this.getLogger().isDebugEnabled() == true) {
  +            this.getLogger().debug("END insertFragment");
  +        }
       }
   
  -    /**
  -     * dispose
  -     */
  -    public void dispose() {
  -    }
  +
   
   }
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     [EMAIL PROTECTED]
To unsubscribe, e-mail:          [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to