rss input update
authorzapata <zapata>
Thu, 22 May 2003 03:15:06 +0000 (03:15 +0000)
committerzapata <zapata>
Thu, 22 May 2003 03:15:06 +0000 (03:15 +0000)
19 files changed:
etc/open/comment.template
etc/open/editarticle.template
etc/open/editcomment.template
etc/open/posting.template
etc/producer/article.template
etc/producer/featurearchive.template
etc/producer/newswirearchive.template
etc/producer/startpage.template
etc/producer/topicpage.template
source/mir/entity/Entity.java
source/mir/entity/adapter/EntityAdapterFailure.java [new file with mode: 0755]
source/mir/entity/adapter/EntityAdapterModel.java
source/mir/producer/EntityModifyingProducerNode.java
source/mir/producer/ListEnumeratingProducerNode.java [new file with mode: 0755]
source/mir/producer/reader/DefaultProducerNodeBuilders.java
source/mir/rss/RSSAggregator.java
source/mir/rss/RSSReader.java
source/mir/rss/RSSTest.java
source/mir/util/DateTimeFunctions.java [new file with mode: 0755]

index f6d9bcc..8051c66 100755 (executable)
@@ -1,5 +1,8 @@
 <html>
-<head><title>${lang("comment.htmltitle")}</title></head>
+<head>
+  <title>${lang("comment.htmltitle")}</title>
+       <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">
+</head>
 <body bgcolor="white" text="black" link="#006600" vlink="#009900" alink="red">
 
 <form action="${config["Producer.OpenAction"]}" method=post>
index 8cd8a6e..0c49459 100755 (executable)
@@ -6,7 +6,7 @@
        <meta name="description" content="${lang("posting.meta.description")}>
        <meta name="author" content="${lang("posting.meta.author")}>
        <meta name="keywords" content="${lang("posting.meta.keywords")}>
-       <meta http-equiv="Content-Type" content="text/html; charset=${lang("htmlcharset")}>
+       <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">
        <meta name="robots" content="index">
        <meta name="robots" content="follow">
        <style type="text/css" media="all">@import "forms.css";</style>
index b5eff3f..dbdb1c9 100755 (executable)
@@ -2,6 +2,8 @@
 <html>
   <head>
     <title>${lang("comment.htmltitle")}</title> 
+    <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">
+    
   </head>
   
   <body marginwidth="0" marginheight="0" leftmargin="0" topmargin="0" bgcolor="#dddddd">
index f98ed27..d22dab1 100755 (executable)
@@ -6,7 +6,7 @@
        <meta name="author" content="${lang("posting.meta.author")}">
        <meta name="keywords" content="${lang("posting.meta.keywords")}">
        <!--<meta name="date" content="### Date ###Time">-->
-       <meta http-equiv="Content-Type" content="text/html; charset=${lang("htmlcharset")}">
+       <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">
        <meta name="robots" content="index">
        <meta name="robots" content="follow">
 
index 870928d..6ca865e 100755 (executable)
@@ -5,7 +5,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-       <meta http-equiv="Content-Type" content="text/html; charset=${lang("htmlcharset")}">    
+       <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">       
     <title>${config["Mir.Name"]} | ${article.title}</title>
        <meta name="keywords" content="indymedia,imc">
        <meta name="description" content="indymedia,imc">
index 5a5a464..8fd5fc5 100755 (executable)
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-       <meta http-equiv="Content-Type" content="text/html; charset=${lang("htmlcharset")}">
+       <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">
     <title>${config["Mir.Name"]} | ${lang("featurearchive.title")}</title>
        <meta name="keywords" content="${lang("general.keywords")}">
        <meta name="description" content="${lang("featurearchive.title")}">
index 8f15f3d..5b9b800 100755 (executable)
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-       <meta http-equiv="Content-Type" content="text/html; charset=${lang("htmlcharset")}">
+       <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">
     <title>${config["Mir.Name"]} | ${lang("newswirearchive.title")}</title>
        <meta name="keywords" content="${lang("general.keywords")}">
        <meta name="description" content="${lang("newswirearchive.title")}">
index 8836961..485d385 100755 (executable)
@@ -7,7 +7,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-       <meta http-equiv="Content-Type" content="text/html; charset=${lang("htmlcharset")}">    
+       <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">       
        <title>${config["Mir.Name"]}</title>
        <meta name="keywords" content="indymedia,imc">
        <meta name="description" content="indymedia,imc">
index 2c4c095..e372834 100755 (executable)
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-       <meta http-equiv="Content-Type" content="text/html; charset=${lang("htmlcharset")}">
+       <meta http-equiv="Content-Type" content="text/html; charset=${config["Mir.DefaultHTMLCharset"]}">
     <title>${config["Mir.Name"]} | ${topic.title}</title>
        <meta name="keywords" content="${lang("general.keywords")}">
        <meta name="description" content="${topic.description}">
index e4d8927..465366b 100755 (executable)
@@ -51,7 +51,7 @@ import freemarker.template.TemplateModelRoot;
  * an entity. Entities are used to represent rows of a database table.<p>
  * Interfacing TemplateHashModel and TemplateModelRoot to be freemarker compliant
  *
- * @version $Id: Entity.java,v 1.21 2003/05/03 00:21:22 zapata Exp $
+ * @version $Id: Entity.java,v 1.21.2.1 2003/05/22 03:15:07 zapata Exp $
  * @author rk
  *
  */
@@ -183,8 +183,7 @@ public class Entity implements TemplateHashModel, TemplateModelRoot
    * @param theValue The new value of the field
    * @exception StorageObjectException
    */
-  public void setValueForProperty(String theProp, String theValue) throws
-      StorageObjectFailure {
+  public void setValueForProperty(String theProp, String theValue) throws StorageObjectFailure {
     if (isField(theProp))
       theValuesHash.put(theProp, theValue);
     else {
diff --git a/source/mir/entity/adapter/EntityAdapterFailure.java b/source/mir/entity/adapter/EntityAdapterFailure.java
new file mode 100755 (executable)
index 0000000..8620a93
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.entity.adapter;
+
+import multex.Failure;
+
+public class EntityAdapterFailure extends Failure {
+  public EntityAdapterFailure(String msg,Throwable cause) {
+    super(msg,cause);
+  }
+
+  public EntityAdapterFailure(Throwable aCause) {
+    this (aCause.getMessage(), aCause);
+  }
+}
\ No newline at end of file
index 0c29089..0d4ea50 100755 (executable)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with  any library licensed under the Apache Software License, 
- * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library 
- * (or with modified versions of the above that use the same license as the above), 
- * and distribute linked combinations including the two.  You must obey the 
- * GNU General Public License in all respects for all of the code used other than 
- * the above mentioned libraries.  If you modify this file, you may extend this 
- * exception to your version of the file, but you are not obligated to do so.  
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
  * If you do not wish to do so, delete this exception statement from your version.
  */
 package mir.entity.adapter;
@@ -48,9 +48,23 @@ public class EntityAdapterModel {
     return mapping.getDefinition().makeEntityAdapter( anEntity, this );
   }
 
+  public EntityAdapter createNewEntity( String aName ) throws EntityAdapterExc {
+    try {
+      Mapping mapping = getMappingForName(aName);
+      StorageObject storage = mapping.storage;
+      Entity entity = (Entity) storage.getEntityClass().newInstance();
+      entity.setStorage(storage);
+
+      return mapping.getDefinition().makeEntityAdapter(entity, this);
+    }
+    catch (Throwable t) {
+      throw new EntityAdapterFailure(t);
+    }
+  }
+
   public void addMapping( String aName, StorageObject aStorage, EntityAdapterDefinition aDefinition ) {
     entityAdapterMappings.put( aName, new Mapping( aStorage, aDefinition ) );
-    }
+  }
 
   public Mapping getMappingForName( String aName ) throws EntityAdapterExc {
     if (!entityAdapterMappings.containsKey(aName))
index 23ce108..ecbf595 100755 (executable)
 
 package mir.producer;
 
-import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
+import mir.entity.Entity;
 import mir.entity.adapter.EntityAdapter;
+import mir.entity.adapter.EntityAdapterModel;
+import mir.log.LoggerWrapper;
 import mir.util.ParameterExpander;
 
 
-public abstract class EntityModifyingProducerNode implements ProducerNode {
-  String entityExpression;
-  String entityField;
-  String valueExpression;
+public class EntityModifyingProducerNode implements ProducerNode {
+  private String entityExpression;
+  private String definition;
+  private Map fields;
+  private boolean create;
+  private EntityAdapterModel model;
 
-  public EntityModifyingProducerNode(String anEntityExpression, String anEntityField, String aValueExpression) {
+  public EntityModifyingProducerNode(EntityAdapterModel aModel, boolean aCreate, String aDefinition, String anEntityExpression, Map aFieldValues) {
     entityExpression = anEntityExpression;
-    entityField = anEntityField;
-    valueExpression = aValueExpression;
+    definition = aDefinition;
+    create = aCreate;
+    model = aModel;
+    fields = new HashMap();
+    fields.putAll(aFieldValues);
   }
 
-  public void produce(Map aValueMap, String aVerb, PrintWriter aLogger) throws ProducerFailure {
-    Object entity;
+  public void addField(String aField, String aValueExpression) {
+    fields.put(aField, aValueExpression);
+  }
 
+  public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerExc, ProducerFailure {
     try {
-      entity = ParameterExpander.findValueForKey( aValueMap, entityExpression );
+      Object entityAdapter;
+
+      if (create) {
+        entityAdapter = model.createNewEntity(definition);
+        ParameterExpander.setValueForKey(aValueMap, entityExpression, entityAdapter);
+      }
+      else {
+        entityAdapter = ParameterExpander.findValueForKey(aValueMap, entityExpression);
+      }
+
+      if (entityAdapter instanceof EntityAdapter) {
+        Entity entity = ((EntityAdapter) entityAdapter).getEntity();
+        Iterator i = fields.entrySet().iterator();
+        while (i.hasNext()) {
+          Map.Entry entry = (Map.Entry) i.next();
+          String entityField = (String) entry.getKey();
+          String valueExpression = (String) entry.getValue();
+
+          Object value = ParameterExpander.evaluateExpression(aValueMap, valueExpression);
 
-      if (entity instanceof EntityAdapter) {
-        ((EntityAdapter) entity).getEntity().setValueForProperty(entityField, valueExpression);
-        ((EntityAdapter) entity).getEntity().update();
+          if (value instanceof String)
+            entity.setValueForProperty(entityField, (String) value);
+          else if (value instanceof EntityAdapter)
+            entity.setValueForProperty(entityField, ((EntityAdapter) value).getEntity().getId());
+          else
+            aLogger.warn("Can't set value " + value.toString() + " for field " + entityField);
+        }
+        entity.update();
       }
       else
-        throw new Exception( entityExpression + " does not evaluate to an entity");
+        throw new ProducerExc( entityExpression + " does not evaluate to an entity");
     }
     catch (Throwable t) {
-      aLogger.println("Error while performing entity modifying operation: " + t.getMessage());
+      aLogger.error("Error while performing entity modification operation: " + t.getMessage());
 
       throw new ProducerFailure(t.getMessage(), t);
     }
diff --git a/source/mir/producer/ListEnumeratingProducerNode.java b/source/mir/producer/ListEnumeratingProducerNode.java
new file mode 100755 (executable)
index 0000000..0752c57
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.producer;
+
+import java.util.*;
+import java.util.Map;
+
+import mir.entity.adapter.EntityAdapterModel;
+import mir.entity.adapter.EntityIteratorAdapter;
+import mir.log.LoggerWrapper;
+import mir.util.*;
+
+public class ListEnumeratingProducerNode extends ProducerNodeDecorator {
+  private String key;
+  private String listExpression;
+
+  public ListEnumeratingProducerNode( String aKey, String aListExpression, ProducerNode aSubNode) {
+    super(aSubNode);
+
+    key = aKey;
+    listExpression = aListExpression;
+  }
+
+  public void produce(Map aValueMap, String aVerb, LoggerWrapper aLogger) throws ProducerFailure, ProducerExc {
+    Iterator browser;
+    Object list;
+
+    try {
+      list = ParameterExpander.evaluateExpression(aValueMap, listExpression);
+      if (list instanceof Collection)
+        browser = ((Collection) list).iterator();
+      else if (list instanceof Iterator)
+        browser = (Iterator) list;
+      else
+        throw new ProducerExc("Can't enumarate a " + list.getClass().getName());
+
+
+      if (browser instanceof RewindableIterator) {
+        ((RewindableIterator) browser).rewind();
+      }
+
+      while (browser.hasNext() && !isAborted(aValueMap)) {
+        ParameterExpander.setValueForKey(aValueMap, key, browser.next());
+        super.produce(aValueMap, aVerb, aLogger);
+      }
+    }
+    catch (Throwable t) {
+      aLogger.error("Exception occurred inside an ListEnumeratingProducerNode: " + t.getMessage());
+    }
+  };
+}
index b458fed..25ce03f 100755 (executable)
@@ -46,7 +46,7 @@ import mir.producer.EntityBatchingProducerNode;
 import mir.producer.EntityEnumeratingProducerNode;
 import mir.producer.EntityListProducerNode;
 import mir.producer.EvaluatedAssignmentProducerNode;
-import mir.producer.ExpandedAssignmentProducerNode;
+import mir.producer.*;
 import mir.producer.FileDateSettingProducerNode;
 import mir.producer.FileDeletingProducerNode;
 import mir.producer.GeneratingProducerNode;
@@ -86,6 +86,9 @@ public class DefaultProducerNodeBuilders {
     aBuilderLibrary.registerFactory("List", new ListProducerNodeBuilder.factory(aModel));
     aBuilderLibrary.registerFactory("Batch", new BatchingProducerNodeBuilder.factory(aModel));
 
+    aBuilderLibrary.registerFactory("UpdateEntity", new UpdateEntityProducerNodeBuilder.factory(aModel));
+    aBuilderLibrary.registerFactory("CreateEntity", new CreateEntityProducerNodeBuilder.factory(aModel));
+
     aBuilderLibrary.registerFactory("Generate",
         new GeneratingProducerNodeBuilder.factory(aGeneratorLibrary, aWriterEngine));
   }
@@ -184,17 +187,21 @@ public class DefaultProducerNodeBuilders {
   public static class EnumeratingProducerNodeBuilder extends AbstractProducerNodeBuilder {
     private final static String   ENUMERATION_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
     private final static String   ENUMERATION_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
+    private final static String   ENUMERATION_LIST_ATTRIBUTE = "list";
     private final static String   ENUMERATION_SELECTION_ATTRIBUTE = SELECTION_ATTRIBUTE;
     private final static String   ENUMERATION_ORDER_ATTRIBUTE = ORDER_ATTRIBUTE;
     private final static String   ENUMERATION_DEFAULT_SUBNODE = "default";
     private final static String   ENUMERATION_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
     private final static String   ENUMERATION_SKIP_ATTRIBUTE = SKIP_ATTRIBUTE;
-    private final static String[] ENUMERATION_REQUIRED_ATTRIBUTES = { ENUMERATION_KEY_ATTRIBUTE, ENUMERATION_DEFINITION_ATTRIBUTE };
-    private final static String[] ENUMERATION_OPTIONAL_ATTRIBUTES = { ENUMERATION_SELECTION_ATTRIBUTE, ENUMERATION_ORDER_ATTRIBUTE, ENUMERATION_LIMIT_ATTRIBUTE, ENUMERATION_SKIP_ATTRIBUTE};
+    private final static String[] ENUMERATION_LIST_REQUIRED_ATTRIBUTES = { ENUMERATION_LIST_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
+    private final static String[] ENUMERATION_LIST_OPTIONAL_ATTRIBUTES = { };
+    private final static String[] ENUMERATION_QUERY_REQUIRED_ATTRIBUTES = { ENUMERATION_DEFINITION_ATTRIBUTE, ENUMERATION_KEY_ATTRIBUTE };
+    private final static String[] ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES = { ENUMERATION_SELECTION_ATTRIBUTE, ENUMERATION_ORDER_ATTRIBUTE, ENUMERATION_LIMIT_ATTRIBUTE, ENUMERATION_SKIP_ATTRIBUTE};
     private final static String[] ENUMERATION_SUBNODES = {ENUMERATION_DEFAULT_SUBNODE};
 
     private String key;
     private String definition;
+    private String list;
     private String selection;
     private String order;
     private String limit;
@@ -208,10 +215,20 @@ public class DefaultProducerNodeBuilders {
     }
 
     public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc  {
-      XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_REQUIRED_ATTRIBUTES, ENUMERATION_OPTIONAL_ATTRIBUTES);
+      definition = (String) anAttributes.get(ENUMERATION_DEFINITION_ATTRIBUTE);
+      list = (String) anAttributes.get(ENUMERATION_DEFINITION_ATTRIBUTE);
+
+      if ((list==null && definition==null) || (list!=null && definition!=null))
+        throw new ProducerConfigExc("Exactly one of "+ENUMERATION_LIST_ATTRIBUTE+" and "+ENUMERATION_LIST_ATTRIBUTE+" must be set");
+
+
+      if (list!=null)
+        XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_LIST_REQUIRED_ATTRIBUTES, ENUMERATION_LIST_OPTIONAL_ATTRIBUTES);
+      if (definition!=null)
+        XMLReaderTool.checkAttributes(anAttributes, ENUMERATION_QUERY_REQUIRED_ATTRIBUTES, ENUMERATION_QUERY_OPTIONAL_ATTRIBUTES);
+
 
       key = (String) anAttributes.get(ENUMERATION_KEY_ATTRIBUTE);
-      definition = (String) anAttributes.get(ENUMERATION_DEFINITION_ATTRIBUTE);
       selection = (String) XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_SELECTION_ATTRIBUTE, "");
       order = (String) XMLReaderTool.getStringAttributeWithDefault(anAttributes, ENUMERATION_ORDER_ATTRIBUTE, "");
       limit = (String) anAttributes.get(ENUMERATION_LIMIT_ATTRIBUTE);
@@ -219,7 +236,10 @@ public class DefaultProducerNodeBuilders {
     };
 
     public ProducerNode constructNode() {
-      return new EntityEnumeratingProducerNode(key, model, definition, selection, order, limit, skip, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
+      if (definition!=null)
+        return new EntityEnumeratingProducerNode(key, model, definition, selection, order, limit, skip, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
+      else
+        return new ListEnumeratingProducerNode(key, list, getSubNode(ENUMERATION_DEFAULT_SUBNODE ));
     };
 
     public static class factory implements ProducerNodeBuilderFactory {
@@ -237,6 +257,106 @@ public class DefaultProducerNodeBuilders {
 
 ////////////////////////////////////////////////////////////////////////////////
 
+  public static class UpdateEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
+    private final static String   UPDATE_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
+    private final static String   UPDATE_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
+    private final static String[] UPDATE_SUBNODES = {};
+
+    private String key;
+    private String definition;
+    private Map fieldValues;
+
+    private EntityAdapterModel model;
+
+    public UpdateEntityProducerNodeBuilder(EntityAdapterModel aModel) {
+      super(UPDATE_SUBNODES);
+
+      model = aModel;
+      fieldValues = new HashMap();
+    }
+
+    public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc  {
+      key = (String) anAttributes.get(UPDATE_KEY_ATTRIBUTE);
+
+      if (key == null)
+        throw new XMLReader.XMLReaderExc("missing required attribute '" + UPDATE_KEY_ATTRIBUTE + "'" );
+      definition = (String) anAttributes.get(UPDATE_DEFINITION_ATTRIBUTE);
+
+      fieldValues.putAll(anAttributes);
+      fieldValues.remove(UPDATE_KEY_ATTRIBUTE);
+      fieldValues.remove(UPDATE_DEFINITION_ATTRIBUTE);
+    };
+
+    public ProducerNode constructNode() {
+      return new EntityModifyingProducerNode(model, false, definition, key, fieldValues);
+    };
+
+    public static class factory implements ProducerNodeBuilderFactory {
+      private EntityAdapterModel model;
+
+      public factory(EntityAdapterModel aModel) {
+        model = aModel;
+      }
+
+      public ProducerNodeBuilder makeBuilder() {
+        return new UpdateEntityProducerNodeBuilder(model);
+      }
+    }
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+
+  public static class CreateEntityProducerNodeBuilder extends AbstractProducerNodeBuilder {
+    private final static String   CREATEENTITY_KEY_ATTRIBUTE = KEY_ATTRIBUTE;
+    private final static String   CREATEENTITY_DEFINITION_ATTRIBUTE = DEFINITION_ATTRIBUTE;
+    private final static String[] CREATEENTITY_SUBNODES = {};
+
+    private String key;
+    private String definition;
+    private Map fieldValues;
+
+    private EntityAdapterModel model;
+
+    public CreateEntityProducerNodeBuilder(EntityAdapterModel aModel) {
+      super(CREATEENTITY_SUBNODES);
+
+      model = aModel;
+      fieldValues = new HashMap();
+    }
+
+    public void setAttributes(Map anAttributes) throws ProducerConfigExc, XMLReader.XMLReaderExc  {
+      key = (String) anAttributes.get(CREATEENTITY_KEY_ATTRIBUTE);
+
+      if (key == null)
+        throw new XMLReader.XMLReaderExc("missing required attribute '" + CREATEENTITY_KEY_ATTRIBUTE + "'" );
+      if (definition == null)
+        throw new XMLReader.XMLReaderExc("missing required attribute '" + CREATEENTITY_DEFINITION_ATTRIBUTE + "'" );
+      definition = (String) anAttributes.get(CREATEENTITY_DEFINITION_ATTRIBUTE);
+
+      fieldValues.putAll(anAttributes);
+      fieldValues.remove(CREATEENTITY_KEY_ATTRIBUTE);
+      fieldValues.remove(CREATEENTITY_DEFINITION_ATTRIBUTE);
+    };
+
+    public ProducerNode constructNode() {
+      return new EntityModifyingProducerNode(model, true, definition, key, fieldValues);
+    };
+
+    public static class factory implements ProducerNodeBuilderFactory {
+      private EntityAdapterModel model;
+
+      public factory(EntityAdapterModel aModel) {
+        model = aModel;
+      }
+
+      public ProducerNodeBuilder makeBuilder() {
+        return new CreateEntityProducerNodeBuilder(model);
+      }
+    }
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+
   public static class LoopProducerNodeBuilder extends AbstractProducerNodeBuilder {
     private final static String   LOOP_CONDITION_ATTRIBUTE = "condition";
     private final static String   LOOP_LIMIT_ATTRIBUTE = LIMIT_ATTRIBUTE;
index 326e583..bdc6ae0 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001, 2002  The Mir-coders group
+ * Copyright (C) 2001, 2002 The Mir-coders group
  *
  * This file is part of Mir.
  *
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with the com.oreilly.servlet library, any library
- * licensed under the Apache Software License, The Sun (tm) Java Advanced
- * Imaging library (JAI), The Sun JIMI library (or with modified versions of
- * the above that use the same license as the above), and distribute linked
- * combinations including the two.  You must obey the GNU General Public
- * License in all respects for all of the code used other than the above
- * mentioned libraries.  If you modify this file, you may extend this exception
- * to your version of the file, but you are not obligated to do so.  If you do
- * not wish to do so, delete this exception statement from your version.
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
  */
 
 package mir.rss;
index 5a67825..2c54eed 100755 (executable)
@@ -394,35 +394,10 @@ public class RSSReader {
     public Object getValue() {
       try {
         String expression = data.toString().trim();
-        SimpleParser parser = new SimpleParser(expression);
-
-        String year="";
-        String month="";
-        String day="";
-        String hour="";
-        String minutes="";
-
-          year = parser.parse(NUMBER);
-          parser.skip("-");
-          month = parser.parse(NUMBER);
-          parser.skip("-");
-          day = parser.parse(NUMBER);
-          parser.skip("T");
-          hour = parser.parse(NUMBER);
-          parser.skip(":");
-          minutes = parser.parse(NUMBER);
-
-          SimpleDateFormat d = new SimpleDateFormat("yyyy-MM-dd HH:mm");
-          d.setLenient(true);
-          expression = year + "-" + month + "-" + day + " " + hour + ":" + minutes;
-
-        System.out.println(expression);
-
-        Date result = d.parse(expression);
-
-        return result;
+        return DateTimeFunctions.parseW3CDTFString(expression);
       }
       catch (Throwable t) {
+
         return null;
       }
     }
index f611f66..f9bbb52 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001, 2002  The Mir-coders group
+ * Copyright (C) 2001, 2002 The Mir-coders group
  *
  * This file is part of Mir.
  *
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with the com.oreilly.servlet library, any library
- * licensed under the Apache Software License, The Sun (tm) Java Advanced
- * Imaging library (JAI), The Sun JIMI library (or with modified versions of
- * the above that use the same license as the above), and distribute linked
- * combinations including the two.  You must obey the GNU General Public
- * License in all respects for all of the code used other than the above
- * mentioned libraries.  If you modify this file, you may extend this exception
- * to your version of the file, but you are not obligated to do so.  If you do
- * not wish to do so, delete this exception statement from your version.
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
  */
 
 package mir.rss;
@@ -36,8 +35,6 @@ import java.util.*;
 public class RSSTest {
 
   public static void main(String[] args) {
-    System.out.println("Testing...");
-
     RSSReader reader = new RSSReader();
     try {
       RSSData wvl = reader.parseUrl("http://wvl.indymedia.org/features.rdf");
diff --git a/source/mir/util/DateTimeFunctions.java b/source/mir/util/DateTimeFunctions.java
new file mode 100755 (executable)
index 0000000..4328fa0
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+package mir.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+
+public class DateTimeFunctions {
+  /**
+   * private parameter-less constructor to prevent construction
+   */
+  private DateTimeFunctions() {
+  }
+
+  /**
+   * Function to parse a <a href="http://www.w3.org/TR/NOTE-datetime">W3CDTF</a> formatted string.
+   *
+   *
+   * YYYY[-MM[-DD[Thh:mm[:ss[.s*]]TZD]]]
+   *
+   * @param aString
+   * @return
+   */
+  private final static String SPACE = "[\t\n\r ]*";
+  private final static String NUMBER = "[0-9]*";
+  private final static String TWODIGITNUMBER = "[0-9][0-9]";
+  private final static String FOURDIGITNUMBER = "[0-9][0-9][0-9][0-9]";
+  private final static String FRACTION = "(\\.[0-9]*)|)";
+  private final static String SIGN = "[-+]";
+  private final static String TZD = "(Z|(+|-)([0-9][0-9]:[0-9][0-9]|[0-9][0-9][0-9][0-9]))";
+
+  public static Date parseW3CDTFString(String aString) throws UtilExc, UtilFailure {
+    try {
+      int year = 1;
+      int month = 1;
+      int day = 1;
+      int hour = 0;
+      int minute = 0;
+      int second = 0;
+      int millisecond = 0;
+      int houroffset = 0;
+      int minuteoffset = 0;
+
+      SimpleParser parser = new SimpleParser(aString.trim());
+      String part = parser.parse(NUMBER);
+      year=Integer.parseInt(part);
+      if (parser.parses("-")) {
+        parser.skip("-");
+        part = parser.parse(NUMBER);
+        month = Integer.parseInt(part);
+        if (parser.parses("-")) {
+          parser.skip("-");
+          part = parser.parse(NUMBER);
+          day = Integer.parseInt(part);
+          if (parser.parses("T")) {
+            parser.skip("T");
+            part = parser.parse(NUMBER);
+            hour = Integer.parseInt(part);
+            parser.skip(":");
+            part = parser.parse(NUMBER);
+            minute = Integer.parseInt(part);
+            if (parser.parses(":")) {
+              parser.skip(":");
+              part = parser.parse(NUMBER);
+              second = Integer.parseInt(part);
+              if (parser.parses("\\.")) {
+                parser.skip("\\.");
+                part = parser.parse(NUMBER).substring(0,3);
+                while (part.length()<3)
+                  part = "0" + part;
+                millisecond = Integer.parseInt(part);
+              }
+            }
+            if (parser.parses("Z|\\+|-")) {
+              String sign = parser.parse("Z|\\+|-");
+              if (sign.equals("+") || sign.equals("-")) {
+                if (parser.parses(TWODIGITNUMBER)) {
+                  part = parser.parse(TWODIGITNUMBER);
+                  houroffset = Integer.parseInt(part);
+                }
+                if (parser.parses(":"))
+                  parser.skip(":");
+                if (parser.parses(TWODIGITNUMBER)) {
+                  part = parser.parse(TWODIGITNUMBER);
+                  minuteoffset = Integer.parseInt(part);
+                }
+
+                if (sign.equals("-")) {
+                  houroffset = -houroffset;
+                  minuteoffset = - minuteoffset;
+                }
+              }
+            }
+
+
+          }
+        }
+      }
+
+
+      String[] ids = TimeZone.getAvailableIDs((houroffset * 60 + minuteoffset) * 60 * 1000);
+      String timeZoneID = "custom";
+      if (ids.length != 0)
+        timeZoneID = ids[0];
+      SimpleTimeZone pdt = new SimpleTimeZone((houroffset * 60 + minuteoffset) * 60 * 1000, timeZoneID);
+
+      Calendar calendar = new GregorianCalendar(pdt);
+      calendar.set(year, month, day, hour, minute, second);
+      calendar.set(Calendar.MILLISECOND, millisecond);
+
+      System.out.println(aString + " -> " + new SimpleDateFormat("yyyy-dd-MM HH:mm Z").format(calendar.getTime()));
+
+      return calendar.getTime();
+    }
+    catch (Throwable t) {
+      System.out.println(aString + " -> " + t.toString());
+
+      throw new UtilFailure(t);
+    }
+  }
+}
\ No newline at end of file