jeremy 2002/07/01 01:53:39
Modified: src/java/org/apache/cocoon/transformation
SourceWritingTransformer.java
Log:
unified the tags style, response and implementation of source:write and
source:insert tags
Revision Changes Path
1.5 +326 -304
xml-cocoon2/src/java/org/apache/cocoon/transformation/SourceWritingTransformer.java
Index: SourceWritingTransformer.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/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 28 Jun 2002 07:14:36 -0000 1.4
+++ SourceWritingTransformer.java 1 Jul 2002 08:53:39 -0000 1.5
@@ -86,7 +86,8 @@
import java.util.Properties;
/**
- * This transformer allows you to output to a WritableSource.
+/**
+ * This transformer allows you to output to a WriteableSource.
*
* <p>Definition:</p>
* <pre>
@@ -98,67 +99,111 @@
* <p>Invocation:</p>
* <pre>
* <map:transform type="tofile">
- * <map:parameter name="serializer" value="xml"/>
+ * <map:parameter name="serializer" value="xml"/> <!-- you can
optionally override the serializer here -->
* </map:transform>
* </pre>
*
- * <p>Input XML document example:</p>
+ * <p>The Tags:</p>
* <pre>
- * <page xmlns:source="http://apache.org/cocoon/source/1.0">
+ * <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>
+ * </pre>
+ *
+ *
+ * <p>Input XML document example (write):</p>
+ * <pre>
+ * <page>
* ...
- * <source:write src="context://doc/editable/my.xml">
- * <page>
- * XML Object body
- * </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>
* </pre>
*
- * <p>Output XML document example:</p>
+ * <p>Input XML document example (insert at end):</p>
* <pre>
- * <page xmlns:source="http://apache.org/cocoon/source/1.0">
+ * <page>
* ...
- * <source:write src="/source/specific/path/to/context/doc/editable/my.xml"
result="success|failure" action="new">
- * source specific error message
- * </source:write>
+ * <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>
* </pre>
*
- * <P>Inserting of XML fragments:</p>
- * This implementation allows the inserting of an xml fragment into a
- * source.
+ * <p>Input XML document example (insert at beginning):</p>
+ * <pre>
+ * <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>
+ * </pre>
*
+ * <p>Input XML document example (replace):</p>
* <pre>
- * <page xmlns:source="http://apache.org/cocoon/source/1.0">
+ * <page>
* ...
- * <source:insert>
- * <source:source>The SRC</source:source>
- * <source:path>XPath denoting the position to insert</source:path>
- * <source:fragment>the xml fragment</source:fragment>
- * </source:insert>
+ * <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>
* </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.
+ * <p>Output XML document example:</p>
* <pre>
- * <page xmlns:source="http://apache.org/cocoon/source/1.0">
+ * <page>
* ...
- * <source:insert>
- * <source:source>The SRC</source:source>
- * <source:path>XPath denoting the position to insert</source:path>
- * <source:fragment>the xml fragment</source:fragment>
- * <source:replace>XPath denoting a criteria for which node will be
replaced</source:replace>
- * </source:insert>
+ * <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>
* </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>
@@ -168,9 +213,9 @@
* <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>
+ * <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>
@@ -178,23 +223,35 @@
* </page>
* </pre>
*
- * This insert replaces (if it exists) the file generator definition with a new one.
+ * <p>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...
+ * are used! Otherwise a node with the name * would be created...</p>
*
- * The create attribute of insert. If this is set
+ * <p>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.
+ * create is only usable for files!</p>
+ * <p>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 node is not inserted if the replace node is available.</p>
*
- * The <session:reinsert> option can be used to
+ * <p>[JQ] - the way I understand this, looking at the code:
+ * <pre>
+ * 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.
+ * </pre></p>
+ *
+ * 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.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Jeremy Quinn</a>
@@ -203,32 +260,34 @@
public class SourceWritingTransformer
extends AbstractSAXTransformer {
- private static String SWT_URI = "http://apache.org/cocoon/source/1.0";
- private static String SWT_ELEMENT = "write";
- private static String SWT_RESULT_ATTRIBUTE= "result";
- private static String SWT_SRC_ATTRIBUTE = "src";
- private static String SWT_ACTION_ATTRIBUTE = "action";
- private static String SWT_SERIALIZER_ATTRIBUTE = "serializer";
- private static String SWT_RESULT_FAILED = "failed";
- private static String SWT_RESULT_SUCCESS = "success";
- private static String SWT_ACTION_NONE = "none";
- private static String SWT_ACTION_NEW = "new";
- private static String SWT_ACTION_OVER = "overwritten";
-
+ public static final String SWT_URI = "http://apache.org/cocoon/source/1.0";
+ public static final String DEFAULT_SERIALIZER = "xml";
+
+ /** incoming elements */
+ public static final String WRITE_ELEMENT = "write";
public static final String INSERT_ELEMENT = "insert";
- public static final String INSERT_CREATE_ATTRIBUTE = "create";
- public static final String INSERT_OVERWRITE_ATTRIBUTE = "overwrite";
-
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 SOURCE_ELEMENT = "source";
-
public static final String REINSERT_ELEMENT = "reinsert";
-
+ /** outgoing elements */
+ public static final String RESULT_ELEMENT = "sourceResult";
+ public static final String EXECUTION_ELEMENT = "execution";
+ public static final String BEHAVIOUR_ELEMENT = "behaviour";
+ public static final String ACTION_ELEMENT = "action";
+ public static final String MESSAGE_ELEMENT = "message";
+ public static final String SERIALIZER_ELEMENT = "serializer";
+ /** main (write or insert) tag attributes */
+ public static final String SERIALIZER_ATTRIBUTE = "serializer";
+ public static final String CREATE_ATTRIBUTE = "create";
+ public static final String OVERWRITE_ATTRIBUTE = "overwrite";
+ /** results */
+ public static final String RESULT_FAILED = "failed";
+ public static final String RESULT_SUCCESS = "success";
+ public static final String ACTION_NONE = "none";
+ public static final String ACTION_NEW = "new";
+ public static final String ACTION_OVER = "overwritten";
/** The current state */
private static final int STATE_OUTSIDE = 0;
private static final int STATE_INSERT = 1;
@@ -238,41 +297,13 @@
private static final int STATE_REPLACE = 5;
private static final int STATE_FILE = 6;
private static final int STATE_REINSERT = 7;
+ private static final int STATE_WRITE = 8;
private int state;
+ private int parent_state;
/** The configured serializer name */
protected String configuredSerializerName;
- /** The ContentHandler instance */
- protected XMLConsumer ch; // is XMLConsumer suitable for this
purpose?
-
-
- /** Are we using a Serializer? */
- private boolean isSerializer = false;
-
- /** Current Serializer name. */
- private String serializer_name = null;
-
- /** Current target name. */
- private String target = null;
-
- /** Current OutputStream. */
- private OutputStream os = null;
-
- /** Current status of outputting the file. */
- private boolean failed = true;
-
- /** Current error message. */
- private String message = null;
-
- /** Does the file exist, before we try to make it? */
- private boolean exists = false;
-
- /** the Source. */
- private Source source = null;
-
- /** the WritableSource. */
- private WriteableSource wsource = null;
/**
* Constructor
@@ -289,7 +320,7 @@
public void configure(Configuration configuration)
throws ConfigurationException {
super.configure( configuration );
- this.configuredSerializerName =
configuration.getChild(SWT_SERIALIZER_ATTRIBUTE).getValue("xml");
+ this.configuredSerializerName =
configuration.getChild(SERIALIZER_ATTRIBUTE).getValue(DEFAULT_SERIALIZER);
}
/**
@@ -299,10 +330,7 @@
public void setup(SourceResolver resolver, Map objectModel, String src,
Parameters par)
throws ProcessingException, SAXException, IOException {
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.configuredSerializerName = par.getParameter(SERIALIZER_ATTRIBUTE,
this.configuredSerializerName);
this.state = STATE_OUTSIDE;
}
@@ -329,30 +357,51 @@
if (name.equals(INSERT_ELEMENT)
&& this.state == STATE_OUTSIDE) {
this.state = STATE_INSERT;
- if (attr.getValue(INSERT_CREATE_ATTRIBUTE) != null
- && attr.getValue(INSERT_CREATE_ATTRIBUTE).equals("false")) {
+ this.parent_state = STATE_INSERT;
+ if (attr.getValue(CREATE_ATTRIBUTE) != null
+ && attr.getValue(CREATE_ATTRIBUTE).equals("false")) {
this.stack.push("false");
} else {
this.stack.push("true");
}
- if (attr.getValue(INSERT_OVERWRITE_ATTRIBUTE) != null
- && attr.getValue(INSERT_OVERWRITE_ATTRIBUTE).equals("false")) {
+ if (attr.getValue(OVERWRITE_ATTRIBUTE) != null
+ && attr.getValue(OVERWRITE_ATTRIBUTE).equals("false")) {
this.stack.push("false");
} else {
this.stack.push("true");
}
+ this.stack.push(attr.getValue(SERIALIZER_ATTRIBUTE));
this.stack.push("INSERT");
+ // Element: write
+ } else if (name.equals(WRITE_ELEMENT)
+ && this.state == STATE_OUTSIDE) {
+ this.state = STATE_WRITE;
+ this.parent_state = STATE_WRITE;
+ if (attr.getValue(CREATE_ATTRIBUTE) != null
+ && attr.getValue(CREATE_ATTRIBUTE).equals("false")) {
+ this.stack.push("false");
+ } else {
+ this.stack.push("true"); // default value
+ }
+ if (attr.getValue(OVERWRITE_ATTRIBUTE) != null
+ && attr.getValue(OVERWRITE_ATTRIBUTE).equals("false")) {
+ this.stack.push("false");
+ } else {
+ this.stack.push("true"); // default value
+ }
+ this.stack.push(attr.getValue(SERIALIZER_ATTRIBUTE));
+ this.stack.push("WRITE");
// Element: file
} else if (name.equals(SOURCE_ELEMENT)
- && this.state == STATE_INSERT) {
+ && (this.state == STATE_INSERT || this.state == STATE_WRITE)) {
this.state = STATE_FILE;
this.startTextRecording();
// Element: path
} else if (name.equals(PATH_ELEMENT)
- && this.state == STATE_INSERT) {
+ && (this.state == STATE_INSERT || this.state == STATE_WRITE)) {
this.state = STATE_PATH;
this.startTextRecording();
@@ -364,7 +413,7 @@
// Element: fragment
} else if (name.equals(FRAGMENT_ELEMENT)
- && this.state == STATE_INSERT) {
+ && (this.state == STATE_INSERT || this.state == STATE_WRITE)) {
this.state = STATE_FRAGMENT;
this.startRecording();
@@ -374,63 +423,6 @@
this.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)((WriteableSAXSource)wsource).getContentHandler();
- }
- this.addRecorder( this.ch );
- this.startDocument();
- this.sendStartPrefixMapping();
-
- } catch (Exception e) {
- getLogger().warn("failed, " + this.message, e);
- this.failed = true;
- try {
- if (this.isSerializer) {
- this.wsource.cancel(this.os);
- } else {
- ((WriteableSAXSource)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);
}
@@ -460,7 +452,6 @@
", raw=" + raw);
}
if (name.equals(INSERT_ELEMENT) == true && this.state == STATE_INSERT) {
- this.state = STATE_OUTSIDE;
// get the information from the stack
String tag;
@@ -483,10 +474,45 @@
reinsert = (String)this.stack.pop();
}
} while (tag.equals("INSERT") == false);
+ final String localSerializer = (String)this.stack.pop();
+ final boolean overwrite = this.stack.pop().equals("true");
+ final boolean create = this.stack.pop().equals("true");
+
+ this.insertFragment(fileName,
+ path,
+ fragment,
+ replacePath,
+ create,
+ overwrite,
+ reinsert,
+ localSerializer,
+ name);
+
+ this.state = STATE_OUTSIDE;
+
+ } else if (name.equals(WRITE_ELEMENT) == true && this.state == STATE_WRITE)
{
+
+ // get the information from the stack
+ String tag;
+ String fileName = null;
+ DocumentFragment fragment = null;
+ String path = "/"; // source:write's path can be empty
+ String replacePath = null;
+ String reinsert = null;
+ do {
+ tag = (String)this.stack.pop();
+ if (tag.equals("PATH") == true) {
+ path = (String)this.stack.pop();
+ } else if (tag.equals("FILE") == true) {
+ fileName = (String)this.stack.pop();
+ } else if (tag.equals("FRAGMENT") == true) {
+ fragment = (DocumentFragment)this.stack.pop();
+ }
+ } while (tag.equals("WRITE") == false);
+ final String localSerializer = (String)this.stack.pop();
final boolean overwrite = this.stack.pop().equals("true");
final boolean create = this.stack.pop().equals("true");
- // FIXME (CZ) : Overriding of serializer is not implemented yet!
this.insertFragment(fileName,
path,
fragment,
@@ -494,97 +520,41 @@
create,
overwrite,
reinsert,
- null);
+ localSerializer,
+ name);
+
+ this.state = STATE_OUTSIDE;
// Element: file
} else if (name.equals(SOURCE_ELEMENT) == true && this.state == STATE_FILE)
{
- this.state = STATE_INSERT;
+ this.state = this.parent_state;
this.stack.push(this.endTextRecording());
this.stack.push("FILE");
// Element: path
} else if (name.equals(PATH_ELEMENT) == true && this.state == STATE_PATH) {
- this.state = STATE_INSERT;
+ this.state = this.parent_state;
this.stack.push(this.endTextRecording());
this.stack.push("PATH");
// Element: replace
} else if (name.equals(REPLACE_ELEMENT) == true && this.state ==
STATE_REPLACE) {
- this.state = STATE_INSERT;
+ this.state = this.parent_state;
this.stack.push(this.endTextRecording());
this.stack.push("REPLACE");
// Element: fragment
} else if (name.equals(FRAGMENT_ELEMENT) == true && this.state ==
STATE_FRAGMENT) {
- this.state = STATE_INSERT;
+ this.state = this.parent_state;
this.stack.push(this.endRecording());
this.stack.push("FRAGMENT");
// Element: reinsert
- } else if (name.equals(REINSERT_ELEMENT) == true
- && this.state == STATE_REINSERT) {
- this.state = STATE_INSERT;
+ } else if (name.equals(REINSERT_ELEMENT) == true && this.state ==
STATE_REINSERT) {
+ this.state = this.parent_state;
this.stack.push(this.endTextRecording());
this.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";
- if (this.isSerializer) {
- this.wsource.cancel(this.os);
- } else {
- ((WriteableSAXSource)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.contentHandler.startElement(uri, name, raw, attrs);
- if (this.message != null && this.failed == true)
super.characters(this.message.toCharArray(), 0, this.message.length());
- super.contentHandler.endElement(uri, name, raw);
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug("Source Written");
- }
- }
// default
} else {
super.endTransformingElement(uri, name, raw);
@@ -596,29 +566,6 @@
}
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 {
- ((WriteableSAXSource)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();
}
@@ -641,7 +588,8 @@
* 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.
- * @param serializer The serializer used to serialize the XML
+ * @param localSerializer The serializer used to serialize the XML
+ * @param tagname The name of the tag that triggered me 'insert' or 'write'
*/
protected void insertFragment(String systemID,
String path,
@@ -650,7 +598,8 @@
boolean create,
boolean overwrite,
String reinsertPath,
- String localSerializer)
+ String localSerializer,
+ String tagname)
throws SAXException, IOException, ProcessingException {
// no sync req
if (this.getLogger().isDebugEnabled() == true) {
@@ -677,18 +626,23 @@
// first: read the source as a DOM
Source source = null;
Document resource = null;
+ boolean failed = true;
+ boolean exists = false;
+ String message = "";
+ String target = systemID;
try {
source = this.resolver.resolveURI( systemID );
if ( ! (source instanceof WriteableSource)) {
throw new ProcessingException("Source '"+systemID+"' is not
writeable.");
}
WriteableSource ws = (WriteableSource)source;
- if ( ws.exists() ) {
-
+ exists = ws.exists();
+ target = source.getSystemId();
+ if ( exists == true && this.state == STATE_INSERT ) {
+ message = "content
inserted at: " + path;
resource = SourceUtil.toDOM( source, this.manager );
// import the fragment
Node importNode = resource.importNode(fragment, true);
-
// get the node
Node parent = XMLUtil.selectSingleNode(resource, path);
@@ -696,96 +650,164 @@
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);
+
parent.replaceChild(importNode, replaceNode);
+
message += ", replacing: " + replacePath;
if (reinsertPath != null) {
Node insertAt =
XMLUtil.getSingleNode(importNode, reinsertPath);
if (insertAt != null) {
while (replaceNode.hasChildNodes() == true)
{
insertAt.appendChild(replaceNode.getFirstChild());
}
+ } else { // reinsert point null
+
message = "replace
failed, could not find your reinsert path: " + reinsertPath;
+
resource = null;
}
}
+ } else { // overwrite was false
+ message = "replace failed, no overwrite allowed.";
+ resource = null;/**/
}
- } else {
+ } else { // specified replaceNode was not found
parent.appendChild(importNode);
}
} catch (javax.xml.transform.TransformerException sax) {
throw new ProcessingException("TransformerException: " +
sax, sax);
}
- } else { // no replace
+ } else { // no replace path, just do an insert at end
parent.appendChild(importNode);
}
} else if (create == true) {
-
- Parser parser = (Parser)this.manager.lookup(Parser.ROLE);
- try {
- resource = parser.createDocument();
- } finally {
- this.manager.release( parser );
- }
-
- // import the fragment
- Node importNode = resource.importNode(fragment, true);
- // get the node
- Node parent = XMLUtil.selectSingleNode(resource, path);
- // add fragment
- parent.appendChild(importNode);
+ Parser parser =
(Parser)this.manager.lookup(Parser.ROLE);
+ try {
+
resource = parser.createDocument();
+ } finally {
+
this.manager.release( parser );
+ }
+ // import the fragment
+ Node importNode =
resource.importNode(fragment, true);
+ if ( path.equals("") )
{ // this is allowed in write
+
resource.appendChild(importNode);
+ message =
"entire source overwritten";
+
+ } else {
+ // get the node
+ Node parent =
XMLUtil.selectSingleNode(resource, path);
+ // add fragment
+
parent.appendChild(importNode);
+ message =
"content appended to: " + path;
+ }
+ } else {
+ message = "create not allowed";
+ resource = null;/**/
}
// write source
if ( resource != null) {
resource.normalize();
-
if (source instanceof WriteableSAXSource) {
ContentHandler contentHandler =
((WriteableSAXSource)ws).getContentHandler();
DOMStreamer streamer = new DOMStreamer(contentHandler);
streamer.stream(resource);
+ localSerializer = "null";
+ failed = false;
} else {
// use serializer
if (localSerializer == null) localSerializer =
this.configuredSerializerName;
if (localSerializer != null) {
- // Lookup the Serializer
- ComponentSelector selector = null;
- Serializer serializer = null;
- OutputStream oStream = null;
- try {
- selector =
(ComponentSelector)manager.lookup(Serializer.ROLE + "Selector");
- serializer =
(Serializer)selector.select(localSerializer);
- oStream = ws.getOutputStream();
- serializer.setOutputStream(oStream);
- DOMStreamer streamer = new DOMStreamer(serializer);
- streamer.stream(resource);
- } finally {
- if (oStream != null) {
- try {
- oStream.flush();
- oStream.close();
- } catch (Exception ignore) {}
- }
- if ( selector != null ) {
- selector.release( serializer );
- this.manager.release( selector );
- }
- }
+
// Lookup the Serializer
+
ComponentSelector selector = null;
+
Serializer serializer = null;
+
OutputStream oStream = null;
+
try {
+
selector = (ComponentSelector)manager.lookup(Serializer.ROLE + "Selector");
+
serializer = (Serializer)selector.select(localSerializer);
+
oStream = ws.getOutputStream();
+
serializer.setOutputStream(oStream);
+
DOMStreamer streamer = new DOMStreamer(serializer);
+
streamer.stream(resource);
+
} finally {
+
if (oStream != null) {
+
oStream.flush();
+
try {
+
oStream.close();
+
failed = false;
+
} catch (Throwable t) {
+
if (this.getLogger().isDebugEnabled() == true) {
+
this.getLogger().debug("FAIL (oStream.close)
exception"+t);
+
throw new ProcessingException("Could not process your
document.", t);
+
}
+
} finally {
+
if ( selector != null ) {
+
selector.release( serializer );
+
this.manager.release( selector );
+
}
+
}
+
}
+
}
} else {
- throw new ProcessingException("No serializer specified for
writing to source " + systemID);
+
if (this.getLogger().isDebugEnabled() == true) {
+
this.getLogger().debug("ERROR no serializer");
+
}
+
//throw new ProcessingException("No serializer specified for writing to source " +
systemID);
+
message = "That source requires a serializer, please add the appropirate tag to your
code.";
}
}
- }
+ }
+ } catch (DOMException de) {
+ if (this.getLogger().isDebugEnabled()
== true) {
+
this.getLogger().debug("FAIL exception: "+de);
+ }
+ //throw new ProcessingException("Could not process your document.", de);
+ message = "There was a problem manipulating your document: " + de;
} catch (ComponentException ce) {
- throw new ProcessingException("Unable to lookup component.", ce);
+ if (this.getLogger().isDebugEnabled()
== true) {
+
this.getLogger().debug("FAIL exception: "+ce);
+ }
+ //throw new ProcessingException("Unable to lookup component.", ce);
+ message = "There was a problem looking up a component: " + ce;
} catch (SourceException se) {
- throw SourceUtil.handle("Error during resolving "+systemID, se);
+ if (this.getLogger().isDebugEnabled()
== true) {
+
this.getLogger().debug("FAIL exception: "+se);
+ }
+ //throw new ProcessingException("Error during resolving "+systemID, se);
+ message = "There was a problem resolving that source: [" + systemID +
"] : " + se;
} finally {
this.resolver.release( source );
}
+
+ // Report result
+ String result = (failed) ? RESULT_FAILED :
RESULT_SUCCESS;
+ String action = ACTION_NONE;
+ if (!failed) { action = (exists) ? ACTION_OVER :
ACTION_NEW; }
+
+ sendStartElementEvent(RESULT_ELEMENT);
+ sendStartElementEvent(EXECUTION_ELEMENT);
+ sendTextEvent(result);
+ sendEndElementEvent(EXECUTION_ELEMENT);
+ sendStartElementEvent(MESSAGE_ELEMENT);
+ sendTextEvent(message);
+ sendEndElementEvent(MESSAGE_ELEMENT);
+ sendStartElementEvent(BEHAVIOUR_ELEMENT);
+ sendTextEvent(tagname);
+ sendEndElementEvent(BEHAVIOUR_ELEMENT);
+ sendStartElementEvent(ACTION_ELEMENT);
+ sendTextEvent(action);
+ sendEndElementEvent(ACTION_ELEMENT);
+ sendStartElementEvent(SOURCE_ELEMENT);
+ sendTextEvent(target);
+ sendEndElementEvent(SOURCE_ELEMENT);
+ if (localSerializer != null) {
+
sendStartElementEvent(SERIALIZER_ELEMENT);
+ sendTextEvent(localSerializer);
+
sendEndElementEvent(SERIALIZER_ELEMENT);
+ }
+ sendEndElementEvent(RESULT_ELEMENT);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END insertFragment");
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]