You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by jh...@apache.org on 2005/11/03 15:00:48 UTC

svn commit: r330548 [88/132] - in /cocoon/whiteboard/maven2/cocoon-flat-layout: ./ cocoon-ajax-block/ cocoon-ajax-block/api/ cocoon-ajax-block/api/src/ cocoon-ajax-block/api/src/main/ cocoon-ajax-block/api/src/main/java/ cocoon-ajax-block/api/src/main/...

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManager.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManager.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManager.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManager.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.forms.binding.library;
+
+
+
+/**
+ * The work interface for the LibraryManager, the class that
+ * manages all used library definitions so they can be shared between
+ * forms.
+ * 
+ * @version $Id: LibraryManager.java 289538 2005-09-16 13:46:22Z sylvain $
+ *
+ */
+public interface LibraryManager {
+
+	String ROLE = LibraryManager.class.getName();
+	
+	Library getLibrary(String librarysource) throws Exception;
+	Library getLibrary(String librarysource, String relative) throws Exception;
+	Library getNewLibrary();
+	
+	boolean libraryInCache(String librarysource) throws Exception;
+	boolean libraryInCache(String librarysource, String relative) throws Exception;
+	
+	void debug(String msg);
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManagerImpl.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManagerImpl.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManagerImpl.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManagerImpl.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,198 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ * 
+ * Licensed 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.forms.binding.library;
+
+import org.apache.avalon.framework.CascadingException;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+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.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.forms.CacheManager;
+import org.apache.cocoon.forms.binding.JXPathBindingManager;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+/**
+ * @version $Id: LibraryManagerImpl.java 289538 2005-09-16 13:46:22Z sylvain $
+ *
+ */
+public class LibraryManagerImpl extends AbstractLogEnabled implements LibraryManager, ThreadSafe, Serviceable,
+Configurable, Initializable, Disposable {
+
+	protected static final String PREFIX = "CocoonFormBindingLibrary:";
+	
+	private ServiceManager serviceManager;
+    private Configuration configuration;
+    private CacheManager cacheManager;
+    
+    private JXPathBindingManager bindingManager;
+
+    public void configure(Configuration configuration) throws ConfigurationException {
+        this.configuration = configuration;
+        getLogger().debug("Gotten a config: top level element: "+this.configuration);
+    }
+
+    public void service(ServiceManager serviceManager) throws ServiceException {
+        this.serviceManager = serviceManager;
+        this.cacheManager = (CacheManager)serviceManager.lookup(CacheManager.ROLE);
+    }
+    
+    public void setBindingManager(JXPathBindingManager bindingManager) {
+    	this.bindingManager = bindingManager;
+    }
+    
+    public void initialize() throws Exception {
+    	
+        // read config to "preload" libraries
+    }
+    
+    public boolean libraryInCache(String librarysource) throws Exception {
+    	return libraryInCache(librarysource,null);
+    }
+    
+    public boolean libraryInCache(String librarysource, String relative) throws Exception {
+    	SourceResolver sourceResolver = null;
+        Source source = null;
+        
+        if(getLogger().isDebugEnabled())
+        	getLogger().debug("Checking if library is in cache: '"+librarysource+"' relative to '"+relative+"'");
+
+        Library lib = null;
+        boolean result = false;
+        
+        try {
+            sourceResolver = (SourceResolver)serviceManager.lookup(SourceResolver.ROLE);
+            source = sourceResolver.resolveURI(librarysource, relative, null);
+            
+            lib = (Library)this.cacheManager.get(source, PREFIX);
+            
+            if( lib != null && lib.dependenciesHaveChanged() ) {
+            	result = false;
+            	this.cacheManager.set(null,source,PREFIX); //evict?
+            }
+            else if( lib == null )
+            	result = false;
+            else
+            	result = true;
+        } catch(Exception e) {
+        	if(getLogger().isErrorEnabled())
+            	getLogger().error("Problem getting library '"+librarysource+"' relative to '"+relative+"'!",e);
+        	throw e;
+        } finally {
+            if (source != null)
+                sourceResolver.release(source);
+            if (sourceResolver != null)
+            	serviceManager.release(sourceResolver);
+        }
+
+        if(getLogger().isDebugEnabled()) {
+        	if(result)
+        		getLogger().debug("Library IS in cache : '"+librarysource+"' relative to '"+relative+"'");
+        	else
+        		getLogger().debug("Library IS NOT in cache : '"+librarysource+"' relative to '"+relative+"'");
+        }
+        
+        return result;
+    }
+    
+    public Library getLibrary(String librarysource) throws Exception {
+    	return getLibrary(librarysource,null);
+    }
+    
+	public Library getLibrary(String librarysource, String relative) throws Exception {
+		SourceResolver sourceResolver = null;
+        Source source = null;
+        Document libraryDocument = null;
+
+        Library lib = null;
+        
+        if(getLogger().isDebugEnabled())
+        	getLogger().debug("Getting library instance: '"+librarysource+"' relative to '"+relative+"'");
+        
+        try {
+            sourceResolver = (SourceResolver)serviceManager.lookup(SourceResolver.ROLE);
+            source = sourceResolver.resolveURI(librarysource, relative, null);
+            
+            lib = (Library)this.cacheManager.get(source, PREFIX);
+            
+            if( lib != null && lib.dependenciesHaveChanged() ) {
+            	if(getLogger().isDebugEnabled())
+                	getLogger().debug("Library dependencies changed, invalidating!");
+            	
+            	lib = null;
+            }
+            
+            if( lib == null ) {
+            	if(getLogger().isDebugEnabled())
+                	getLogger().debug("Library not in cache, creating!");
+            	
+            	try {
+                    InputSource inputSource = new InputSource(source.getInputStream());
+                    inputSource.setSystemId(source.getURI());
+                    libraryDocument = DomHelper.parse(inputSource, this.serviceManager);
+                    
+                    lib = getNewLibrary();
+                    lib.buildLibrary(libraryDocument.getDocumentElement());
+                    
+                    this.cacheManager.set(lib,source,PREFIX);
+                    
+                } catch (Exception e) {
+                    throw new CascadingException("Could not parse form definition from " +
+                                                 source.getURI(), e);
+                }
+            }
+        } finally {
+            if (source != null)
+                sourceResolver.release(source);
+            if (sourceResolver != null)
+            	serviceManager.release(sourceResolver);
+        }
+
+        return lib;
+	}
+	
+	public Library getNewLibrary() {
+		Library lib = new Library(this);
+		lib.setAssistant(this.bindingManager.getBuilderAssistant());
+        
+        if(getLogger().isDebugEnabled())
+        	getLogger().debug("Created new library! "+lib);
+        
+        return lib;
+	}
+
+	public void dispose() {
+		this.serviceManager.release(this.cacheManager);
+	    this.cacheManager = null;
+	    this.serviceManager = null;
+	}
+	
+	public void debug(String msg) {
+		if(getLogger().isDebugEnabled()) {
+			getLogger().debug(msg);
+		}
+	}
+	
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/binding/library/LibraryManagerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/AbstractJavaSelectionList.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/AbstractJavaSelectionList.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/AbstractJavaSelectionList.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/AbstractJavaSelectionList.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,215 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.forms.datatype;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.forms.FormsConstants;
+import org.apache.cocoon.forms.datatype.convertor.Convertor;
+import org.apache.cocoon.forms.datatype.convertor.DefaultFormatCache;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.XMLUtils;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.apache.excalibur.xml.sax.XMLizable;
+
+/**
+ * Abstract implementation of a JavaSelectionList
+ */
+public abstract class AbstractJavaSelectionList implements JavaSelectionList,
+                                                           Serviceable {
+
+    protected Datatype datatype;
+    protected ServiceManager manager;
+
+    private HashMap attributes;
+    private List items;
+    private boolean nullable;
+    private boolean rebuild;
+
+    public AbstractJavaSelectionList() {
+        this.items = new ArrayList();
+        this.rebuild = true;
+    }
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    public String getAttribute(String name) {
+        if (this.attributes == null) {
+            return null;
+        }
+        return (String) this.attributes.get(name);
+    }
+
+    public void removeAttribute(String name) {
+        if (this.attributes != null) {
+            this.attributes.remove(name);
+        }
+    }
+
+    public void setAttribute(String name, String value) {
+        if (this.attributes == null) {
+            this.attributes = new HashMap();
+        }
+        this.attributes.put(name, value);
+    }
+
+    public boolean isNullable() {
+        return this.nullable;
+    }
+
+    public void setDatatype(Datatype datatype) {
+        this.datatype = datatype;
+    }
+
+    public void setNullable(boolean nullable) {
+        this.nullable = nullable;
+    }
+
+    public Datatype getDatatype() {
+        return this.datatype;
+    }
+
+    /**
+     * Enforce one rebuild on next usage of #generateSaxFragment(ContentHandler, Locale).
+     */
+    public void markForRebuild() {
+        this.rebuild = true;
+    }
+
+    public void generateSaxFragment(ContentHandler contentHandler, Locale locale)
+    throws SAXException {
+        if (this.rebuild) {
+            try {
+                this.items.clear();
+                this.rebuild = build();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        Convertor.FormatCache formatCache = new DefaultFormatCache();
+        contentHandler.startElement(FormsConstants.INSTANCE_NS, SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON + SELECTION_LIST_EL, XMLUtils.EMPTY_ATTRIBUTES);
+
+        if (this.nullable) {
+            AttributesImpl voidAttrs = new AttributesImpl();
+            voidAttrs.addCDATAAttribute("value", "");
+            contentHandler.startElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL, voidAttrs);
+            contentHandler.endElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL);
+        }
+
+        Iterator itemIt = items.iterator();
+        while (itemIt.hasNext()) {
+            SelectionListItem item = (SelectionListItem) itemIt.next();
+            item.generateSaxFragment(contentHandler, locale, formatCache);
+        }
+
+        contentHandler.endElement(FormsConstants.INSTANCE_NS, SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON + SELECTION_LIST_EL);
+    }
+
+    /**
+     * Build the list of SelectionListItems using #addItem(Object, String).
+     * @return <code>true</code> if the list should be rebuild on each usage,
+     *         <code>false</code> if it is static.
+     */
+    protected abstract boolean build() throws Exception;
+
+    /**
+     * Adds a new item to this selection list.
+     *
+     * @param value
+     *            a value of the correct type (i.e. the type with which this
+     *            selectionlist is associated)
+     * @param label
+     *            string label, can be null.
+     */
+    protected void addItem(Object value, String label) {
+        this.items.add(new SelectionListItem(value, label));
+    }
+
+    /**
+     * Adds a new item to this selection list.
+     *
+     * @param value
+     *            a value of the correct type (i.e. the type with which this
+     *            selectionlist is associated)
+     * @param label
+     *            a SAX-fragment such as a
+     *            {@link org.apache.cocoon.xml.SaxBuffer}, can be null
+     */
+    protected void addItem(Object value, XMLizable label) {
+        this.items.add(new SelectionListItem(value, label));
+    }
+
+    protected List getItems() {
+        return this.items;
+    }
+
+    private final class SelectionListItem {
+        private final Object value;
+
+        private final Object label;
+
+        public SelectionListItem(Object value, String label) {
+            this.value = value;
+            this.label = label;
+        }
+
+        public SelectionListItem(Object value, XMLizable label) {
+            this.value = value;
+            this.label = label;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public void generateSaxFragment(ContentHandler contentHandler,
+                                        Locale locale, Convertor.FormatCache formatCache)
+        throws SAXException {
+            String stringValue;
+            if (this.value == null) {
+                stringValue = "";
+            } else {
+                stringValue = datatype.getConvertor().convertToString(this.value, locale, formatCache);
+            }
+
+            AttributesImpl attrs = new AttributesImpl();
+            attrs.addCDATAAttribute("value", stringValue);
+            contentHandler.startElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL, attrs);
+            contentHandler.startElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL, XMLUtils.EMPTY_ATTRIBUTES);
+            if (this.label == null) {
+                contentHandler.characters(stringValue.toCharArray(), 0, stringValue.length());
+            } else if (this.label instanceof XMLizable) {
+                ((XMLizable) this.label).toSAX(contentHandler);
+            } else {
+                String stringLabel = (String) this.label;
+                contentHandler.characters(stringLabel.toCharArray(), 0, stringLabel.length());
+            }
+            contentHandler.endElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL);
+            contentHandler.endElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL);
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/AbstractJavaSelectionList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/Datatype.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/Datatype.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/Datatype.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/Datatype.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.forms.datatype;
+
+import org.outerj.expression.ExpressionContext;
+import org.apache.cocoon.forms.datatype.convertor.Convertor;
+import org.apache.cocoon.forms.datatype.convertor.ConversionResult;
+import org.apache.cocoon.forms.validation.ValidationError;
+import org.xml.sax.SAXException;
+import org.xml.sax.ContentHandler;
+
+import java.util.Locale;
+
+/**
+ * A Datatype encapsulates the functionality for working with specific
+ * kinds of data like integers, decimals or dates.
+ *
+ * <p>It provides:
+ * <ul>
+ *  <li>Methods for converting between String and Object representation of the data
+ *  <li>For validating the data (usually against a set of validation rules)
+ *  <li>optionally a selection list
+ * </ul>
+ *
+ * <p>Each datatype can be marked as an "arraytype". Currently, this only has an
+ * influence on the {@link #validate(Object, ExpressionContext)} method, which should in that case be passed
+ * an array of objects. See also {@link #isArrayType()}.
+ * 
+ * @version $Id: Datatype.java 178749 2005-05-27 05:18:23Z antonio $
+ */
+public interface Datatype {
+    /**
+     * Converts a string to an object of this datatype. This method uses the
+     * same {@link Convertor} as returned by the {@link #getConvertor()} method.
+     */
+    ConversionResult convertFromString(String value, Locale locale);
+
+    /**
+     * Converts an object of this datatype to a string representation.
+     * This method uses the same {@link Convertor} as returned by the
+     * {@link #getConvertor()} method.
+     */
+    String convertToString(Object value, Locale locale);
+
+    /**
+     * Returns null if validation is successful, otherwise returns a
+     * {@link ValidationError} instance.
+     *
+     * @param value  an Object of the correct type for this datatype (see
+     *               {@link #getTypeClass()}, or if {@link #isArrayType()}
+     *               returns true, an array of objects of that type.
+     */
+    ValidationError validate(Object value, ExpressionContext expressionContext);
+
+    /**
+     * Gets the class object for the type represented by this datatype. E.g. Long, String, ...
+     * The objects returned from the convertFromString* methods are of this type, and the object
+     * passed to the convertToString* or validate methods should be of this type.
+     */
+    Class getTypeClass();
+
+    /**
+     * Returns a descriptive name for the base type of this datatype,
+     * i.e. something like 'string', 'long', 'decimal', ...
+     */
+    String getDescriptiveName();
+
+    /**
+     * Indicates wether this datatype represents an array type. This approach has been
+     * chosen instead of creating a seperate ArrayDatatype interface (and corresponding
+     * implementations), since almost all functionality is the same between the scalar
+     * and array types. The main difference is that the validate() method will be passed
+     * arrays instead of single values, and hence different validation rules will be
+     * required.
+     */
+    boolean isArrayType();
+
+    /**
+     * Returns the convertor used by this datatype.
+     */
+    Convertor getConvertor();
+
+    /**
+     * Returns the "plain convertor". This is convertor that should have a locale-independent
+     * string encoding, and guarantees perfect roundtripping. It is used if a value of this
+     * datatype needs to be stored but not displayed to the user.
+     */
+    Convertor getPlainConvertor();
+
+    /**
+     * Returns the factory that built this datatype.
+     */
+    DatatypeBuilder getBuilder();
+
+    /**
+     * Generates a bit of information about this datatype.
+     */
+    void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException;
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/Datatype.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.forms.datatype;
+
+import org.w3c.dom.Element;
+import org.apache.cocoon.forms.datatype.convertor.Convertor;
+
+/**
+ * Implementations of this class build a Datatype from an XML description
+ * (a DOM Element).
+ *
+ * <p>These builders should be threadsafe, only one instance of them will be created.
+ *
+ * <p>Implementations may implement Avalon's Serviceable interface to get access to
+ * other components.
+ * 
+ * @version $Id: DatatypeBuilder.java 55391 2004-10-23 18:15:02Z cziegeler $
+ */
+public interface DatatypeBuilder {
+    public Datatype build(Element datatypeElement, boolean arrayType, DatatypeManager datatypeManager) throws Exception;
+
+    public Convertor getPlainConvertor();
+
+    public Convertor buildConvertor(Element convertorEl) throws Exception;
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeManager.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeManager.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeManager.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeManager.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.forms.datatype;
+
+import org.w3c.dom.Element;
+import org.apache.cocoon.forms.datatype.convertor.Convertor;
+
+/**
+ * Work interface for the component that manages the datatypes.
+ *
+ * <p>See also {@link Datatype} and {@link DefaultDatatypeManager}.
+ * 
+ * @version $Id: DatatypeManager.java 56582 2004-11-04 10:16:22Z sylvain $
+ */
+public interface DatatypeManager {
+    
+    String ROLE = DatatypeManager.class.getName();
+
+    /**
+     * Creates a datatype from an XML description.
+     */
+    Datatype createDatatype(Element datatypeElement, boolean arrayType) throws Exception;
+
+    /**
+     * Creates a validation rule from an XML description. This will usually be used by the
+     * {@link DatatypeBuilder}s while building a {@link Datatype}.
+     */
+    ValidationRule createValidationRule(Element validationRuleElement) throws Exception;
+
+    /**
+     * Creates a convertor based on an XML description.
+     */
+    Convertor createConvertor(String dataTypeName, Element convertorElement) throws Exception;
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DatatypeManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultDatatypeManager.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultDatatypeManager.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultDatatypeManager.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultDatatypeManager.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.forms.datatype;
+
+import org.apache.avalon.framework.thread.ThreadSafe;
+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.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.CascadingException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.cocoon.forms.datatype.convertor.Convertor;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.apache.cocoon.forms.util.SimpleServiceSelector;
+import org.w3c.dom.Element;
+
+/**
+ * Implementation of the {@link DatatypeManager} component.
+ *
+ * <p>It supports an extensible number of datatype and validation rule implementations
+ * by delegating the creation of them to {@link DatatypeBuilder}s and {@link ValidationRuleBuilder}s.
+ * Currently the list of datatype and validationrule builders is hardcoded, but this will
+ * become externally configurable in the future.
+ * 
+ * @version $Id: DefaultDatatypeManager.java 56582 2004-11-04 10:16:22Z sylvain $
+ *
+ */
+public class DefaultDatatypeManager extends AbstractLogEnabled implements DatatypeManager, ThreadSafe, Serviceable,
+        Configurable, Initializable, Disposable, Contextualizable {
+    private SimpleServiceSelector typeBuilderSelector;
+    private SimpleServiceSelector validationRuleBuilderSelector;
+    private ServiceManager serviceManager;
+    private Configuration configuration;
+    private Context context;
+
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    public void configure(Configuration configuration) throws ConfigurationException {
+        this.configuration = configuration;
+    }
+
+    public void service(ServiceManager serviceManager) throws ServiceException {
+        this.serviceManager = serviceManager;
+    }
+
+    public void initialize() throws Exception {
+        typeBuilderSelector = new SimpleServiceSelector("datatype", DatatypeBuilder.class);
+        typeBuilderSelector.enableLogging(getLogger());
+        typeBuilderSelector.contextualize(context);
+        typeBuilderSelector.service(serviceManager);
+        typeBuilderSelector.configure(configuration.getChild("datatypes"));
+
+        validationRuleBuilderSelector = new SimpleServiceSelector("validation-rule", ValidationRuleBuilder.class);
+        validationRuleBuilderSelector.enableLogging(getLogger());
+        validationRuleBuilderSelector.contextualize(context);
+        validationRuleBuilderSelector.service(serviceManager);
+        validationRuleBuilderSelector.configure(configuration.getChild("validation-rules"));
+
+        configuration = null;
+    }
+
+    public Datatype createDatatype(Element datatypeElement, boolean arrayType) throws Exception {
+        String typeName = DomHelper.getAttribute(datatypeElement, "base");
+        DatatypeBuilder builder = null;
+        try {
+            builder = (DatatypeBuilder)typeBuilderSelector.select(typeName);
+        } catch (ServiceException e) {
+            throw new CascadingException("Unknown datatype '" + typeName + "' specified at " + DomHelper.getLocation(datatypeElement), e);
+        }
+        return builder.build(datatypeElement, arrayType, this);
+    }
+
+    public ValidationRule createValidationRule(Element validationRuleElement) throws Exception {
+        String name  = validationRuleElement.getLocalName();
+        ValidationRuleBuilder builder = null;
+        try {
+            builder = (ValidationRuleBuilder)validationRuleBuilderSelector.select(name);
+        } catch (ServiceException e) {
+            throw new CascadingException("Unknown validation rule \"" + name + "\" specified at " + DomHelper.getLocation(validationRuleElement), e);
+        }
+        return builder.build(validationRuleElement);
+    }
+
+    public Convertor createConvertor(String dataTypeName, Element convertorElement) throws Exception {
+        DatatypeBuilder datatypeBulder = (DatatypeBuilder)typeBuilderSelector.select(dataTypeName);
+        return datatypeBulder.buildConvertor(convertorElement);
+    }
+
+    public void dispose() {
+        typeBuilderSelector.dispose();
+        validationRuleBuilderSelector.dispose();
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultDatatypeManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultSelectionListBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultSelectionListBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultSelectionListBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultSelectionListBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,174 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.forms.datatype;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Node;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.forms.FormsConstants;
+import org.apache.cocoon.forms.datatype.convertor.Convertor;
+import org.apache.cocoon.forms.datatype.convertor.DefaultFormatCache;
+import org.apache.cocoon.forms.datatype.convertor.ConversionResult;
+import org.apache.cocoon.forms.util.DomHelper;
+import org.apache.cocoon.util.Deprecation;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import java.util.Locale;
+
+/**
+ * Builds {@link SelectionList}s from an XML description or an URL.
+ *
+ * <p>Note: the class {@link DynamicSelectionList} also interprets the same
+ * <code>fd:selection-list</code> XML, so if anything changes here to how
+ * that XML is interpreted, it also needs to change over there and vice
+ * versa.</p>
+ *
+ * @version $Id: DefaultSelectionListBuilder.java 326838 2005-10-20 06:26:53Z sylvain $
+ */
+public class DefaultSelectionListBuilder implements SelectionListBuilder, Serviceable, Contextualizable {
+
+    private ServiceManager serviceManager;
+    private Context context;
+
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    public void service(ServiceManager manager) throws ServiceException {
+        this.serviceManager = manager;
+    }
+
+    public SelectionList build(Element selectionListElement, Datatype datatype) throws Exception {
+        SelectionList selectionList;
+        String src = selectionListElement.getAttribute("src");
+        if (src.length() > 0) {
+            boolean dynamic = false;
+            boolean usePerRequestCache = false;
+            String cacheType = DomHelper.getAttribute(selectionListElement, "cache", null);
+
+            // Read @cache 
+            if ("request".equals(cacheType)) { // Dynamic SelectionList cached per request
+                dynamic = true;
+                usePerRequestCache = true;
+            } else if ("none".equals(cacheType)){ // Dynamic SelectionList non cached
+                dynamic = true;
+            } else if ("static".equals(cacheType)) {
+                // Static SelectionList (default values)
+            } else { // Checking for deprecated @dynamic
+                if (DomHelper.getAttribute(selectionListElement, "dynamic", null) != null) {
+                    Deprecation.logger.warn("'@dynamic' is deprecated in <fd:selection-list> and replaced by '@cache' at " + DomHelper.getLocation(selectionListElement));                    
+                }
+                dynamic = DomHelper.getAttributeAsBoolean(selectionListElement, "dynamic", false);
+            }
+            // Create SelectionList
+            if (dynamic) {
+                selectionList = new DynamicSelectionList(datatype, src, usePerRequestCache, serviceManager, context);
+            } else {
+                selectionListElement = readSelectionList(src);
+                selectionList = buildStaticList(selectionListElement, datatype);                
+            }
+        } else {
+            // selection list is defined inline
+            selectionList = buildStaticList(selectionListElement, datatype);
+        }
+        return selectionList;
+    }
+
+    private  SelectionList buildStaticList(Element selectionListElement, Datatype datatype) throws Exception {
+        StaticSelectionList selectionList = new StaticSelectionList(datatype);
+        Convertor convertor = null;
+        Convertor.FormatCache formatCache = new DefaultFormatCache();
+
+        NodeList children = selectionListElement.getChildNodes();
+        for (int i = 0; children.item(i) != null; i++) {
+            Node node = children.item(i);
+            if (convertor == null && node instanceof Element && FormsConstants.DEFINITION_NS.equals(node.getNamespaceURI()) && "convertor".equals(node.getLocalName())) {
+                Element convertorConfigElement = (Element)node;
+                try {
+                    convertor = datatype.getBuilder().buildConvertor(convertorConfigElement);
+                } catch (Exception e) {
+                    throw new SAXException("Error building convertor from convertor configuration embedded in selection list XML.", e);
+                }
+            } else if (node instanceof Element && FormsConstants.DEFINITION_NS.equals(node.getNamespaceURI()) && "item".equals(node.getLocalName())) {
+                if (convertor == null) {
+                    convertor = datatype.getConvertor();
+                }
+                Element element = (Element)node;
+                String stringValue = element.getAttribute("value");
+                Object value;
+                if ("".equals(stringValue)) {
+                    // Empty value translates into the null object
+                    value = null;
+                } else {
+                    ConversionResult conversionResult = convertor.convertFromString(stringValue, Locale.US, formatCache);
+                    if (!conversionResult.isSuccessful()) {
+                        throw new Exception("Could not convert the value \"" + stringValue +
+                                            "\" to the type " + datatype.getDescriptiveName() +
+                                            ", defined at " + DomHelper.getLocation(element));
+                    }
+                    value = conversionResult.getResult();
+                }
+
+                XMLizable label = null;
+                Element labelEl = DomHelper.getChildElement(element, FormsConstants.DEFINITION_NS, "label");
+                if (labelEl != null) {
+                    label = DomHelper.compileElementContent(labelEl);
+                }
+                selectionList.addItem(value, label);
+            }
+        }
+
+        return selectionList;
+    }
+
+    private Element readSelectionList(String src) throws Exception {
+        SourceResolver resolver = null;
+        Source source = null;
+        try {
+            resolver = (SourceResolver)serviceManager.lookup(SourceResolver.ROLE);
+            source = resolver.resolveURI(src);
+            InputSource inputSource = new InputSource(source.getInputStream());
+            inputSource.setSystemId(source.getURI());
+            Document document = DomHelper.parse(inputSource, this.serviceManager);
+            Element selectionListElement = document.getDocumentElement();
+            if (!FormsConstants.DEFINITION_NS.equals(selectionListElement.getNamespaceURI()) ||
+                    !"selection-list".equals(selectionListElement.getLocalName())) {
+                throw new Exception("Expected a fd:selection-list element at " +
+                                    DomHelper.getLocation(selectionListElement));
+            }
+
+            return selectionListElement;
+        } finally {
+            if (resolver != null) {
+                if (source != null) {
+                    resolver.release(source);
+                }
+                serviceManager.release(resolver);
+            }
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DefaultSelectionListBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DynamicSelectionList.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DynamicSelectionList.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DynamicSelectionList.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DynamicSelectionList.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,367 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.forms.datatype;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.Attributes;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.source.Source;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.forms.FormsConstants;
+import org.apache.cocoon.forms.datatype.convertor.Convertor;
+import org.apache.cocoon.forms.datatype.convertor.DefaultFormatCache;
+import org.apache.cocoon.forms.datatype.convertor.ConversionResult;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.AbstractXMLPipe;
+import org.apache.cocoon.xml.SaxBuffer;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.w3c.dom.Element;
+
+import java.io.IOException;
+import java.rmi.server.UID;
+import java.util.Enumeration;
+import java.util.Locale;
+
+/**
+ * SelectionList implementation that always reads its content from the source
+ * each time it is requested.
+ *
+ * <p>Note: the class {@link SelectionListBuilder} also interprets the same
+ * <code>fd:selection-list</code> XML, so if anything changes here to how that
+ * XML is interpreted, it also needs to change over there and vice versa.</p>
+ *
+ * @version $Id: DynamicSelectionList.java 326838 2005-10-20 06:26:53Z sylvain $
+ */
+public class DynamicSelectionList implements SelectionList {
+    private String src;
+    private boolean usePerRequestCache;
+    private Datatype datatype;
+    private ServiceManager serviceManager;
+    private Context context;
+
+    /**
+     * @param datatype
+     * @param src
+     * @param usePerRequestCache 
+     * @param serviceManager
+     * @param context
+     */
+    public DynamicSelectionList(Datatype datatype, String src, boolean usePerRequestCache, ServiceManager serviceManager, Context context) {
+        this.datatype = datatype;
+        this.src = src;
+        this.serviceManager = serviceManager;
+        this.usePerRequestCache = usePerRequestCache;
+        this.context = context;
+    }
+
+    /**
+     * Creates a DynamicSelectionList without caching
+     * @param datatype - 
+     * @param src - 
+     * @param serviceManager -
+     */
+    public DynamicSelectionList(Datatype datatype, String src, ServiceManager serviceManager) {
+        this.usePerRequestCache = false;
+        this.context = null;
+        this.datatype = datatype;
+        this.src = src;
+        this.serviceManager = serviceManager;
+    }
+
+    public Datatype getDatatype() {
+        return datatype;
+    }
+
+    /*
+     * This method is only used by a test case and by the public version
+     * of generateSaxFragment.
+     */
+    void generateSaxFragment(ContentHandler contentHandler, Locale locale, Source source)
+    throws ProcessingException, SAXException, IOException {
+        SelectionListHandler handler = new SelectionListHandler(locale);
+        handler.setContentHandler(contentHandler);
+        SourceUtil.toSAX(serviceManager, source, null, handler);
+    }
+    
+    /*
+     * This method generate SaxFragment directly from source.
+     */
+    private void generateSaxFragmentFromSrc(ContentHandler contentHandler, Locale locale) throws SAXException {
+        SourceResolver sourceResolver = null;
+        Source source = null;
+        try {
+            sourceResolver = (SourceResolver)serviceManager.lookup(SourceResolver.ROLE);
+            source = sourceResolver.resolveURI(src);
+            generateSaxFragment(contentHandler, locale, source);
+        } catch (SAXException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SAXException("Error while generating selection list: " + e.getMessage(), e);
+        } finally {
+            if (sourceResolver != null) {
+                if (source != null) {
+                    try { sourceResolver.release(source); } catch (Exception e) {}
+                }
+                serviceManager.release(sourceResolver);
+            }
+        }
+    }
+
+    public void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException {
+
+        if (usePerRequestCache) {
+            // Search the cacheID in request attributes
+            Request request = ContextHelper.getRequest(this.context);
+            Enumeration enumeration = request.getAttributeNames();
+            boolean cacheFound = false;
+            String name = null;
+            while (enumeration.hasMoreElements()) {
+                name = (String)enumeration.nextElement();
+                if (name.startsWith(src)) {
+                    cacheFound = true;
+                    break;
+                }
+            }
+            SaxBuffer saxBuffer;
+            if (cacheFound) {
+                saxBuffer = (SaxBuffer)request.getAttribute(name);
+            } else {
+                // Generate the usePerRequestCache and store in a request attribute.
+                saxBuffer = new SaxBuffer();
+                generateSaxFragmentFromSrc(saxBuffer, locale);
+                String cacheID = (new UID()).toString();
+                request.setAttribute(src + cacheID, saxBuffer);
+            }
+            // Output the stored saxBuffer to the contentHandler
+            saxBuffer.toSAX(contentHandler);
+        } else { // We don't use usePerRequestCache => re-read from the source.
+            generateSaxFragmentFromSrc(contentHandler, locale);
+        }
+    }
+
+    /**
+     * XMLConsumer used to handle selection lists generated on the fly.
+     */
+    public class SelectionListHandler extends AbstractXMLPipe {
+        private Object currentValue;
+        private String currentValueAsString;
+        private boolean hasLabel;
+        private Locale locale;
+        /** The convertor used to parse the values in the selection list. */
+        private Convertor convertor;
+        private DOMBuilder convertorConfigDOMBuilder;
+        private int convertorConfigNestingLevel = 0;
+        private Convertor.FormatCache fromFormatCache = new DefaultFormatCache();
+        private Convertor.FormatCache toFormatCache = new DefaultFormatCache();
+
+        public SelectionListHandler(Locale locale) {
+            this.locale = locale;
+        }
+
+        public void startDocument()
+                throws SAXException {
+        }
+
+        public void endDocument()
+                throws SAXException {
+        }
+
+        public void endDTD()
+                throws SAXException {
+        }
+
+        public void startDTD(String name, String publicId, String systemId)
+                throws SAXException {
+        }
+
+        public void startElement(String namespaceURI, String localName, String qName, Attributes attributes)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigNestingLevel++;
+                convertorConfigDOMBuilder.startElement(namespaceURI, localName,  qName, attributes);
+            } else if (namespaceURI.equals(FormsConstants.DEFINITION_NS)) {
+                if (localName.equals("item")) {
+                    if (convertor == null) {
+                        // if no convertor was explicitely configured, use the default one of the datatype
+                        convertor = datatype.getConvertor();
+                    }
+                    hasLabel = false;
+
+                    String unparsedValue = attributes.getValue("value");
+                    if (unparsedValue == null || "".equals(unparsedValue)) {
+                        // Empty (or null) value translates into the empty string
+                        currentValueAsString = "";
+                    } else {
+                        ConversionResult conversionResult = convertor.convertFromString(unparsedValue, locale, fromFormatCache);
+                        if (!conversionResult.isSuccessful()) {
+                            throw new SAXException("Could not interpret the following value: \"" + unparsedValue + "\".");
+                        }
+                        currentValue = conversionResult.getResult();
+                        currentValueAsString = datatype.getConvertor().convertToString(currentValue, locale, toFormatCache);
+                    }
+                    AttributesImpl attrs = new AttributesImpl();
+                    attrs.addCDATAAttribute("value", currentValueAsString);
+                    super.startElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName, attrs);
+                } else if (localName.equals("label")) {
+                    hasLabel = true;
+                    super.startElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName, attributes);
+                } else if (localName.equals("selection-list")) {
+                    super.startElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName, attributes);
+                } else if (convertor == null && localName.equals("convertor")) {
+                    // record the content of this element in a dom-tree
+                    convertorConfigDOMBuilder = new DOMBuilder();
+                    convertorConfigDOMBuilder.startElement(namespaceURI, localName, qName, attributes);
+                    convertorConfigNestingLevel++;
+                } else {
+                    super.startElement(namespaceURI, localName, qName, attributes);
+                }
+            } else {
+                super.startElement(namespaceURI, localName, qName, attributes);
+            }
+        }
+
+        private static final String LABEL_EL = "label";
+
+        public void endElement(String namespaceURI, String localName, String qName)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigNestingLevel--;
+                convertorConfigDOMBuilder.endElement(namespaceURI, localName, qName);
+                if (convertorConfigNestingLevel == 0) {
+                    Element convertorElement = convertorConfigDOMBuilder.getDocument().getDocumentElement();
+                    try {
+                        convertor = datatype.getBuilder().buildConvertor(convertorElement);
+                    } catch (Exception e) {
+                        throw new SAXException("Error building convertor from convertor configuration embedded in selection list XML.", e);
+                    }
+                }
+            } else if (namespaceURI.equals(FormsConstants.DEFINITION_NS)) {
+                if (localName.equals("item")) {
+                    if (!hasLabel) {
+                        // make the label now
+                        super.startElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL, XMLUtils.EMPTY_ATTRIBUTES);
+                        super.characters(currentValueAsString.toCharArray(), 0, currentValueAsString.length());
+                        super.endElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL);
+                    }
+                    super.endElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName);
+                } else if (localName.equals("label")) {
+                    super.endElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName);
+                } else if (localName.equals("selection-list")) {
+                    super.endElement(FormsConstants.INSTANCE_NS, localName, FormsConstants.INSTANCE_PREFIX_COLON + localName);
+                } else {
+                    super.endElement(namespaceURI, localName, qName);
+                }
+            } else {
+                super.endElement(namespaceURI, localName, qName);
+            }
+        }
+
+        public void comment(char ch[], int start, int len)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.comment(ch, start, len);
+            } else
+                super.comment(ch, start, len);
+        }
+
+        public void startPrefixMapping(String prefix, String uri)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.startPrefixMapping(prefix, uri);
+            } else
+                super.startPrefixMapping(prefix, uri);
+        }
+
+        public void endPrefixMapping(String prefix)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.endPrefixMapping(prefix);
+            } else
+                super.endPrefixMapping(prefix);
+        }
+
+        public void characters(char c[], int start, int len)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.characters(c, start, len);
+            } else
+                super.characters(c, start, len);
+        }
+
+        public void ignorableWhitespace(char c[], int start, int len)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.ignorableWhitespace(c, start, len);
+            } else
+                super.ignorableWhitespace(c, start, len);
+        }
+
+        public void processingInstruction(String target, String data)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.processingInstruction(target, data);
+            } else
+                super.processingInstruction(target, data);
+        }
+
+        public void skippedEntity(String name)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.skippedEntity(name);
+            } else
+                super.skippedEntity(name);
+        }
+
+        public void startEntity(String name)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.startEntity(name);
+            } else
+                super.startEntity(name);
+        }
+
+        public void endEntity(String name)
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.endEntity(name);
+            } else
+                super.endEntity(name);
+        }
+
+        public void startCDATA()
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.startCDATA();
+            } else
+                super.startCDATA();
+        }
+
+        public void endCDATA()
+                throws SAXException {
+            if (convertorConfigNestingLevel > 0) {
+                convertorConfigDOMBuilder.endCDATA();
+            } else
+                super.endCDATA();
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/DynamicSelectionList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EmptySelectionList.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EmptySelectionList.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EmptySelectionList.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EmptySelectionList.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.forms.datatype;
+
+import java.util.Locale;
+
+import org.apache.cocoon.forms.FormsConstants;
+import org.apache.cocoon.transformation.I18nTransformer;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.XMLUtils;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * 
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: EmptySelectionList.java 326838 2005-10-20 06:26:53Z sylvain $
+ */
+public class EmptySelectionList implements SelectionList {
+    private String text;
+    private boolean i18n;
+    
+    public EmptySelectionList(String text) {
+        this.text = text;
+        this.i18n = false;
+    }
+    
+    public EmptySelectionList(String text, boolean i18n) {
+        this.text = text;
+        this.i18n = i18n;
+    }
+
+    public Datatype getDatatype() {
+        // Cannot return anything meaningful
+        return null;
+    }
+
+    public void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException {
+        // Start wi:selection list
+        contentHandler.startElement(FormsConstants.INSTANCE_NS, SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON + SELECTION_LIST_EL, XMLUtils.EMPTY_ATTRIBUTES);
+
+        // Start wi:item
+        AttributesImpl itemAttrs = new AttributesImpl();
+        itemAttrs.addCDATAAttribute("value", "");
+        contentHandler.startElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL, itemAttrs);
+
+        // Start wi:label
+        contentHandler.startElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL, XMLUtils.EMPTY_ATTRIBUTES);
+        if (this.text != null) {
+
+            if (i18n) {
+                contentHandler.startPrefixMapping("i18n", I18nTransformer.I18N_NAMESPACE_URI);
+        
+                contentHandler.startElement(I18nTransformer.I18N_NAMESPACE_URI, I18nTransformer.I18N_TEXT_ELEMENT, "i18n:" + I18nTransformer.I18N_TEXT_ELEMENT, XMLUtils.EMPTY_ATTRIBUTES);
+                contentHandler.characters(this.text.toCharArray(), 0, this.text.length());
+                contentHandler.endElement(I18nTransformer.I18N_NAMESPACE_URI, I18nTransformer.I18N_TEXT_ELEMENT, "i18n:" + I18nTransformer.I18N_TEXT_ELEMENT);
+    
+                contentHandler.endPrefixMapping("i18n");
+            } else {
+                contentHandler.characters(this.text.toCharArray(), 0, this.text.length());
+            }
+        }
+        
+        // End wi:label
+        contentHandler.endElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL);
+        
+        // End wi:item
+        contentHandler.endElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL);
+        
+        // End wi:selection-list
+        contentHandler.endElement(FormsConstants.INSTANCE_NS, SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON + SELECTION_LIST_EL);
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EmptySelectionList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionList.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionList.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionList.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionList.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,122 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * Licensed 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.forms.datatype;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Locale;
+
+import org.apache.cocoon.forms.FormsConstants;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.XMLUtils;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * This type of selection list outputs a list of items
+ * corresponding to the possible instances of an {@link org.apache.cocoon.forms.datatype.typeimpl.EnumType}.
+ * <p>Example usage:</p>
+ * <pre>
+ * &lt;fd:selection-list type="enum" class="com.example.Sex"/&gt;
+ * </pre>
+ * <p>Produces the following output:</p>
+ * <pre>
+ * &lt;fi:selection-list&gt;
+ *   &lt;fi:item value=""/&gt;
+ *   &lt;fi:item value="com.example.Sex.MALE"&gt;
+ *     &lt;fi:label&gt;
+ *       &lt;i18n:text&gt;com.example.Sex.MALE&lt;/i18n:text&gt;
+ *     &lt;/fi:label&gt;
+ *   &lt;/fi:item&gt;
+ *   &lt;fi:item value="com.example.Sex.FEMALE"&gt;
+ *     &lt;fi:label&gt;
+ *       &lt;i18n:text&gt;com.example.Sex.FEMALE&lt;/i18n:text&gt;
+ *     &lt;/fi:label&gt;
+ *   &lt;/fi:item&gt;
+ * &lt;/fi:selection-list&gt;
+ * </pre>
+ *
+ * <p>If you don't want an initial null value, add a
+ * <code>nullable="false"</code> attribute to the
+ * <code>fd:selection-list</code> element.</p>
+ *
+ * @version $Id: EnumSelectionList.java 326838 2005-10-20 06:26:53Z sylvain $
+ */
+public class EnumSelectionList implements SelectionList {
+    public static final String TEXT_EL = "text";
+
+    private Datatype datatype;
+    private Class clazz;
+    private boolean nullable;
+
+    /**
+     * @param className
+     * @param datatype
+     */
+    public EnumSelectionList(String className, Datatype datatype, boolean nullable) throws ClassNotFoundException {
+        this.datatype = datatype;
+        this.nullable = nullable;
+        this.clazz = Class.forName(className);
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.forms.datatype.SelectionList#getDatatype()
+     */
+    public Datatype getDatatype() {
+        return datatype;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.forms.datatype.SelectionList#generateSaxFragment(org.xml.sax.ContentHandler, java.util.Locale)
+     */
+    public void generateSaxFragment(ContentHandler contentHandler,
+                                    Locale locale)
+    throws SAXException {
+        try {
+            contentHandler.startElement(FormsConstants.INSTANCE_NS, SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON + SELECTION_LIST_EL, XMLUtils.EMPTY_ATTRIBUTES);
+            Field fields[] = clazz.getDeclaredFields();
+            // Create void element
+            if (nullable) {
+                AttributesImpl voidAttrs = new AttributesImpl();
+                voidAttrs.addCDATAAttribute("value", "");
+                contentHandler.startElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL, voidAttrs);
+                contentHandler.endElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL);
+            }
+            for (int i = 0 ; i < fields.length ; ++i) {
+                int mods = fields[i].getModifiers();
+                if (Modifier.isPublic(mods) && Modifier.isStatic(mods)
+                        && Modifier.isFinal(mods) && fields[i].get(null).getClass().equals(clazz)) {
+                    String stringValue = clazz.getName() + "." + fields[i].getName();
+                    // Output this item
+                    AttributesImpl itemAttrs = new AttributesImpl();
+                    itemAttrs.addCDATAAttribute("value", stringValue);
+                    contentHandler.startElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL, itemAttrs);
+                    contentHandler.startElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL, XMLUtils.EMPTY_ATTRIBUTES);
+                    // TODO: make i18n element optional
+                    contentHandler.startElement(FormsConstants.I18N_NS, TEXT_EL, FormsConstants.I18N_PREFIX_COLON + TEXT_EL, XMLUtils.EMPTY_ATTRIBUTES);
+                    contentHandler.characters(stringValue.toCharArray(), 0, stringValue.length());
+                    contentHandler.endElement(FormsConstants.I18N_NS, TEXT_EL, FormsConstants.I18N_PREFIX_COLON + TEXT_EL);
+                    contentHandler.endElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL);
+                    contentHandler.endElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL);
+                }
+            }
+            // End the selection-list
+            contentHandler.endElement(FormsConstants.INSTANCE_NS, SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON + SELECTION_LIST_EL);
+        } catch (Exception e) {
+            throw new SAXException("Got exception trying to get enum's values", e);
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionList.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionListBuilder.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionListBuilder.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionListBuilder.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionListBuilder.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.forms.datatype;
+
+import org.apache.cocoon.forms.util.DomHelper;
+import org.w3c.dom.Element;
+
+/**
+ * Description of EnumSelectionListBuilder.
+ * @version $Id: EnumSelectionListBuilder.java 151179 2005-02-03 16:55:16Z tim $
+ */
+public class EnumSelectionListBuilder implements SelectionListBuilder {
+
+    /* (non-Javadoc)
+     * @see org.apache.cocoon.forms.datatype.SelectionListBuilder#build(org.w3c.dom.Element, org.apache.cocoon.forms.datatype.Datatype)
+     */
+    public SelectionList build(Element selectionListElement, Datatype datatype)
+        throws Exception {
+        String className = DomHelper.getAttribute(selectionListElement, "class");
+        boolean nullable = DomHelper.getAttributeAsBoolean(selectionListElement, "nullable", true);
+        return new EnumSelectionList(className, datatype, nullable);
+    }
+
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/EnumSelectionListBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/FlowJXPathSelectionList.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/FlowJXPathSelectionList.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/FlowJXPathSelectionList.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/FlowJXPathSelectionList.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,211 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed 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.forms.datatype;
+
+import java.util.Iterator;
+import java.util.Locale;
+
+import org.apache.avalon.framework.context.Context;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.components.flow.FlowHelper;
+import org.apache.cocoon.forms.FormsConstants;
+import org.apache.cocoon.forms.util.I18nMessage;
+import org.apache.cocoon.xml.AttributesImpl;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.Pointer;
+import org.apache.excalibur.xml.sax.XMLizable;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * A selection list that takes its values from the flow page data.
+ *
+ * @see org.apache.cocoon.forms.datatype.FlowJXPathSelectionListBuilder
+ * @author <a href="http://www.apache.org/~sylvain/">Sylvain Wallez</a>
+ * @version $Id: FlowJXPathSelectionList.java 326838 2005-10-20 06:26:53Z sylvain $
+ */
+public class FlowJXPathSelectionList implements SelectionList {
+
+    private Context context;
+    private String listPath;
+    private String valuePath;
+    private String labelPath;
+    private Datatype datatype;
+    private Object model;
+    private boolean nullable = false; 
+    private String nullText;
+    private boolean nullTextIsI18nKey = false;
+    private String i18nCatalog;
+    private boolean labelIsI18nKey = false;
+
+    public FlowJXPathSelectionList(Context context, 
+                                   String listPath, 
+                                   String valuePath, 
+                                   String labelPath, 
+                                   Datatype datatype,
+                                   String nullText, 
+                                   boolean nullTextIsI18nKey, 
+                                   String i18nCatalog, 
+                                   boolean labelIsI18nKey) {
+        this.context = context;
+        this.listPath = listPath;
+        this.valuePath = valuePath;
+        this.labelPath = labelPath;
+        this.datatype = datatype;
+        this.nullText = nullText;
+        this.nullable = (nullText != null);
+        this.nullTextIsI18nKey = nullTextIsI18nKey;
+        this.i18nCatalog =i18nCatalog;
+        this.labelIsI18nKey = labelIsI18nKey;
+    }
+
+    /**
+     * Builds a dynamic selection list from an in-memory collection.
+     * @see org.apache.cocoon.forms.formmodel.Field#setSelectionList(Object model, String valuePath, String labelPath)
+     * @param model The collection used as a model for the selection list.
+     * @param valuePath An XPath expression referring to the attribute used
+     * to populate the values of the list's items.
+     * @param labelPath An XPath expression referring to the attribute used
+     * to populate the labels of the list's items.
+     * @param datatype
+     */
+    public FlowJXPathSelectionList(Object model, String valuePath, String labelPath, Datatype datatype) {
+        this.model = model;
+        this.valuePath = valuePath;
+        this.labelPath = labelPath;
+        this.datatype = datatype;
+    }
+
+    public Datatype getDatatype() {
+        return this.datatype;
+    }
+
+    public void generateSaxFragment(ContentHandler contentHandler, Locale locale) throws SAXException {
+        JXPathContext ctx = null;
+        Iterator iter = null;
+        if (model == null) {
+            Object flowData = FlowHelper.getContextObject(ContextHelper.getObjectModel(this.context));
+            if (flowData == null) {
+                throw new SAXException("No flow data to produce selection list");
+            }
+
+            // Move to the list location
+            ctx = JXPathContext.newContext(flowData);
+
+            // Iterate on all elements of the list
+            iter = ctx.iteratePointers(this.listPath);
+        } else {
+            // Move to the list location
+            ctx = JXPathContext.newContext(model);
+
+            // Iterate on all elements of the list
+            iter = ctx.iteratePointers(".");
+        }
+
+        // Start the selection-list
+        contentHandler.startElement(FormsConstants.INSTANCE_NS, SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON + SELECTION_LIST_EL, XMLUtils.EMPTY_ATTRIBUTES);
+        if( this.nullable ) {
+            final AttributesImpl voidAttrs = new AttributesImpl(  );
+            voidAttrs.addCDATAAttribute( "value", "" );
+            contentHandler.startElement( FormsConstants.INSTANCE_NS, ITEM_EL,
+                                         FormsConstants.INSTANCE_PREFIX_COLON +
+                                         ITEM_EL, voidAttrs );
+
+            if( this.nullText != null ) {
+                contentHandler.startElement( FormsConstants.INSTANCE_NS, LABEL_EL,
+                                             FormsConstants.INSTANCE_PREFIX_COLON +
+                                             LABEL_EL, XMLUtils.EMPTY_ATTRIBUTES );
+
+                if( this.nullTextIsI18nKey ) {
+                    if( ( this.i18nCatalog != null ) &&
+                        ( this.i18nCatalog.trim(  ).length(  ) > 0 ) ) {
+                        new I18nMessage( this.nullText, this.i18nCatalog ).toSAX( contentHandler );
+                    } else {
+                        new I18nMessage( this.nullText ).toSAX( contentHandler );
+                    }
+                } else {
+                    contentHandler.characters( this.nullText.toCharArray(  ), 0,
+                                               this.nullText.length(  ) );
+                }
+
+                contentHandler.endElement( FormsConstants.INSTANCE_NS, LABEL_EL,
+                                           FormsConstants.INSTANCE_PREFIX_COLON +
+                                           LABEL_EL );
+            }
+
+            contentHandler.endElement( FormsConstants.INSTANCE_NS, ITEM_EL,
+                                       FormsConstants.INSTANCE_PREFIX_COLON +
+                                       ITEM_EL );
+        }
+
+        while(iter.hasNext()) {
+            String stringValue = "";
+            Object label = null;
+
+            // Get a context on the current item
+            Pointer ptr = (Pointer)iter.next();
+            if (ptr.getValue() != null) {
+                JXPathContext itemCtx = ctx.getRelativeContext(ptr);
+
+                // Get the value as a string
+                Object value = itemCtx.getValue(this.valuePath);
+
+                // List may contain null value, and (per contract with convertors),
+                // convertors are not invoked on nulls.
+                if (value != null) {
+                    stringValue = this.datatype.convertToString(value, locale);
+                }
+
+                // Get the label (can be ommitted)
+                itemCtx.setLenient(true);
+                label = itemCtx.getValue(this.labelPath);
+                if (label == null) {
+                    label = stringValue;
+                }
+            }
+
+            // Output this item
+            AttributesImpl itemAttrs = new AttributesImpl();
+            itemAttrs.addCDATAAttribute("value", stringValue);
+            contentHandler.startElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL, itemAttrs);
+            if (label != null) {
+                contentHandler.startElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL, XMLUtils.EMPTY_ATTRIBUTES);
+                if (label instanceof XMLizable) {
+                    ((XMLizable)label).toSAX(contentHandler);
+                }  else if( this.labelIsI18nKey ) {
+                    String stringLabel = label.toString();
+
+                    if( ( this.i18nCatalog != null ) &&
+                        ( this.i18nCatalog.trim(  ).length(  ) > 0 ) ) {
+                        new I18nMessage( stringLabel, this.i18nCatalog ).toSAX( contentHandler );
+                    } else {
+                        new I18nMessage( stringLabel ).toSAX( contentHandler );
+                    }
+                } else {
+                    String stringLabel = label.toString();
+                    contentHandler.characters(stringLabel.toCharArray(), 0, stringLabel.length());
+                }
+                contentHandler.endElement(FormsConstants.INSTANCE_NS, LABEL_EL, FormsConstants.INSTANCE_PREFIX_COLON + LABEL_EL);
+            }
+            contentHandler.endElement(FormsConstants.INSTANCE_NS, ITEM_EL, FormsConstants.INSTANCE_PREFIX_COLON + ITEM_EL);
+        }
+
+        // End the selection-list
+        contentHandler.endElement(FormsConstants.INSTANCE_NS, SELECTION_LIST_EL, FormsConstants.INSTANCE_PREFIX_COLON + SELECTION_LIST_EL);
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-forms-block/impl/src/main/java/org/apache/cocoon/forms/datatype/FlowJXPathSelectionList.java
------------------------------------------------------------------------------
    svn:eol-style = native