sylvain 02/01/30 06:35:08
Modified: . changes.xml
src/java/org/apache/cocoon/transformation
FragmentExtractorTransformer.java
src/scratchpad/src/org/apache/cocoon/treeprocessor
AbstractParentProcessingNode.java
MapStackResolver.java TreeBuilder.java
TreeProcessor.java
src/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap
GenerateNode.java PipelinesNode.java
SerializeNode.java TransformNode.java
Log:
- applied FragmentExtractor patch from Stephan Michels
([EMAIL PROTECTED])
- minor cleaning on TreeProcessor
Revision Changes Path
1.83 +6 -1 xml-cocoon2/changes.xml
Index: changes.xml
===================================================================
RCS file: /home/cvs/xml-cocoon2/changes.xml,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -r1.82 -r1.83
--- changes.xml 29 Jan 2002 19:49:36 -0000 1.82
+++ changes.xml 30 Jan 2002 14:35:07 -0000 1.83
@@ -4,7 +4,7 @@
<!--
History of Cocoon changes
- $Id: changes.xml,v 1.82 2002/01/29 19:49:36 froehlich Exp $
+ $Id: changes.xml,v 1.83 2002/01/30 14:35:07 sylvain Exp $
-->
<changes title="History of Changes">
@@ -31,6 +31,11 @@
</devs>
<release version="@version@" date="@date@">
+ <action dev="SW" type="update" due-to="Stephan Michels"
due-to-email="[EMAIL PROTECTED]">
+ The FragmentExtractorTransformer is now configurable to extract any fragment
+ identified by an element name and namespace URI, and no more limited to
+ SVG images only.
+ </action>
<action dev="VG" type="fix">
XSP engine now correctly works with dynamically generated sources
with last modification date of 0, and it is correctly reloaded on Cocoon
1.5 +50 -21
xml-cocoon2/src/java/org/apache/cocoon/transformation/FragmentExtractorTransformer.java
Index: FragmentExtractorTransformer.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/transformation/FragmentExtractorTransformer.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- FragmentExtractorTransformer.java 25 Jan 2002 03:58:30 -0000 1.4
+++ FragmentExtractorTransformer.java 30 Jan 2002 14:35:07 -0000 1.5
@@ -13,6 +13,9 @@
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
+import org.apache.avalon.framework.configuration.Configurable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.caching.CacheValidity;
@@ -35,26 +38,34 @@
/** The transformation half of the FragmentExtractor.
- * This transformer sieves an incoming stream of xml with embedded SVG images
- * and replaces the images with an xlink locator pointing to the image.
- * Ultimately this could be much more general, but at the moment, I think it's
- * mainly SVG extraction that's likely to go on, and afterall,
- * <a href="http://c2.com/cgi/wiki?YouArentGonnaNeedIt">you aren't gonna need
it</a>,
- * so I've just used very simple extraction based on a URI and local name.
+ * This transformer sieves an incoming stream of xml
+ * and replaces fragments with an xlink locator pointing to the fragments.
* <p>
+ * The extracted fragments are idendified by their element name and namespace URI.
+ * The default is to extract SVG images ("svg" elements in namespace
+ * "http://www.w3.org/2000/svg"), but this can be overriden in the configuration :
+ * <pre>
+ * <extract-uri>http://my/namespace/uri</extract-uri>
+ * <extract-element>my-element</extract-element>
+ * </pre>
+ * <p>
* <b><em>Warning</em> : since fragments are stored locally in the class, this
transformer
* and the associated generator are very likely to fail on a clustered server.</b>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Paul Russell</a>
- * @version CVS $Revision: 1.4 $ $Date: 2002/01/25 03:58:30 $
+ * @version CVS $Revision: 1.5 $ $Date: 2002/01/30 14:35:07 $
*/
public class FragmentExtractorTransformer extends AbstractTransformer
- implements Composable, Disposable, Cacheable, Poolable {
- private static String EXTRACT_URI="http://www.w3.org/2000/svg";
- private static String EXTRACT_ELEMENT="svg";
+ implements Composable, Disposable, Cacheable, Poolable, Configurable {
+
+ private String extractURI;
+ private String extractElement;
- private static String FE_URI="http://apache.org/cocoon/fragmentextractor/2.0";
- private static String XLINK_URI="http://www.w3c.org/1999/xlink";
+ private final static String EXTRACT_URI_NAME = "extract-uri";
+ private final static String EXTRACT_ELEMENT_NAME = "extract-element";
+
+ private static String FE_URI = "http://apache.org/cocoon/fragmentextractor/2.0";
+ private static String XLINK_URI = "http://www.w3c.org/1999/xlink";
private static String generatorClass =
"org.apache.cocoon.generation.FragmentExtractorGenerator";
@@ -64,23 +75,41 @@
private int extractLevel;
- private int imageID;
+ private int fragmentID;
protected ComponentManager manager;
private DOMFactory documentFactory;
- public void compose(ComponentManager manager) throws ComponentException {
+ public void compose(ComponentManager manager)
+ throws ComponentException{
this.manager = manager;
this.documentFactory = (DOMFactory) this.manager.lookup(Parser.ROLE);
}
+ /**
+ * Configure this transformer.
+ */
+ public void configure( Configuration conf )
+ throws ConfigurationException {
+ if ( conf != null ) {
+
+ this.extractURI =
conf.getChild(EXTRACT_URI_NAME).getValue("http://www.w3.org/2000/svg");
+ this.extractElement =
conf.getChild(EXTRACT_ELEMENT_NAME).getValue("svg");
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Extraction URI is " + this.extractURI);
+ getLogger().debug("Extraction element is " + this.extractElement);
+ }
+ }
+ }
+
/** Setup the transformer.
*/
- public void setup(SourceResolver resolver, Map objectModel, String src,
Parameters par)
+ public void setup(SourceResolver resolver, Map objectModel, String src,
Parameters parameters)
throws ProcessingException, SAXException, IOException {
extractLevel = 0;
- imageID = 0;
+ fragmentID = 0;
prefixMap = new HashMap();
}
@@ -166,9 +195,9 @@
*/
public void startElement(String uri, String loc, String raw, Attributes a)
throws SAXException {
- if ( this.EXTRACT_URI.equals(uri) && this.EXTRACT_ELEMENT.equals(loc) ) {
+ if ( this.extractElement.equals(uri) && this.extractElement.equals(loc) ) {
extractLevel++;
- imageID++;
+ fragmentID++;
getLogger().debug("FragmentExtractorTransformer extractLevel now " +
extractLevel + ".");
// Start the DOM document
@@ -209,7 +238,7 @@
super.endElement(uri,loc,raw);
} else {
this.currentBuilder.endElement(uri,loc,raw);
- if ( this.EXTRACT_URI.equals(uri) && this.EXTRACT_ELEMENT.equals(loc) )
{
+ if ( this.extractURI.equals(uri) && this.extractElement.equals(loc) ) {
extractLevel--;
getLogger().debug("FragmentExtractorTransformer extractLevel now "
+ extractLevel + ".");
@@ -318,7 +347,7 @@
super.startDTD(name,publicId,systemId);
} else {
throw new SAXException(
- "Recieved startDTD after beginning SVG extraction process."
+ "Recieved startDTD after beginning fragment extraction process."
);
}
}
@@ -332,7 +361,7 @@
super.endDTD();
} else {
throw new SAXException(
- "Recieved endDTD after beginning SVG extraction process."
+ "Recieved endDTD after beginning fragment extraction process."
);
}
}
1.3 +12 -7
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractParentProcessingNode.java
Index: AbstractParentProcessingNode.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/AbstractParentProcessingNode.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AbstractParentProcessingNode.java 15 Jan 2002 11:10:52 -0000 1.2
+++ AbstractParentProcessingNode.java 30 Jan 2002 14:35:07 -0000 1.3
@@ -18,7 +18,7 @@
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/15 11:10:52 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/30 14:35:07 $
*/
public abstract class AbstractParentProcessingNode extends AbstractProcessingNode {
@@ -37,10 +37,18 @@
throws Exception {
context.pushMap(currentMap);
- boolean success = invokeNodes(nodes, env, context);
- context.popMap();
+
+ for (int i = 0; i < nodes.length; i++) {
+ if (nodes[i].invoke(env, context)) {
+ // Success
+ context.popMap();
+ return true;
+ }
+ }
- return success;
+ // No success
+ context.popMap();
+ return false;
}
/**
@@ -52,11 +60,8 @@
InvokeContext context)
throws Exception {
- boolean debug = getLogger().isDebugEnabled();
for (int i = 0; i < nodes.length; i++) {
if (nodes[i].invoke(env, context)) {
- if (debug)
- getLogger().debug("Node " + nodes[i] + " at " +
nodes[i].getLocation() + " succeeded");
return true;
}
}
1.7 +3 -3
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/MapStackResolver.java
Index: MapStackResolver.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/MapStackResolver.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- MapStackResolver.java 16 Jan 2002 21:57:10 -0000 1.6
+++ MapStackResolver.java 30 Jan 2002 14:35:07 -0000 1.7
@@ -18,7 +18,7 @@
* Utility class for handling {...} pattern substitutions from a List of Maps.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
- * @version CVS $Revision: 1.6 $ $Date: 2002/01/16 21:57:10 $
+ * @version CVS $Revision: 1.7 $ $Date: 2002/01/30 14:35:07 $
*/
public abstract class MapStackResolver {
@@ -164,7 +164,7 @@
return this.originalExpr;
}
- public String resolve(List mapStack) {
+ public final String resolve(List mapStack) {
return this.expression;
}
}
@@ -251,7 +251,7 @@
}
}
- public String resolve(List mapStack) throws PatternException {
+ public final String resolve(List mapStack) throws PatternException {
StringBuffer result = new StringBuffer();
int stackSize = mapStack.size();
1.3 +20 -4
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/TreeBuilder.java
Index: TreeBuilder.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/TreeBuilder.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TreeBuilder.java 15 Jan 2002 11:10:52 -0000 1.2
+++ TreeBuilder.java 30 Jan 2002 14:35:07 -0000 1.3
@@ -46,7 +46,7 @@
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/15 11:10:52 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/30 14:35:07 $
*/
public class TreeBuilder extends AbstractLoggable implements
@@ -62,15 +62,31 @@
protected LogKitManager logKit;
+ /**
+ * The parent component manager, set using <code>compose()</code>
(implementation of
+ * <code>Composable</code>).
+ */
protected ComponentManager parentManager;
- protected RoleManager roleManager;
+ /**
+ * The parent role manager, set using <code>setRoleManager</code>
(implementation of
+ * <code>createRoleManager</code>).
+ */
+ protected RoleManager parentRoleManager;
protected Configuration configuration;
// -------------------------------------
+ /**
+ * Component manager created by {@link #createComponentManager()}.
+ */
protected ComponentManager manager;
+ /**
+ * Role manager result created by {@link #createRoleManager()}.
+ */
+ protected RoleManager roleManager;
+
/** Selector for ProcessingNodeBuilders */
protected ComponentSelector builderSelector;
@@ -114,7 +130,7 @@
}
public void setRoleManager(RoleManager rm) {
- this.roleManager = rm;
+ this.parentRoleManager = rm;
}
public void configure(Configuration config) throws ConfigurationException {
@@ -146,7 +162,7 @@
getLogger(),
this.context,
this.manager,
- null, // role manager,
+ this.parentRoleManager,
this.logKit,
this.configuration.getChild("roles")
);
1.3 +11 -32
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/TreeProcessor.java
Index: TreeProcessor.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/TreeProcessor.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TreeProcessor.java 15 Jan 2002 11:10:52 -0000 1.2
+++ TreeProcessor.java 30 Jan 2002 14:35:07 -0000 1.3
@@ -8,7 +8,7 @@
package org.apache.cocoon.treeprocessor;
-import org.apache.avalon.excalibur.component.DefaultRoleManager;
+import org.apache.avalon.excalibur.component.RoleManageable;
import org.apache.avalon.excalibur.component.RoleManager;
import org.apache.avalon.excalibur.logger.LogKitManageable;
import org.apache.avalon.excalibur.logger.LogKitManager;
@@ -54,14 +54,13 @@
* Interpreted tree-traversal implementation of a pipeline assembly language.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/15 11:10:52 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/30 14:35:07 $
*/
public class TreeProcessor extends AbstractLoggable implements ThreadSafe,
Processor,
- Composable, Configurable, LogKitManageable, Initializable, Contextualizable,
Disposable {
+ Composable, Configurable, LogKitManageable, RoleManageable, Initializable,
Contextualizable, Disposable {
private static final String XCONF_URL =
"resource://org/apache/cocoon/treeprocessor/treeprocessor.xconf";
-// private static final String ROLES_URL =
"resource://org/apache/cocoon/treeprocessor/treeprocessor.roles";
/** The parent TreeProcessor, if any */
protected TreeProcessor parent;
@@ -75,6 +74,9 @@
/** The logkit manager to get Loggers */
protected LogKitManager logKit;
+ /** The role manager */
+ protected RoleManager roleManager;
+
/** The language used by this processor */
protected String language;
@@ -157,6 +159,10 @@
public void setLogKitManager(LogKitManager logKit) {
this.logKit = logKit;
}
+
+ public void setRoleManager(RoleManager rm) {
+ this.roleManager = rm;
+ }
/*
@@ -328,7 +334,7 @@
getLogger(),
this.context,
this.manager,
- null, //getRoleManager(),
+ this.roleManager,
this.logKit,
this.currentLanguage);
@@ -356,33 +362,6 @@
// Finished
this.rootNode = root;
}
-
-//
-// Of no use, since the TreeBuilder has to work with the role manager of the target
language.
-//
-// private RoleManager getRoleManager() throws Exception {
-//
-// Configuration rolesConfig;
-//
-// URLFactory factory = (URLFactory)this.manager.lookup(URLFactory.ROLE);
-// URLSource source = new URLSource(factory.getURL(ROLES_URL), this.manager);
-// try {
-// SAXConfigurationHandler handler = new SAXConfigurationHandler();
-// source.toSAX(handler);
-// rolesConfig = handler.getConfiguration();
-// } finally {
-// this.manager.release((Component)factory);
-// if (source != null) {
-// source.recycle();
-// }
-// }
-//
-// DefaultRoleManager sitemapRoleManager = new DefaultRoleManager();
-// sitemapRoleManager.setLogger(getLogger());
-// sitemapRoleManager.configure(rolesConfig);
-//
-// return sitemapRoleManager;
-// }
public void dispose() {
disposeTree();
1.3 +12 -9
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GenerateNode.java
Index: GenerateNode.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/GenerateNode.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- GenerateNode.java 15 Jan 2002 11:10:54 -0000 1.2
+++ GenerateNode.java 30 Jan 2002 14:35:07 -0000 1.3
@@ -24,7 +24,7 @@
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/15 11:10:54 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/30 14:35:07 $
*/
public class GenerateNode extends AbstractProcessingNode implements
ParameterizableProcessingNode {
@@ -65,17 +65,20 @@
);
// Check view
- String cocoonView = env.getView();
- if (cocoonView != null && this.views != null) {
+ if (this.views != null) {
- // Get view node
- ProcessingNode viewNode = (ProcessingNode)this.views.get(cocoonView);
+ String cocoonView = env.getView();
+ if (cocoonView != null) {
- if (viewNode != null) {
- if (getLogger().isInfoEnabled()) {
- getLogger().info("Jumping to view " + cocoonView + " from
generator at " + this.getLocation());
+ // Get view node
+ ProcessingNode viewNode =
(ProcessingNode)this.views.get(cocoonView);
+
+ if (viewNode != null) {
+ if (getLogger().isInfoEnabled()) {
+ getLogger().info("Jumping to view " + cocoonView + " from
generator at " + this.getLocation());
+ }
+ return viewNode.invoke(env, context);
}
- return viewNode.invoke(env, context);
}
}
1.3 +2 -2
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelinesNode.java
Index: PipelinesNode.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/PipelinesNode.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- PipelinesNode.java 15 Jan 2002 11:10:54 -0000 1.2
+++ PipelinesNode.java 30 Jan 2002 14:35:07 -0000 1.3
@@ -31,7 +31,7 @@
* Handles <map:pipelines>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/15 11:10:54 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/30 14:35:07 $
*/
public final class PipelinesNode extends SimpleParentProcessingNode
@@ -66,7 +66,7 @@
* and a <code>Redirector</code> in the object model. The previous resolver and
* redirector, if any, are restored before return.
*/
- public boolean invoke(Environment env, InvokeContext context)
+ public final boolean invoke(Environment env, InvokeContext context)
throws Exception {
// Recompose context (and pipelines) to the local component manager
1.4 +13 -11
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/SerializeNode.java
Index: SerializeNode.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/SerializeNode.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- SerializeNode.java 16 Jan 2002 10:54:12 -0000 1.3
+++ SerializeNode.java 30 Jan 2002 14:35:07 -0000 1.4
@@ -24,7 +24,7 @@
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
- * @version CVS $Revision: 1.3 $ $Date: 2002/01/16 10:54:12 $
+ * @version CVS $Revision: 1.4 $ $Date: 2002/01/30 14:35:07 $
*/
public class SerializeNode extends AbstractProcessingNode {
@@ -58,17 +58,19 @@
throws Exception {
// Check view
- String cocoonView = env.getView();
- if (cocoonView != null && this.views != null) {
-
- // Get view node
- ProcessingNode viewNode = (ProcessingNode)this.views.get(cocoonView);
-
- if (viewNode != null) {
- if (getLogger().isInfoEnabled()) {
- getLogger().info("Jumping to view " + cocoonView + " from
serializer at " + this.getLocation());
+ if (this.views != null) {
+ String cocoonView = env.getView();
+ if (cocoonView != null) {
+
+ // Get view node
+ ProcessingNode viewNode =
(ProcessingNode)this.views.get(cocoonView);
+
+ if (viewNode != null) {
+ if (getLogger().isInfoEnabled()) {
+ getLogger().info("Jumping to view " + cocoonView + " from
serializer at " + this.getLocation());
+ }
+ return viewNode.invoke(env, context);
}
- return viewNode.invoke(env, context);
}
}
1.3 +14 -12
xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/TransformNode.java
Index: TransformNode.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/treeprocessor/sitemap/TransformNode.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TransformNode.java 15 Jan 2002 11:10:54 -0000 1.2
+++ TransformNode.java 30 Jan 2002 14:35:07 -0000 1.3
@@ -23,7 +23,7 @@
/**
*
* @author <a href="mailto:[EMAIL PROTECTED]">Sylvain Wallez</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/15 11:10:54 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/30 14:35:07 $
*/
public class TransformNode extends AbstractProcessingNode implements
ParameterizableProcessingNode {
@@ -49,7 +49,7 @@
this.views = views;
}
- public boolean invoke(Environment env, InvokeContext context)
+ public final boolean invoke(Environment env, InvokeContext context)
throws Exception {
List mapStack = context.getMapStack();
@@ -61,17 +61,19 @@
);
// Check view
- String cocoonView = env.getView();
- if (cocoonView != null && this.views != null) {
-
- // Get view node
- ProcessingNode viewNode = (ProcessingNode)this.views.get(cocoonView);
-
- if (viewNode != null) {
- if (getLogger().isInfoEnabled()) {
- getLogger().info("Jumping to view " + cocoonView + " from
transformer at " + this.getLocation());
+ if (this.views != null) {
+ String cocoonView = env.getView();
+ if (cocoonView != null) {
+
+ // Get view node
+ ProcessingNode viewNode =
(ProcessingNode)this.views.get(cocoonView);
+
+ if (viewNode != null) {
+ if (getLogger().isInfoEnabled()) {
+ getLogger().info("Jumping to view " + cocoonView + " from
transformer at " + this.getLocation());
+ }
+ return viewNode.invoke(env, context);
}
- return viewNode.invoke(env, context);
}
}
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]