svn commit: r1298246 - in /cocoon/cocoon3/trunk/cocoon-optional/src: main/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/ main/resources/META-INF/cocoon/spring-optional/ test/java/org/apache/cocoon/optional/pipeline/components/sax/cal...

[email protected]
Newsgroups gmane.text.xml.cocoon.cvs
Message-ID <[email protected]>
Author: thorsten
Date: Thu Mar  8 00:59:01 2012
New Revision: 1298246

URL: http://svn.apache.org/viewvc?rev=1298246&view=rev
Log:
COCOON3-91
Migrate CalendarGenerator
It is basically the same as in c2.2 but cache key is implemented c3 style.
Add a small bugfix/feature that weekdays are as well locale and not static as before.

Adding  as well basic functional test.


Added:
    cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/
    cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGenerator.java
      - copied, changed from r1298119, cocoon/trunk/core/cocoon-pipeline/cocoon-pipeline-components/src/main/java/org/apache/cocoon/generation/CalendarGenerator.java
    cocoon/cocoon3/trunk/cocoon-optional/src/test/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/
    cocoon/cocoon3/trunk/cocoon-optional/src/test/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGeneratorTest.java
Modified:
    cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml

Copied: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGenerator.java (from r1298119, cocoon/trunk/core/cocoon-pipeline/cocoon-pipeline-components/src/main/java/org/apache/cocoon/generation/CalendarGenerator.java)
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGenerator.java?p2=cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGenerator.java&p1=cocoon/trunk/core/cocoon-pipeline/cocoon-pipeline-components/src/main/java/org/apache/cocoon/generation/CalendarGenerator.java&r1=1298119&r2=1298246&rev=1298246&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-pipeline/cocoon-pipeline-components/src/main/java/org/apache/cocoon/generation/CalendarGenerator.java (original)
+++ cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGenerator.java Thu Mar  8 00:59:01 2012
@@ -14,33 +14,36 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.cocoon.generation;
+package org.apache.cocoon.optional.pipeline.components.sax.calendar;
 
-import java.io.IOException;
-import java.io.Serializable;
 import java.text.DateFormat;
+import java.text.DateFormatSymbols;
 import java.text.DecimalFormat;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
-import org.apache.avalon.framework.parameters.Parameters;
-import org.apache.cocoon.ProcessingException;
-import org.apache.cocoon.caching.CacheableProcessingComponent;
-import org.apache.cocoon.environment.SourceResolver;
-import org.apache.commons.lang.BooleanUtils;
-import org.apache.excalibur.source.SourceValidity;
-import org.apache.excalibur.source.impl.validity.NOPValidity;
+import org.apache.cocoon.pipeline.ProcessingException;
+import org.apache.cocoon.pipeline.caching.CacheKey;
+import org.apache.cocoon.pipeline.caching.ParameterCacheKey;
+import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
+import org.apache.cocoon.pipeline.components.parameters.Parameters;
+import org.apache.cocoon.sax.AbstractSAXGenerator;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
 
 /**
  * Generates an XML document representing a calendar for a given month and year.
- *
- * <p>Here is a sample output:
+ * 
+ * <p>
+ * Note for c3: Since this is a migration code the source is ATM only really usable 
+ * if you call setConfiguration(final Map<String, ? extends Object> configuration) with
+ * your custom settings since it assumes to be invoked from within a sitemap. 
+ * 
+ * <p>
+ * Here is a sample output:
+ * 
  * <pre>
  * &lt;calendar:calendar xmlns:calendar="http://apache.org/cocoon/calendar/1.0"
  *     year="2004" month="January" prevMonth="12" prevYear="2003"
@@ -54,155 +57,161 @@ import org.xml.sax.helpers.AttributesImp
  *   ...
  * &lt;/calendar:calendar&gt;
  * </pre>
- *
- * <p>The <i>src</i> parameter is ignored.
- *
+ * 
  * <p>
- *  <b>Configuration options:</b>
- *  <dl>
- *   <dt> <i>month</i> (optional)</dt>
- *   <dd> Sets the month for the calendar (January is 1). Default is the current month.</dd>
- *   <dt> <i>year</i> (optional)</dt>
- *   <dd> Sets the year for the calendar. Default is the current year.</dd>
- *   <dt> <i>dateFormat</i> (optional)</dt>
- *   <dd> Sets the format for the date attribute of each node, as
- *        described in java.text.SimpleDateFormat. If unset, the default
- *        format for the current locale will be used.</dd>
- *   <dt> <i>lang</i> (optional)</dt>
- *   <dd> Sets the ISO language code for determining the locale.</dd>
- *   <dt> <i>country</i> (optional)</dt>
- *   <dd> Sets the ISO country code for determining the locale.</dd>
- *   <dt> <i>padWeeks</i> (optional)</dt>
- *   <dd> If set to true, full weeks will be generated by adding
- *        days from the end of the previous month and the beginning
- *        of the following month.</dd>
- *  </dl>
+ * The <i>src</i> parameter is ignored.
+ * 
+ * <p>
+ * <b>Configuration options:</b>
+ * <dl>
+ * <dt><i>month</i> (optional)</dt>
+ * <dd>Sets the month for the calendar (January is 1). Default is the current
+ * month.</dd>
+ * <dt><i>year</i> (optional)</dt>
+ * <dd>Sets the year for the calendar. Default is the current year.</dd>
+ * <dt><i>dateFormat</i> (optional)</dt>
+ * <dd>Sets the format for the date attribute of each node, as described in
+ * java.text.SimpleDateFormat. If unset, the default format for the current
+ * locale will be used.</dd>
+ * <dt><i>lang</i> (optional)</dt>
+ * <dd>Sets the ISO language code for determining the locale.</dd>
+ * <dt><i>country</i> (optional)</dt>
+ * <dd>Sets the ISO country code for determining the locale.</dd>
+ * <dt><i>padWeeks</i> (optional)</dt>
+ * <dd>If set to true, full weeks will be generated by adding days from the end
+ * of the previous month and the beginning of the following month.</dd>
+ * </dl>
  * </p>
- *               
- * @cocoon.sitemap.component.documentation
- * Generates an XML document representing a calendar for a given month and year.
- * @cocoon.sitemap.component.name   calendar
- * @cocoon.sitemap.component.label  content
+ * 
+ * @cocoon.sitemap.component.documentation Generates an XML document
+ *                                         representing a calendar for a given
+ *                                         month and year.
+ * @cocoon.sitemap.component.name calendar
+ * @cocoon.sitemap.component.label content
  * @cocoon.sitemap.component.documentation.caching Yes
- *
- * @version $Id$
+ * 
  */
-public class CalendarGenerator extends ServiceableGenerator
-                               implements CacheableProcessingComponent {
-    
+public class CalendarGenerator extends AbstractSAXGenerator implements
+        CachingPipelineComponent {
+
     /** The URI of the namespace of this generator. */
     protected static final String URI = "http://apache.org/cocoon/calendar/1.0";
-    
+
     /** The namespace prefix for this namespace. */
     protected static final String PREFIX = "calendar";
-    
+
     /** Node and attribute names */
-    protected static final String CALENDAR_NODE_NAME   = "calendar";
-    protected static final String WEEK_NODE_NAME       = "week";
-    protected static final String DAY_NODE_NAME        = "day";
-    protected static final String MONTH_ATTR_NAME      = "month";
-    protected static final String YEAR_ATTR_NAME       = "year";
-    protected static final String DATE_ATTR_NAME       = "date";
-    protected static final String NUMBER_ATTR_NAME     = "number";
-    protected static final String WEEKDAY_ATTR_NAME    = "weekday";
+    protected static final String CALENDAR_NODE_NAME = "calendar";
+    protected static final String WEEK_NODE_NAME = "week";
+    protected static final String DAY_NODE_NAME = "day";
+    protected static final String MONTH_ATTR_NAME = "month";
+    protected static final String YEAR_ATTR_NAME = "year";
+    protected static final String DATE_ATTR_NAME = "date";
+    protected static final String NUMBER_ATTR_NAME = "number";
+    protected static final String WEEKDAY_ATTR_NAME = "weekday";
     protected static final String PREV_MONTH_ATTR_NAME = "prevMonth";
-    protected static final String PREV_YEAR_ATTR_NAME  = "prevYear";
+    protected static final String PREV_YEAR_ATTR_NAME = "prevYear";
     protected static final String NEXT_MONTH_ATTR_NAME = "nextMonth";
-    protected static final String NEXT_YEAR_ATTR_NAME  = "nextYear";
-    
+    protected static final String NEXT_YEAR_ATTR_NAME = "nextYear";
+
     /** Formatter for month number */
-    protected static final DecimalFormat monthNumberFormatter = new DecimalFormat("00");
-    
-    /** Convenience object, so we don't need to create an AttributesImpl for every element. */
+    protected static final DecimalFormat monthNumberFormatter = new DecimalFormat(
+            "00");
+
+    /**
+     * Convenience object, so we don't need to create an AttributesImpl for
+     * every element.
+     */
     protected AttributesImpl attributes;
-    
+
     /**
      * The cache key needs to be generated for the configuration of this
      * generator, so storing the parameters for generateKey().
      */
-    protected List cacheKeyParList;
-    
+    protected Parameters cacheKeyParList;
+
     /** The year to generate the calendar for */
     protected int year;
-    
+
     /** The month to generate the calendar for */
     protected int month;
-    
+
     /** The format for dates */
     protected DateFormat dateFormatter;
-    
+
     /** The format for month names */
     protected DateFormat monthFormatter;
-    
+
     /** The current locale */
     protected Locale locale;
-    
+
     /** Do we need to pad out the first and last weeks? */
     protected boolean padWeeks;
-    
-    /* Add the day of the week 
+
+    /*
+     * Add the day of the week
      * 
-     * since SUNDAY=1, we start with a dummy
-     * entry. 
+     * since SUNDAY=1, we start with a dummy entry.
      */
-    protected String weekdays[] = { "",
-        "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", 
-        "FRIDAY", "SATURDAY"
-    };
-	
+    protected String weekdays[] = { "", "SUNDAY", "MONDAY", "TUESDAY",
+            "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY" };
+
     /**
      * Set the request parameters. Must be called before the generate method.
-     *
-     * @param resolver     the SourceResolver object
-     * @param objectModel  a <code>Map</code> containing model object
-     * @param src          the source URI (ignored)
-     * @param par          configuration parameters
+     * 
+     * @param resolver
+     *            the SourceResolver object
+     * @param objectModel
+     *            a <code>Map</code> containing model object
+     * @param src
+     *            the source URI (ignored)
+     * @param par
+     *            configuration parameters
      */
-    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par)
-    throws ProcessingException, SAXException, IOException {
-        super.setup(resolver, objectModel, src, par);
-        
-        this.cacheKeyParList = new ArrayList();
-        this.cacheKeyParList.add(src);
+    @Override
+    public void setConfiguration(
+            final Map<String, ? extends Object> configuration) {
 
+        this.cacheKeyParList = new Parameters(configuration);
         // Determine the locale
-        String langString = par.getParameter("lang", null);
+        String langString = cacheKeyParList.get("lang", null);
         locale = Locale.getDefault();
         if (langString != null) {
-            this.cacheKeyParList.add(langString);
-            String countryString = par.getParameter("country", "");
-            if (! "".equals(countryString)) {
-                this.cacheKeyParList.add(countryString);
-            }
+            String countryString = cacheKeyParList.get("country", "");
             locale = new Locale(langString, countryString);
         }
-        
+
         // Determine year and month. Default is current year and month.
         Calendar now = Calendar.getInstance(locale);
-        this.year = par.getParameterAsInteger("year", now.get(Calendar.YEAR));
-        this.cacheKeyParList.add(String.valueOf(this.year));
-        this.month = par.getParameterAsInteger("month", now.get(Calendar.MONTH) + 1) - 1;
-        this.cacheKeyParList.add(String.valueOf(this.month));
-        
-        String dateFormatString = par.getParameter("dateFormat", null);
-        this.cacheKeyParList.add(dateFormatString);
+        this.year = cacheKeyParList.getAsInteger("year", now.get(Calendar.YEAR));
+        this.month = cacheKeyParList.getAsInteger("month", now.get(Calendar.MONTH) + 1) - 1;
+        String dateFormatString = cacheKeyParList.get("dateFormat", null);
         if (dateFormatString != null) {
             this.dateFormatter = new SimpleDateFormat(dateFormatString, locale);
         } else {
-            this.dateFormatter = DateFormat.getDateInstance(DateFormat.LONG, locale);
+            this.dateFormatter = DateFormat.getDateInstance(DateFormat.LONG,
+                    locale);
         }
-        this.padWeeks = par.getParameterAsBoolean("padWeeks", false);
-        this.cacheKeyParList.add(BooleanUtils.toBooleanObject(this.padWeeks));
-        this.monthFormatter = new SimpleDateFormat("MMMM", locale);        
+        this.padWeeks = cacheKeyParList.getAsBoolean("padWeeks", false);
+        this.monthFormatter = new SimpleDateFormat("MMMM", locale);
+        DateFormatSymbols dfs = new DateFormatSymbols(locale);
+        weekdays = dfs.getWeekdays();
         this.attributes = new AttributesImpl();
     }
-    
+
+    @Override
+    public CacheKey constructCacheKey() {
+        CacheKey key = new ParameterCacheKey(this.cacheKeyParList.export());
+        return key;
+    }
+
     /**
      * Generate XML data.
-     *
-     * @throws  SAXException if an error occurs while outputting the document
+     * 
+     * @throws SAXException
+     *             if an error occurs while outputting the document
      */
-    public void generate() throws SAXException, ProcessingException {
+    public void execute() throws ProcessingException {
         Calendar start = Calendar.getInstance(locale);
         start.clear();
         start.set(Calendar.YEAR, this.year);
@@ -214,143 +223,147 @@ public class CalendarGenerator extends S
         // Determine previous and next months
         Calendar prevMonth = (Calendar) start.clone();
         prevMonth.add(Calendar.MONTH, -1);
-        
-        this.contentHandler.startDocument();
-        this.contentHandler.startPrefixMapping(PREFIX, URI);
-        attributes.clear();
-        attributes.addAttribute("", YEAR_ATTR_NAME, YEAR_ATTR_NAME, "CDATA", String.valueOf(year));
-        attributes.addAttribute("", MONTH_ATTR_NAME, MONTH_ATTR_NAME, "CDATA", 
-                monthFormatter.format(start.getTime()));
-        
-        // Add previous and next month
-        attributes.addAttribute("", PREV_YEAR_ATTR_NAME, PREV_YEAR_ATTR_NAME, "CDATA", 
-                String.valueOf(prevMonth.get(Calendar.YEAR)));
-        attributes.addAttribute("", PREV_MONTH_ATTR_NAME, PREV_MONTH_ATTR_NAME, "CDATA", 
-                monthNumberFormatter.format(prevMonth.get(Calendar.MONTH) + 1));
-        attributes.addAttribute("", NEXT_YEAR_ATTR_NAME, NEXT_YEAR_ATTR_NAME, "CDATA", 
-                String.valueOf(end.get(Calendar.YEAR)));
-        attributes.addAttribute("", NEXT_MONTH_ATTR_NAME, NEXT_MONTH_ATTR_NAME, "CDATA", 
-                monthNumberFormatter.format(end.get(Calendar.MONTH) + 1));
-
-        this.contentHandler.startElement(URI, CALENDAR_NODE_NAME,
-                PREFIX + ':' + CALENDAR_NODE_NAME, attributes);
-        int weekNo = start.get(Calendar.WEEK_OF_MONTH);
-        int firstDay = start.getFirstDayOfWeek();
-        if (start.get(Calendar.DAY_OF_WEEK) != firstDay) {
+        try {
+            this.getSAXConsumer().startDocument();
+            this.getSAXConsumer().startPrefixMapping(PREFIX, URI);
             attributes.clear();
-            attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA", String.valueOf(weekNo));
-            this.contentHandler.startElement(URI, WEEK_NODE_NAME,
-                    PREFIX + ':' + WEEK_NODE_NAME, attributes);
-            if (padWeeks) {
-                Calendar previous = (Calendar) start.clone();
-                while (previous.get(Calendar.DAY_OF_WEEK) != firstDay) {
-                    previous.add(Calendar.DAY_OF_MONTH, -1);		
-                }
-                while (previous.before(start)) {
-                    attributes.clear();
-                    attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA",
-                            String.valueOf(previous.get(Calendar.DAY_OF_MONTH)));
-                    attributes.addAttribute("", WEEKDAY_ATTR_NAME, WEEKDAY_ATTR_NAME, "CDATA",
-                            weekdays[previous.get(Calendar.DAY_OF_WEEK)]);
-                    attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME, "CDATA",
-                            dateFormatter.format(previous.getTime()));
-                    this.contentHandler.startElement(URI, DAY_NODE_NAME,
-                            PREFIX + ':' + DAY_NODE_NAME, attributes);
-                    addContent(previous, locale);
-                    this.contentHandler.endElement(URI, DAY_NODE_NAME,
-                            PREFIX + ':' + DAY_NODE_NAME);
-                    previous.add(Calendar.DAY_OF_MONTH, 1); 
-                } 
-            }
-        }
-        while (start.before(end)) {
-            if (start.get(Calendar.DAY_OF_WEEK) == firstDay) {
-                weekNo = start.get(Calendar.WEEK_OF_MONTH);
+            attributes.addAttribute("", YEAR_ATTR_NAME, YEAR_ATTR_NAME,
+                    "CDATA", String.valueOf(year));
+            attributes.addAttribute("", MONTH_ATTR_NAME, MONTH_ATTR_NAME,
+                    "CDATA", monthFormatter.format(start.getTime()));
+
+            // Add previous and next month
+            attributes.addAttribute("", PREV_YEAR_ATTR_NAME,
+                    PREV_YEAR_ATTR_NAME, "CDATA",
+                    String.valueOf(prevMonth.get(Calendar.YEAR)));
+            attributes.addAttribute("", PREV_MONTH_ATTR_NAME,
+                    PREV_MONTH_ATTR_NAME, "CDATA", monthNumberFormatter
+                            .format(prevMonth.get(Calendar.MONTH) + 1));
+            attributes.addAttribute("", NEXT_YEAR_ATTR_NAME,
+                    NEXT_YEAR_ATTR_NAME, "CDATA",
+                    String.valueOf(end.get(Calendar.YEAR)));
+            attributes.addAttribute("", NEXT_MONTH_ATTR_NAME,
+                    NEXT_MONTH_ATTR_NAME, "CDATA",
+                    monthNumberFormatter.format(end.get(Calendar.MONTH) + 1));
+
+            this.getSAXConsumer().startElement(URI, CALENDAR_NODE_NAME,
+                    PREFIX + ':' + CALENDAR_NODE_NAME, attributes);
+            int weekNo = start.get(Calendar.WEEK_OF_MONTH);
+            int firstDay = start.getFirstDayOfWeek();
+            if (start.get(Calendar.DAY_OF_WEEK) != firstDay) {
                 attributes.clear();
-                attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA", String.valueOf(weekNo));
-                this.contentHandler.startElement(URI, WEEK_NODE_NAME,
+                attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME,
+                        "CDATA", String.valueOf(weekNo));
+                this.getSAXConsumer().startElement(URI, WEEK_NODE_NAME,
                         PREFIX + ':' + WEEK_NODE_NAME, attributes);
+                if (padWeeks) {
+                    Calendar previous = (Calendar) start.clone();
+                    while (previous.get(Calendar.DAY_OF_WEEK) != firstDay) {
+                        previous.add(Calendar.DAY_OF_MONTH, -1);
+                    }
+                    while (previous.before(start)) {
+                        attributes.clear();
+                        attributes.addAttribute("", NUMBER_ATTR_NAME,
+                                NUMBER_ATTR_NAME, "CDATA", String
+                                        .valueOf(previous
+                                                .get(Calendar.DAY_OF_MONTH)));
+                        attributes.addAttribute("", WEEKDAY_ATTR_NAME,
+                                WEEKDAY_ATTR_NAME, "CDATA",
+                                weekdays[previous.get(Calendar.DAY_OF_WEEK)]);
+                        attributes.addAttribute("", DATE_ATTR_NAME,
+                                DATE_ATTR_NAME, "CDATA",
+                                dateFormatter.format(previous.getTime()));
+                        this.getSAXConsumer().startElement(URI, DAY_NODE_NAME,
+                                PREFIX + ':' + DAY_NODE_NAME, attributes);
+                        addContent(previous, locale);
+                        this.getSAXConsumer().endElement(URI, DAY_NODE_NAME,
+                                PREFIX + ':' + DAY_NODE_NAME);
+                        previous.add(Calendar.DAY_OF_MONTH, 1);
+                    }
+                }
             }
-            attributes.clear();
-            attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA",
-                    String.valueOf(start.get(Calendar.DAY_OF_MONTH)));
-            attributes.addAttribute("", WEEKDAY_ATTR_NAME, WEEKDAY_ATTR_NAME, "CDATA",
-                    weekdays[start.get(Calendar.DAY_OF_WEEK)]);
-            attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME, "CDATA",
-                    dateFormatter.format(start.getTime()));
-            this.contentHandler.startElement(URI, DAY_NODE_NAME,
-                    PREFIX + ':' + DAY_NODE_NAME, attributes);
-            addContent(start, locale);
-            this.contentHandler.endElement(URI, DAY_NODE_NAME,
-                    PREFIX + ':' + DAY_NODE_NAME);
-            start.add(Calendar.DAY_OF_MONTH, 1);
-            if (start.get(Calendar.DAY_OF_WEEK) == firstDay
-                    || (!padWeeks && ! start.before(end))) {
-                this.contentHandler.endElement(URI, WEEK_NODE_NAME,
-                        PREFIX + ':' + WEEK_NODE_NAME);
-            }
-        }
-        
-        if (padWeeks) {
-            while (firstDay != end.get(Calendar.DAY_OF_WEEK)) {
+            while (start.before(end)) {
+                if (start.get(Calendar.DAY_OF_WEEK) == firstDay) {
+                    weekNo = start.get(Calendar.WEEK_OF_MONTH);
+                    attributes.clear();
+                    attributes.addAttribute("", NUMBER_ATTR_NAME,
+                            NUMBER_ATTR_NAME, "CDATA", String.valueOf(weekNo));
+                    this.getSAXConsumer().startElement(URI, WEEK_NODE_NAME,
+                            PREFIX + ':' + WEEK_NODE_NAME, attributes);
+                }
                 attributes.clear();
-                attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME, "CDATA",
-                        String.valueOf(end.get(Calendar.DAY_OF_MONTH)));
-                attributes.addAttribute("", WEEKDAY_ATTR_NAME, WEEKDAY_ATTR_NAME, "CDATA",
-                        weekdays[end.get(Calendar.DAY_OF_WEEK)]);
-                attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME, "CDATA",
-                        dateFormatter.format(end.getTime()));
-                this.contentHandler.startElement(URI, DAY_NODE_NAME,
+                attributes.addAttribute("", NUMBER_ATTR_NAME, NUMBER_ATTR_NAME,
+                        "CDATA",
+                        String.valueOf(start.get(Calendar.DAY_OF_MONTH)));
+                attributes.addAttribute("", WEEKDAY_ATTR_NAME,
+                        WEEKDAY_ATTR_NAME, "CDATA",
+                        weekdays[start.get(Calendar.DAY_OF_WEEK)]);
+                attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME,
+                        "CDATA", dateFormatter.format(start.getTime()));
+                this.getSAXConsumer().startElement(URI, DAY_NODE_NAME,
                         PREFIX + ':' + DAY_NODE_NAME, attributes);
-                addContent(end, locale);
-                this.contentHandler.endElement(URI, DAY_NODE_NAME,
+                addContent(start, locale);
+                this.getSAXConsumer().endElement(URI, DAY_NODE_NAME,
                         PREFIX + ':' + DAY_NODE_NAME);
-                end.add(Calendar.DAY_OF_MONTH, 1); 		
-                if (firstDay == end.get(Calendar.DAY_OF_WEEK)) { 
-                        this.contentHandler.endElement(URI, WEEK_NODE_NAME,
-	                       PREFIX + ':' + WEEK_NODE_NAME);
+                start.add(Calendar.DAY_OF_MONTH, 1);
+                if (start.get(Calendar.DAY_OF_WEEK) == firstDay
+                        || (!padWeeks && !start.before(end))) {
+                    this.getSAXConsumer().endElement(URI, WEEK_NODE_NAME,
+                            PREFIX + ':' + WEEK_NODE_NAME);
                 }
             }
-        }
-        this.contentHandler.endElement(URI, CALENDAR_NODE_NAME,
-                PREFIX + ':' + CALENDAR_NODE_NAME);
-        this.contentHandler.endPrefixMapping(PREFIX);
-        this.contentHandler.endDocument();
-    }
-    
-    /**
-     * Add content to a &lt;day&gt; element. This method is intended to be overridden
-     * by subclasses that want to add content to one or more days of the calendar.
-     * 
-     * @param date   The date corresponding to the current element.
-     * @param locale The current locale.
-     * @throws SAXException if an error occurs while outputting the document
-     */
-    protected void addContent(Calendar date, Locale locale) throws SAXException {}
 
-    /**
-     * @see org.apache.cocoon.caching.CacheableProcessingComponent#getKey()
-     */
-    public Serializable getKey() {
-        StringBuffer buffer = new StringBuffer();
-        int len = this.cacheKeyParList.size();
-        for (int i = 0; i < len; i++) {
-            buffer.append(this.cacheKeyParList.get(i)).append(":");
+            if (padWeeks) {
+                while (firstDay != end.get(Calendar.DAY_OF_WEEK)) {
+                    attributes.clear();
+                    attributes.addAttribute("", NUMBER_ATTR_NAME,
+                            NUMBER_ATTR_NAME, "CDATA",
+                            String.valueOf(end.get(Calendar.DAY_OF_MONTH)));
+                    attributes.addAttribute("", WEEKDAY_ATTR_NAME,
+                            WEEKDAY_ATTR_NAME, "CDATA",
+                            weekdays[end.get(Calendar.DAY_OF_WEEK)]);
+                    attributes.addAttribute("", DATE_ATTR_NAME, DATE_ATTR_NAME,
+                            "CDATA", dateFormatter.format(end.getTime()));
+                    this.getSAXConsumer().startElement(URI, DAY_NODE_NAME,
+                            PREFIX + ':' + DAY_NODE_NAME, attributes);
+                    addContent(end, locale);
+                    this.getSAXConsumer().endElement(URI, DAY_NODE_NAME,
+                            PREFIX + ':' + DAY_NODE_NAME);
+                    end.add(Calendar.DAY_OF_MONTH, 1);
+                    if (firstDay == end.get(Calendar.DAY_OF_WEEK)) {
+                        this.getSAXConsumer().endElement(URI, WEEK_NODE_NAME,
+                                PREFIX + ':' + WEEK_NODE_NAME);
+                    }
+                }
+            }
+            this.getSAXConsumer().endElement(URI, CALENDAR_NODE_NAME,
+                    PREFIX + ':' + CALENDAR_NODE_NAME);
+            this.getSAXConsumer().endPrefixMapping(PREFIX);
+            this.getSAXConsumer().endDocument();
+        } catch (Exception e) {
+            throw new ProcessingException("Could not create calendar ", e);
         }
-
-        return buffer.toString();
     }
-    
+
     /**
-     * @see org.apache.cocoon.caching.CacheableProcessingComponent#getValidity()
+     * Add content to a &lt;day&gt; element. This method is intended to be
+     * overridden by subclasses that want to add content to one or more days of
+     * the calendar.
+     * 
+     * @param date
+     *            The date corresponding to the current element.
+     * @param locale
+     *            The current locale.
+     * @throws SAXException
+     *             if an error occurs while outputting the document
      */
-    public SourceValidity getValidity() {
-        return NOPValidity.SHARED_INSTANCE;
+    protected void addContent(Calendar date, Locale locale) throws SAXException {
     }
-    
+
     /**
      * Recycle resources
-     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
+     * 
+     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle() for traditional background history. Keeping it for handyniess 
      */
     public void recycle() {
         this.cacheKeyParList = null;
@@ -358,6 +371,5 @@ public class CalendarGenerator extends S
         this.dateFormatter = null;
         this.monthFormatter = null;
         this.locale = null;
-        super.recycle();
     }
-}
+}
\ No newline at end of file

Modified: cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml?rev=1298246&r1=1298245&r2=1298246&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml (original)
+++ cocoon/cocoon3/trunk/cocoon-optional/src/main/resources/META-INF/cocoon/spring-optional/cocoon-optional-generators.xml Thu Mar  8 00:59:01 2012
@@ -24,5 +24,6 @@
   <bean name="generator:dir" class="org.apache.cocoon.optional.pipeline.components.sax.directory.DirectoryGenerator" scope="prototype" />
   <bean name="generator:html" class="org.apache.cocoon.optional.pipeline.components.sax.neko.NekoGenerator" scope="prototype" />
   <bean name="generator:csv" class="org.apache.cocoon.optional.pipeline.components.sax.csv.CSVGenerator" scope="prototype" />
+  <bean name="generator:calendar" class="org.apache.cocoon.optional.pipeline.components.sax.calendar.CalendarGenerator" scope="prototype" />
 
 </beans>

Added: cocoon/cocoon3/trunk/cocoon-optional/src/test/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGeneratorTest.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-optional/src/test/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGeneratorTest.java?rev=1298246&view=auto
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-optional/src/test/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGeneratorTest.java (added)
+++ cocoon/cocoon3/trunk/cocoon-optional/src/test/java/org/apache/cocoon/optional/pipeline/components/sax/calendar/CalendarGeneratorTest.java Thu Mar  8 00:59:01 2012
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.optional.pipeline.components.sax.calendar;
+
+import static org.custommonkey.xmlunit.XMLAssert.assertNodeTestPasses;
+
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cocoon.pipeline.NonCachingPipeline;
+import org.apache.cocoon.pipeline.Pipeline;
+import org.apache.cocoon.sax.SAXPipelineComponent;
+import org.apache.cocoon.sax.component.XMLSerializer;
+import org.custommonkey.xmlunit.examples.CountingNodeTester;
+import org.junit.Test;
+import org.w3c.dom.Node;
+
+public class CalendarGeneratorTest {
+
+    @Test
+    public void testPipelineWithCalendarGenerator() throws Exception {
+        Pipeline<SAXPipelineComponent> pipeline = new NonCachingPipeline<SAXPipelineComponent>();
+        CalendarGenerator generator  = new CalendarGenerator();
+        Map<String, Object> parameters = new HashMap<String, Object>();
+        parameters.put("lang", "de");
+        parameters.put("country", "DE");
+        parameters.put("year", 2012);
+        parameters.put("month", 3);
+        generator.setConfiguration(parameters);
+        pipeline.addComponent(generator);
+        pipeline.addComponent(new XMLSerializer());
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        pipeline.setup(baos);
+        pipeline.execute();
+        CountingNodeTester countingNodeTester = new CountingNodeTester(37);
+        String out = new String(baos.toByteArray());
+        System.out.println(out);
+        assertNodeTestPasses(out, countingNodeTester, Node.ELEMENT_NODE);
+    }
+
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.