commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mben...@apache.org
Subject svn commit: r692147 [2/3] - in /commons/sandbox/flatfile/trunk: doc/ src/ src/grammar/ src/java/ src/java/com/ src/java/com/pgac/ src/java/com/pgac/flatfile/ src/java/com/pgac/flatfile/dsl/ src/java/com/pgac/flatfile/entityfactory/ src/java/com/pgac/fl...
Date Thu, 04 Sep 2008 16:39:31 GMT
Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/PadJustifyFieldSupport.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/PadJustifyFieldSupport.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/PadJustifyFieldSupport.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/PadJustifyFieldSupport.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,138 @@
+package com.pgac.flatfile;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import com.pgac.flatfile.util.ConcatenatedInputStream;
+import com.pgac.flatfile.util.RepeatingInputStream;
+
+/**
+ * Support for fields with pad/justify.
+ */
+public abstract class PadJustifyFieldSupport extends FieldSupport {
+    /**
+     * Justify enumerated type.
+     */
+    public static abstract class Justify implements FieldOption {
+        /** Left-justify */
+        public static final Justify LEFT = new Justify() {
+            private static final long serialVersionUID = 9080286767796807220L;
+
+            protected InputStream getInputStream(byte[] src,
+                    PadJustifyFieldSupport dest) {
+                InputStream is = new ByteArrayInputStream(src);
+                int dlen = dest.getPadJustifyLength();
+                return dlen <= src.length ? is : new ConcatenatedInputStream(
+                        is, RepeatingInputStream.getInstance(dest.getPad(),
+                                dlen - src.length));
+            }
+        };
+
+        /** Right-justify */
+        public static final Justify RIGHT = new Justify() {
+            private static final long serialVersionUID = -5793503470625462046L;
+
+            protected InputStream getInputStream(byte[] src,
+                    PadJustifyFieldSupport dest) {
+                int dlen = dest.getPadJustifyLength();
+                if (dlen < src.length) {
+                    return new ByteArrayInputStream(src, src.length - dlen,
+                            dlen);
+                }
+                InputStream is = new ByteArrayInputStream(src);
+                return dlen == src.length ? is : new ConcatenatedInputStream(
+                        RepeatingInputStream.getInstance(dest.getPad(), dlen
+                                - src.length), is);
+            }
+        };
+
+        /** Center */
+        public static final Justify CENTER = new Justify() {
+            private static final long serialVersionUID = -5301921606809471697L;
+
+            protected InputStream getInputStream(byte[] src,
+                    PadJustifyFieldSupport dest) {
+                int dlen = dest.getPadJustifyLength();
+                // it would be odd and therefore hopefully rare to center a
+                // field that allowed overflow,
+                // but we'll provide for it:
+                if (dlen < src.length) {
+                    return new ByteArrayInputStream(src,
+                            (src.length - dlen) / 2, dlen);
+                }
+                InputStream is = new ByteArrayInputStream(src);
+                if (dlen == src.length) {
+                    return is;
+                }
+                ArrayList l = new ArrayList(3);
+                byte pad = dest.getPad();
+                l.add(RepeatingInputStream.getInstance(pad,
+                        (dlen - src.length) / 2));
+                l.add(is);
+                l.add(RepeatingInputStream.getInstance(pad));
+                return new ConcatenatedInputStream(l);
+            }
+        };
+
+        private Justify() {
+        }
+
+        /**
+         * Get an InputStream for the specified parameters.
+         * @param src byte[] value
+         * @param dest PadJustifyFieldSupport
+         * @return InputStream
+         */
+        protected abstract InputStream getInputStream(byte[] src,
+                PadJustifyFieldSupport dest);
+    }
+
+    private byte pad = 0x20;
+    private Justify justify;
+
+    /**
+     * Get the justify.
+     * @return Justify
+     */
+    public Justify getJustify() {
+        return justify == null ? Justify.LEFT : justify;
+    }
+
+    /**
+     * Set the justify.
+     * @param justify Justify
+     */
+    public void setJustify(Justify justify) {
+        this.justify = justify;
+    }
+
+    /**
+     * Get the pad.
+     * @return byte
+     */
+    public byte getPad() {
+        return pad;
+    }
+
+    /**
+     * Set the pad.
+     * @param pad byte
+     */
+    public void setPad(byte pad) {
+        this.pad = pad;
+    }
+
+    /**
+     * Implement pad/justify.
+     */
+    public void setValue(byte[] b) {
+        dieOnExceptionRead(getJustify().getInputStream(b, this));
+    }
+
+    /**
+     * Provide the desired target length for padding/justification actions.
+     * @return int
+     */
+    protected abstract int getPadJustifyLength();
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/PadJustifyFieldSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ConstantEntityNameStrategy.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ConstantEntityNameStrategy.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ConstantEntityNameStrategy.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ConstantEntityNameStrategy.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,33 @@
+package com.pgac.flatfile.dsl;
+
+/**
+ * Another simple implementation; always return the same thing.
+ */
+public class ConstantEntityNameStrategy implements EntityNameStrategy {
+    private String entityName;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.reflectors.EntityNameStrategy#getEntityName(java.lang.Object)
+     */
+    public String getEntityName(Object o) {
+        return getEntityName();
+    }
+
+    /**
+     * Get the constant entityName.
+     * @return String.
+     */
+    public String getEntityName() {
+        return entityName;
+    }
+
+    /**
+     * Set the constant entityName.
+     * @param entityName The String entityName to set.
+     */
+    public void setEntityName(String entityName) {
+        this.entityName = entityName;
+    }
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ConstantEntityNameStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/DefaultEntityNameStrategy.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/DefaultEntityNameStrategy.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/DefaultEntityNameStrategy.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/DefaultEntityNameStrategy.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,32 @@
+package com.pgac.flatfile.dsl;
+
+import org.apache.commons.lang.ClassUtils;
+
+/**
+ * Default implementation.
+ */
+public class DefaultEntityNameStrategy implements EntityNameStrategy {
+    private static final String NULL = "null";
+
+    /**
+     * If <code>o</code> is a <code>String</code>, it returns unscathed.
+     * If <code>o</code> is <code>null</code>, returns <code>"null"</code>.
+     * If <code>o</code> is a <code>Class</code>, returns simple classname.
+     * Otherwise returns simple classname of <code>o</code>.
+     * @param o Object.
+     * @return String entity name.
+     */
+    public String getEntityName(Object o) {
+        if (o == null) {
+            return NULL;
+        }
+        if (o instanceof String) {
+            return (String) o;
+        }
+        Class c = o instanceof Class ? (Class) o : o.getClass();
+        StringBuffer sb = new StringBuffer(ClassUtils.getShortClassName(c));
+        sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
+        return sb.toString();
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/DefaultEntityNameStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityDefinition.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityDefinition.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityDefinition.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityDefinition.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,57 @@
+package com.pgac.flatfile.dsl;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import antlr.collections.AST;
+
+/**
+ * Entity definition.
+ */
+public class EntityDefinition {
+    private String name;
+    private AST ast;
+    private Collection checks;
+
+    /**
+     * Create a new EntityDefinition.
+     * @param name
+     * @param ast
+     */
+    public EntityDefinition(String name, AST ast) {
+        this.name = name;
+        this.ast = ast;
+    }
+
+    /**
+     * Get the ast.
+     * @return AST.
+     */
+    public AST getAst() {
+        return ast;
+    }
+
+    /**
+     * Get the name.
+     * @return String.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Get the checks.
+     * @return Collection.
+     */
+    public synchronized Collection getChecks() {
+        return checks == null ? Collections.EMPTY_LIST : checks;
+    }
+
+    /**
+     * Set the checks.
+     * @param checks The Collection checks to set.
+     */
+    public synchronized void setChecks(Collection checks) {
+        this.checks = checks;
+    }
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityDefinition.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityNameStrategy.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityNameStrategy.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityNameStrategy.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityNameStrategy.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,8 @@
+package com.pgac.flatfile.dsl;
+
+/**
+ * Interface for how to get an entity name for an Object.
+ */
+public interface EntityNameStrategy {
+    String getEntityName(Object o);
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/EntityNameStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ParserEntityFactory.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ParserEntityFactory.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ParserEntityFactory.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ParserEntityFactory.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,244 @@
+package com.pgac.flatfile.dsl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.lang.ObjectUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import antlr.TokenBuffer;
+import antlr.collections.AST;
+
+import com.pgac.flatfile.DynamicField;
+import com.pgac.flatfile.Entity;
+import com.pgac.flatfile.EntityFactory;
+import com.pgac.flatfile.Field;
+import com.pgac.flatfile.dsl.EntityLexer;
+import com.pgac.flatfile.dsl.EntityParser;
+import com.pgac.flatfile.dsl.EntityTreeParser;
+import com.pgac.flatfile.util.ApplyOptions;
+
+/**
+ * Entity factory; provides access to named entities parsed from one or more description files.
+ */
+public class ParserEntityFactory implements EntityFactory {
+    /** Field option constant */
+    public static final String OPTION_FIELD = "field";
+    /** DynamicField option constant */
+    public static final String OPTION_DYNAMIC_FIELD = "dynamicField";
+
+    private static final Log LOG = LogFactory.getLog(ParserEntityFactory.class);
+    private static final EntityNameStrategy DEFAULT_NAME_STRATEGY = new DefaultEntityNameStrategy();
+    private EntityNameStrategy entityNameStrategy;
+
+    private ThreadLocal treeParser = new ThreadLocal() {
+        protected Object initialValue() {
+            EntityTreeParser result = new EntityTreeParser();
+            result.setEntityFactory(ParserEntityFactory.this);
+            return result;
+        }
+    };
+
+    private Map entityMap;
+    private Map defaultOptionMaps = new HashMap();
+    private boolean checked;
+    private InputStream[] sources;
+    private EntityFactory parent;
+
+    /**
+     * Create a new ParserEntityFactory.
+     */
+    public ParserEntityFactory() {
+    }
+
+    /**
+     * Create a new ParserEntityFactory.
+     * @param source
+     */
+    public ParserEntityFactory(InputStream source) {
+        setSource(source);
+    }
+
+    /**
+     * Create a new ParserEntityFactory.
+     * @param sources
+     */
+    public ParserEntityFactory(InputStream[] sources) {
+        setSources(sources);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.EntityFactory#getEntity(java.lang.Object)
+     */
+    public final Entity getEntity(Object cue) {
+        if (parent != null) {
+            Entity e = parent.getEntity(cue);
+            if (e != null) {
+                return e;
+            }
+        }
+        Object o = getEntityMap().get(
+                getEntityNameStrategy().getEntityName(cue));
+        if (o == null) {
+            return null;
+        }
+        Entity prototype = null;
+        if (o instanceof Entity) {
+            prototype = (Entity) o;
+        } else {
+            EntityDefinition def = (EntityDefinition) o;
+            EntityTreeParser tp = getTreeParser();
+            prototype = tp.createEntity(def);
+            entityMap.put(def.getName(), prototype);
+        }
+        return (Entity) prototype.clone();
+    }
+
+    /**
+     * Validate all defined entities.
+     */
+    public final synchronized void validate() {
+        if (checked) {
+            return;
+        }
+        for (Iterator it = getEntityMap().keySet().iterator(); it.hasNext();) {
+            getEntity((String) it.next());
+        }
+    }
+
+    /**
+     * Get the entityNameStrategy.
+     * @return EntityNameStrategy.
+     */
+    public synchronized EntityNameStrategy getEntityNameStrategy() {
+        return entityNameStrategy == null ? DEFAULT_NAME_STRATEGY
+                : entityNameStrategy;
+    }
+
+    /**
+     * Set the entityNameStrategy.
+     * @param entityNameStrategy The EntityNameStrategy entityNameStrategy to set.
+     */
+    public synchronized void setEntityNameStrategy(
+            EntityNameStrategy entityNameStrategy) {
+        this.entityNameStrategy = entityNameStrategy;
+    }
+
+    /**
+     * Get the InputStream[] sources.
+     * @return InputStream[]
+     */
+    public InputStream[] getSources() throws IOException {
+        return sources;
+    }
+
+    /**
+     * Set the InputStream[] sources.
+     * @param sources InputStream[]
+     */
+    public void setSources(InputStream[] sources) {
+        this.sources = sources;
+    }
+
+    /**
+     * Convenience setter for a single InputStream source.
+     * @param source
+     */
+    public void setSource(InputStream source) {
+        setSources(new InputStream[] { source });
+    }
+
+    /**
+     * Get the parent.
+     * @return EntityFactory
+     */
+    public EntityFactory getParent() {
+        return parent;
+    }
+
+    /**
+     * Set the parent.
+     * @param parent EntityFactory
+     */
+    public void setParent(EntityFactory parent) {
+        this.parent = parent;
+    }
+
+    /* package-private */
+    void add(String name, EntityDefinition def) {
+        entityMap.put(name, def);
+    }
+
+    /* package-private */
+    void setDefaultOptions(String type, Map options) {
+        Object old = defaultOptionMaps.put(type, options);
+        if (!ObjectUtils.equals(old, options)) {
+            LOG.warn("Overriding " + type + " options");
+        }
+    }
+
+    /* package-private */
+    Map getDefaultOptions(String type) {
+        return (Map) defaultOptionMaps.get(type);
+    }
+
+    /* package-private */
+    Entity createField(int length) {
+        return applyDefaultOptions(new Field(length), OPTION_FIELD);
+    }
+
+    /* package-private */
+    Entity createDynamicField() {
+        return applyDefaultOptions(new DynamicField(), OPTION_DYNAMIC_FIELD);
+    }
+
+    /* package-private */
+    Entity createField(byte[] value) {
+        return applyDefaultOptions(new Field(value), OPTION_FIELD);
+    }
+
+    private Entity applyDefaultOptions(Entity e, String type) {
+        Map m = (Map) defaultOptionMaps.get(type);
+        return m == null ? e : (Entity) ApplyOptions.apply(e, m);
+    }
+
+    private EntityTreeParser getTreeParser() {
+        return (EntityTreeParser) treeParser.get();
+    }
+
+    private synchronized Map getEntityMap() {
+        if (entityMap == null) {
+            entityMap = new HashMap();
+            try {
+                EntityParser p = null;
+                ArrayList trees = new ArrayList();
+                InputStream[] is = getSources();
+                for (int i = 0; i < is.length; i++) {
+                    TokenBuffer tb = new TokenBuffer(new EntityLexer(is[i]));
+                    if (p == null) {
+                        p = new EntityParser(tb);
+                    } else {
+                        p.setTokenBuffer(tb);
+                    }
+                    p.parse();
+                    trees.add(p.getAST());
+                }
+                for (Iterator it = trees.iterator(); it.hasNext();) {
+                    getTreeParser().load((AST) it.next());
+                }
+            } catch (Exception e) {
+                throw e instanceof RuntimeException ? (RuntimeException) e
+                        : new RuntimeException(e);
+            }
+        }
+        return entityMap;
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/dsl/ParserEntityFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CloningEntityFactory.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CloningEntityFactory.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CloningEntityFactory.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CloningEntityFactory.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,35 @@
+package com.pgac.flatfile.entityfactory;
+
+import java.util.Map;
+
+import com.pgac.flatfile.Entity;
+import com.pgac.flatfile.EntityFactory;
+
+/**
+ * Stores prototype entities in a Map and returns cloned Entities.
+ */
+public class CloningEntityFactory implements EntityFactory {
+    private Map lookup;
+
+    /**
+     * Create a new CloningEntityFactory.
+     * @param lookup lookup Map
+     */
+    public CloningEntityFactory(Map lookup) {
+        if (lookup == null) {
+            throw new IllegalArgumentException("null lookup Map");
+        }
+        this.lookup = lookup;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.EntityFactory#getEntity(java.lang.Object)
+     */
+    public Entity getEntity(Object cue) {
+        Entity prototype = (Entity) lookup.get(cue);
+        return prototype == null ? null : (Entity) prototype.clone();
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CloningEntityFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CompositeEntityFactory.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CompositeEntityFactory.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CompositeEntityFactory.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CompositeEntityFactory.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,36 @@
+package com.pgac.flatfile.entityfactory;
+
+import com.pgac.flatfile.Entity;
+import com.pgac.flatfile.EntityFactory;
+
+/**
+ * Delegates to <i>0..n</i> EntityFactories.
+ */
+public class CompositeEntityFactory implements EntityFactory {
+
+    private EntityFactory[] delegates;
+
+    /**
+     * Create a new CompositeEntityFactory.
+     * @param delegates EntityFactory[]
+     */
+    public CompositeEntityFactory(EntityFactory[] delegates) {
+        this.delegates = delegates;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.EntityFactory#getEntity(java.lang.Object)
+     */
+    public Entity getEntity(Object cue) {
+        for (int i = 0; delegates != null && i < delegates.length; i++) {
+            Entity result = delegates[i].getEntity(cue);
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/entityfactory/CompositeEntityFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/BaseEntityCollectionReflector.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/BaseEntityCollectionReflector.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/BaseEntityCollectionReflector.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/BaseEntityCollectionReflector.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,344 @@
+package com.pgac.flatfile.morph;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import com.pgac.flatfile.Entity;
+import com.pgac.flatfile.EntityCollection;
+
+import net.sf.morph.Defaults;
+import net.sf.morph.reflect.IndexedContainerReflector;
+import net.sf.morph.reflect.reflectors.BaseContainerReflector;
+import net.sf.morph.reflect.reflectors.ObjectReflector;
+import net.sf.morph.transform.DecoratedConverter;
+import net.sf.morph.util.ClassUtils;
+
+/**
+ * Base EntityCollection reflector.
+ */
+public abstract class BaseEntityCollectionReflector extends
+        BaseContainerReflector {
+    /**
+     * Entity property strategy base class.
+     */
+    protected abstract class PropertyStrategy {
+        protected String propertyName;
+
+        protected PropertyStrategy(String propertyName) {
+            this.propertyName = propertyName;
+        }
+
+        final Class getTypeFrom(Object bean) throws Exception {
+            if (isEntity(bean, propertyName)) {
+                return getEntityType(getEntity(bean, propertyName));
+            }
+            return FALLBACK.getType(bean, propertyName);
+        }
+
+        abstract Class getEntityType(Entity e) throws Exception;
+
+        final Object getFrom(Object bean) throws Exception {
+            if (isEntity(bean, propertyName)) {
+                return getEntityValue(getEntity(bean, propertyName));
+            }
+            return FALLBACK.get(bean, propertyName);
+        }
+
+        abstract Object getEntityValue(Entity e) throws Exception;
+
+        final void setOn(Object bean, Object propertyValue) throws Exception {
+            if (isEntity(bean, propertyName)) {
+                setEntityValueOn(bean, getEntity(bean, propertyName),
+                        propertyValue);
+            } else {
+                FALLBACK.set(bean, propertyName, propertyValue);
+            }
+        }
+
+        abstract void setEntityValueOn(Object bean, Entity e,
+                Object propertyValue) throws Exception;
+
+        final boolean isReadableOn(Object bean) throws Exception {
+            return isEntity(bean, propertyName)
+                    || FALLBACK.isReadable(bean, propertyName);
+        }
+
+        final boolean isWriteableOn(Object bean) throws Exception {
+            return isEntity(bean, propertyName)
+                    || FALLBACK.isWriteable(bean, propertyName);
+        }
+    }
+
+    private class OverrideStrategy extends PropertyStrategy {
+        public OverrideStrategy(String propertyName) {
+            super(propertyName.substring(TYPE_OVERRIDE.length()));
+        }
+
+        Class getEntityType(Entity e) {
+            return ClassUtils.getClass(e);
+        }
+
+        Object getEntityValue(Entity e) {
+            return e;
+        }
+
+        void setEntityValueOn(Object bean, Entity e, Object propertyValue)
+                throws Exception {
+            FALLBACK.set(bean, propertyName, propertyValue);
+        }
+    }
+
+    private class DefaultStrategy extends PropertyStrategy {
+        public DefaultStrategy(String propertyName) {
+            super(propertyName);
+        }
+
+        Class getEntityType(Entity e) {
+            return e instanceof EntityCollection ? EntityCollection.class
+                    : String.class;
+        }
+
+        Object getEntityValue(Entity e) {
+            return e instanceof EntityCollection ? (Object) e : getString(e);
+        }
+
+        void setEntityValueOn(Object bean, Entity e, Object propertyValue)
+                throws Exception {
+            setEntityValue(e, propertyValue);
+        }
+    }
+
+    /** Property name prefix indicating to return runtime Entity type rather than String even for non-collection Entities. */
+    public static final String TYPE_OVERRIDE = "@";
+
+    private static final ObjectReflector FALLBACK = new ObjectReflector();
+
+    private DecoratedConverter toTextConverter;
+    private boolean trimStrings = true;
+
+    /**
+     * Get the boolean trimStrings.
+     * @return boolean
+     */
+    public boolean isTrimStrings() {
+        return trimStrings;
+    }
+
+    /**
+     * Set the boolean trimStrings.
+     * @param trimStrings boolean
+     */
+    public void setTrimStrings(boolean trimStrings) {
+        this.trimStrings = trimStrings;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getContainedTypeImpl(java.lang.Class)
+     */
+    protected Class getContainedTypeImpl(Class c) throws Exception {
+        return Entity.class;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getIteratorImpl(java.lang.Object)
+     */
+    protected Iterator getIteratorImpl(Object o) throws Exception {
+        return ((EntityCollection) o).getChildren().iterator();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getSizeImpl(java.lang.Object)
+     */
+    protected int getSizeImpl(Object o) throws Exception {
+        return ((EntityCollection) o).getChildren().size();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getTypeImpl(java.lang.Object,
+     *      java.lang.String)
+     */
+    protected Class getTypeImpl(Object bean, String propertyName)
+            throws Exception {
+        return getPropertyStrategy(propertyName).getTypeFrom(bean);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getImpl(java.lang.Object,
+     *      int)
+     */
+    protected Object getImpl(Object container, int index) throws Exception {
+        Entity e = getEntity(container, index);
+        return e instanceof EntityCollection ? (Object) e : getString(e);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getImpl(java.lang.Object,
+     *      java.lang.String)
+     */
+    protected Object getImpl(Object bean, String propertyName) throws Exception {
+        return getPropertyStrategy(propertyName).getFrom(bean);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#setImpl(java.lang.Object,
+     *      java.lang.String, java.lang.Object)
+     */
+    protected void setImpl(Object bean, String propertyName, Object value)
+            throws Exception {
+        getPropertyStrategy(propertyName).setOn(bean, value);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#setImpl(java.lang.Object,
+     *      int, java.lang.Object)
+     */
+    protected Object setImpl(Object container, int index, Object propertyValue)
+            throws Exception {
+        Entity e = getEntity(container, index);
+        byte[] result = e.getValue();
+        setEntityValue(e, propertyValue);
+        return result;
+    }
+
+    /**
+     * @param value Object Set the value of <code>e</code> by converting <code>value</code> to a byte[]
+     * @param e Entity
+     * @throws Exception
+     */
+    protected void setEntityValue(Entity e, Object value) throws Exception {
+        e.setValue((byte[]) getToTextConverter().convert(byte[].class, value));
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getPropertyNamesImpl(java.lang.Object)
+     */
+    protected String[] getPropertyNamesImpl(Object bean) throws Exception {
+        HashSet result = new HashSet();
+        if (this instanceof IndexedContainerReflector) {
+            result.addAll(Arrays.asList(super.getPropertyNamesImpl(bean)));
+        }
+        String[] fallback = FALLBACK.getPropertyNames(bean);
+        if (fallback != null && fallback.length > 0) {
+            result.addAll(Arrays.asList(fallback));
+            // add override property names:
+            for (int i = 0; i < fallback.length; i++) {
+                result.add("@" + fallback[i]);
+            }
+        }
+        return (String[]) result.toArray(new String[result.size()]);
+    }
+
+    /**
+     * Learn whether the specified property refers to an Entity child.
+     * @param bean
+     * @param propertyName
+     * @return
+     * @throws Exception
+     */
+    protected abstract boolean isEntity(Object bean, String propertyName)
+            throws Exception;
+
+    /**
+     * Get the named child entity
+     * @param bean
+     * @param propertyName
+     * @return
+     * @throws Exception
+     */
+    protected Entity getEntity(Object bean, String propertyName)
+            throws Exception {
+        return getEntity(bean, Integer.parseInt(propertyName));
+    }
+
+    /**
+     * Get the child entity at index <code>index</code>.
+     * @param container
+     * @param index
+     * @return
+     * @throws Exception
+     */
+    protected Entity getEntity(Object container, int index) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#isReadableImpl(java.lang.Object,
+     *      java.lang.String)
+     */
+    protected boolean isReadableImpl(Object bean, String propertyName)
+            throws Exception {
+        return getPropertyStrategy(propertyName).isReadableOn(bean);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#isWriteableImpl(java.lang.Object,
+     *      java.lang.String)
+     */
+    protected boolean isWriteableImpl(Object bean, String propertyName)
+            throws Exception {
+        return getPropertyStrategy(propertyName).isWriteableOn(bean);
+    }
+
+    /**
+     * @return the toTextConverter
+     */
+    public synchronized DecoratedConverter getToTextConverter() {
+        if (toTextConverter == null) {
+            setToTextConverter(Defaults.createToTextConverter());
+        }
+        return toTextConverter;
+    }
+
+    /**
+     * @param toTextConverter the toTextConverter to set
+     */
+    public synchronized void setToTextConverter(
+            DecoratedConverter toTextConverter) {
+        this.toTextConverter = toTextConverter;
+    }
+
+    /**
+     * Get the strategy instance to handle this property.
+     * @param propertyName
+     */
+    protected PropertyStrategy getPropertyStrategy(String propertyName) {
+        return propertyName.startsWith(TYPE_OVERRIDE) ? (PropertyStrategy) new OverrideStrategy(
+                propertyName)
+                : new DefaultStrategy(propertyName);
+    }
+
+    /**
+     * Get the value of the specified Entity as a String, respecting this {@link BaseEntityCollectionReflector}'s
+     * trimStrings property.
+     * @param e Entity
+     * @return e's value as a String.
+     */
+    protected String getString(Entity e) {
+        String s = new String(e.getValue());
+        return isTrimStrings() ? s.trim() : s;
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/BaseEntityCollectionReflector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ByteArrayToEntityCopier.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ByteArrayToEntityCopier.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ByteArrayToEntityCopier.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ByteArrayToEntityCopier.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,47 @@
+package com.pgac.flatfile.morph;
+
+import java.util.Locale;
+
+import com.pgac.flatfile.Entity;
+
+import net.sf.morph.transform.DecoratedConverter;
+import net.sf.morph.transform.DecoratedCopier;
+import net.sf.morph.transform.transformers.BaseTransformer;
+
+/**
+ * If you want to use as a converter you must set a reflector that can
+ * behave as an InstantiatingReflector and return an Entity.
+ */
+public class ByteArrayToEntityCopier extends BaseTransformer implements
+        DecoratedConverter, DecoratedCopier {
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#copyImpl(java.lang.Object,
+     *      java.lang.Object, java.util.Locale, java.lang.Integer)
+     */
+    protected void copyImpl(Object destination, Object source, Locale locale,
+            Integer preferredTransformationType) throws Exception {
+        ((Entity) destination).setValue((byte[]) source);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl()
+     */
+    protected Class[] getSourceClassesImpl() throws Exception {
+        return new Class[] { byte[].class };
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getDestinationClassesImpl()
+     */
+    protected Class[] getDestinationClassesImpl() throws Exception {
+        return new Class[] { Entity.class };
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ByteArrayToEntityCopier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ContainerToIndexedEntityCollectionCopier.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ContainerToIndexedEntityCollectionCopier.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ContainerToIndexedEntityCollectionCopier.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ContainerToIndexedEntityCollectionCopier.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,115 @@
+package com.pgac.flatfile.morph;
+
+import java.util.Locale;
+
+import com.pgac.flatfile.IndexedEntityCollection;
+
+import net.sf.morph.reflect.Reflector;
+import net.sf.morph.reflect.SizableReflector;
+import net.sf.morph.reflect.reflectors.ArrayReflector;
+import net.sf.morph.reflect.reflectors.CollectionReflector;
+import net.sf.morph.reflect.reflectors.EnumerationReflector;
+import net.sf.morph.reflect.reflectors.IteratorReflector;
+import net.sf.morph.reflect.reflectors.ListReflector;
+import net.sf.morph.reflect.reflectors.ObjectReflector;
+import net.sf.morph.reflect.reflectors.SetReflector;
+import net.sf.morph.reflect.reflectors.SimpleDelegatingReflector;
+import net.sf.morph.reflect.reflectors.SortedSetReflector;
+import net.sf.morph.transform.copiers.ContainerCopier;
+import net.sf.morph.transform.TransformationException;
+
+/**
+ * Copies containers to IndexedEntityCollections. Additionally recognizes <code>null</code> copy source as an empty
+ * collection.
+ */
+public class ContainerToIndexedEntityCollectionCopier extends ContainerCopier {
+    private static final Class[] DEST_CLASSES = new Class[] { IndexedEntityCollection.class };
+
+    private static class SizeOneReflector extends ObjectReflector implements
+            SizableReflector {
+        /*
+         * (non-Javadoc)
+         * 
+         * @see net.sf.morph.reflect.reflectors.BaseReflector#getSizeImpl(java.lang.Object)
+         */
+        protected int getSizeImpl(Object container) throws Exception {
+            return 1;
+        }
+    }
+
+    /**
+     * Create a new ContainerToIndexedEntityCollectionCopier
+     */
+    public ContainerToIndexedEntityCollectionCopier() {
+        setReflector(new SimpleDelegatingReflector(new Reflector[] {
+                new EntityCollectionReflector(), new ListReflector(),
+                new SortedSetReflector(), new SetReflector(),
+                new EnumerationReflector(), new IteratorReflector(),
+                new ArrayReflector(), new CollectionReflector(),
+                new SizeOneReflector() }));
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#setSourceClasses(java.lang.Class[])
+     */
+    public synchronized void setSourceClasses(Class[] sourceClasses) {
+        super.setSourceClasses(sourceClasses);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.copiers.ContainerCopier#getSourceClassesImpl()
+     */
+    protected Class[] getSourceClassesImpl() throws Exception {
+        Class[] c = getBeanReflector().getReflectableClasses();
+        Class[] result = new Class[c.length + 1];
+        System.arraycopy(c, 0, result, 0, c.length);
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#setDestinationClasses(java.lang.Class[])
+     */
+    public synchronized void setDestinationClasses(Class[] destinationClasses) {
+        super.setDestinationClasses(destinationClasses);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.copiers.ContainerCopier#getDestinationClassesImpl()
+     */
+    protected Class[] getDestinationClassesImpl() throws Exception {
+        return DEST_CLASSES;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.copiers.ContainerCopier#copyImpl(java.lang.Object,
+     *      java.lang.Object, java.util.Locale, java.lang.Integer)
+     */
+    protected void copyImpl(Object destination, Object source, Locale locale,
+            Integer preferredTransformationType) throws TransformationException {
+        int size = source == null ? 0 : getBeanReflector().getSize(source);
+        ((IndexedEntityCollection) destination).setSize(size);
+        if (size > 0) {
+            super.copyImpl(destination, source, locale,
+                    preferredTransformationType);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#isAutomaticallyHandlingNulls()
+     */
+    protected boolean isAutomaticallyHandlingNulls() {
+        return false;
+    }
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/ContainerToIndexedEntityCollectionCopier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityCollectionReflector.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityCollectionReflector.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityCollectionReflector.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityCollectionReflector.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,28 @@
+package com.pgac.flatfile.morph;
+
+import net.sf.morph.reflect.Reflector;
+import net.sf.morph.reflect.reflectors.SimpleDelegatingReflector;
+
+/**
+ * Entity collection reflector.
+ */
+public class EntityCollectionReflector extends SimpleDelegatingReflector {
+
+    /**
+     * Create a new EntityCollectionReflector.
+     */
+    public EntityCollectionReflector() {
+        // default
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.SimpleDelegatingReflector#createDefaultComponents()
+     */
+    protected synchronized Reflector[] createDefaultComponents() {
+        return new Reflector[] { new IndexedEntityCollectionReflector(),
+                new NamedEntityCollectionReflector() };
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityCollectionReflector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityInstantiatingReflector.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityInstantiatingReflector.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityInstantiatingReflector.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityInstantiatingReflector.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,85 @@
+package com.pgac.flatfile.morph;
+
+import com.pgac.flatfile.Entity;
+import com.pgac.flatfile.EntityFactory;
+import com.pgac.flatfile.IndexedEntityCollection;
+
+import net.sf.morph.reflect.InstantiatingReflector;
+import net.sf.morph.reflect.Reflector;
+import net.sf.morph.reflect.reflectors.BaseReflector;
+import net.sf.morph.reflect.reflectors.SimpleDelegatingReflector;
+
+/**
+ * Instantiates basic entities by sending the source object as a cue object
+ * to a configured EntityFactory.
+ */
+public class EntityInstantiatingReflector extends BaseReflector implements
+        InstantiatingReflector {
+    // use a SimpleDelegatingReflector prepended with an
+    // EntityCollectionReflector to get the
+    // size and contained type of source objects when implementing
+    // InstantiatingReflector
+    private static final SimpleDelegatingReflector CONTAINER_REFLECTOR = new SimpleDelegatingReflector(
+            new Reflector[] { new EntityCollectionReflector() }, true);
+
+    private EntityFactory entityFactory;
+
+    /**
+     * Create a new EntityInstantiatingReflector.
+     */
+    public EntityInstantiatingReflector() {
+        // default constructor
+    }
+
+    /**
+     * Create a new EntityInstantiatingReflector.
+     * @param entityFactory
+     */
+    public EntityInstantiatingReflector(EntityFactory entityFactory) {
+        setEntityFactory(entityFactory);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getReflectableClassesImpl()
+     */
+    protected Class[] getReflectableClassesImpl() throws Exception {
+        return new Class[] { Entity.class };
+    }
+
+    /**
+     * Get the entityFactory.
+     * @return EntityFactory.
+     */
+    public EntityFactory getEntityFactory() {
+        return entityFactory;
+    }
+
+    /**
+     * Set the entityFactory.
+     * @param entityFactory The EntityFactory entityFactory to set.
+     */
+    public void setEntityFactory(EntityFactory entityFactory) {
+        this.entityFactory = entityFactory;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#newInstanceImpl(java.lang.Class,
+     *      java.lang.Object)
+     */
+    protected Object newInstanceImpl(Class destType, Object source)
+            throws Exception {
+        Entity e = getEntityFactory().getEntity(source);
+        if (e instanceof IndexedEntityCollection) {
+            IndexedEntityCollection c = (IndexedEntityCollection) e;
+            if (c.isSizable()) {
+                c.setSize(CONTAINER_REFLECTOR.getSize(source));
+            }
+        }
+        return e;
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityInstantiatingReflector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityToByteArrayConverter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityToByteArrayConverter.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityToByteArrayConverter.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityToByteArrayConverter.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,43 @@
+package com.pgac.flatfile.morph;
+
+import java.util.Locale;
+
+import com.pgac.flatfile.Entity;
+
+import net.sf.morph.transform.transformers.BaseTransformer;
+import net.sf.morph.transform.DecoratedConverter;
+
+/**
+ *
+ */
+public class EntityToByteArrayConverter extends BaseTransformer implements
+        DecoratedConverter {
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getDestinationClassesImpl()
+     */
+    protected Class[] getDestinationClassesImpl() throws Exception {
+        return new Class[] { byte[].class };
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl()
+     */
+    protected Class[] getSourceClassesImpl() throws Exception {
+        return new Class[] { Entity.class };
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#convertImpl(java.lang.Class,
+     *      java.lang.Object, java.util.Locale)
+     */
+    protected Object convertImpl(Class destType, Object source, Locale locale)
+            throws Exception {
+        return ((Entity) source).getValue();
+    }
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/EntityToByteArrayConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/FieldOptionConstantConverter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/FieldOptionConstantConverter.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/FieldOptionConstantConverter.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/FieldOptionConstantConverter.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,69 @@
+package com.pgac.flatfile.morph;
+
+import java.util.Locale;
+
+import com.pgac.flatfile.FieldOption;
+
+import net.sf.morph.Defaults;
+import net.sf.morph.transform.DecoratedConverter;
+import net.sf.morph.transform.transformers.BaseTransformer;
+
+/**
+ * Convert text to FieldOption instances from class constants.
+ */
+public class FieldOptionConstantConverter extends BaseTransformer implements
+        DecoratedConverter {
+    private DecoratedConverter textConverter;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getDestinationClassesImpl()
+     */
+    protected Class[] getDestinationClassesImpl() throws Exception {
+        return new Class[] { FieldOption.class };
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl()
+     */
+    protected Class[] getSourceClassesImpl() throws Exception {
+        return getTextConverter().getSourceClasses();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#convertImpl(java.lang.Class,
+     *      java.lang.Object, java.util.Locale)
+     */
+    protected Object convertImpl(Class destinationClass, Object source,
+            Locale locale) throws Exception {
+        String constant = (String) getTextConverter().convert(String.class,
+                source, locale);
+        // return static field
+        return destinationClass.getField(constant).get(null);
+    }
+
+    /**
+     * Get the DecoratedConverter textConverter.
+     * @return DecoratedConverter
+     */
+    public synchronized DecoratedConverter getTextConverter() {
+        if (textConverter == null) {
+            setTextConverter(Defaults.createTextConverter());
+        }
+        return textConverter;
+    }
+
+    /**
+     * Set the DecoratedConverter textConverter.
+     * @param textConverter DecoratedConverter
+     */
+    public synchronized void setTextConverter(DecoratedConverter textConverter) {
+        this.textConverter = textConverter;
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/FieldOptionConstantConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionInstantiatingReflector.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionInstantiatingReflector.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionInstantiatingReflector.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionInstantiatingReflector.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,72 @@
+package com.pgac.flatfile.morph;
+
+import net.sf.morph.reflect.InstantiatingReflector;
+import net.sf.morph.reflect.Reflector;
+import net.sf.morph.reflect.reflectors.BaseReflector;
+import net.sf.morph.reflect.reflectors.SimpleDelegatingReflector;
+
+import com.pgac.flatfile.Entity;
+import com.pgac.flatfile.EntityArray;
+import com.pgac.flatfile.IndexedEntityCollection;
+
+/**
+ * IndexedEntityCollection InstantiatingReflector.
+ */
+public class IndexedEntityCollectionInstantiatingReflector extends
+        BaseReflector implements InstantiatingReflector {
+
+    // use a SimpleDelegatingReflector prepended with an
+    // EntityCollectionReflector to get the
+    // size and contained type of source objects when implementing
+    // InstantiatingReflector
+    private static final SimpleDelegatingReflector CONTAINER_REFLECTOR = new SimpleDelegatingReflector(
+            new Reflector[] { new EntityCollectionReflector() }, true);
+
+    private InstantiatingReflector componentReflector;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getReflectableClassesImpl()
+     */
+    protected Class[] getReflectableClassesImpl() throws Exception {
+        return new Class[] { IndexedEntityCollection.class };
+    }
+
+    /**
+     * Get the componentReflector.
+     * @return InstantiatingReflector.
+     */
+    public synchronized InstantiatingReflector getComponentReflector() {
+        return componentReflector;
+    }
+
+    /**
+     * Set the componentReflector.  Essential for use of this class as an InstantiatingReflector.
+     * @param componentReflector The InstantiatingReflector componentReflector to set.
+     */
+    public synchronized void setComponentReflector(
+            InstantiatingReflector componentReflector) {
+        this.componentReflector = componentReflector;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.reflectors.BaseEntityCollectionReflector#newInstanceImpl(java.lang.Class,
+     *      java.lang.Object)
+     */
+    protected Object newInstanceImpl(Class destType, Object source)
+            throws Exception {
+        int size = CONTAINER_REFLECTOR.getSize(source);
+        if (size == 0) {
+            return new EntityArray(0);
+        }
+        Class containedType = source == null ? null : CONTAINER_REFLECTOR
+                .getContainedType(source.getClass());
+        Entity prototype = (Entity) getComponentReflector().newInstance(
+                destType, containedType);
+        return new EntityArray(prototype, size);
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionInstantiatingReflector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionReflector.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionReflector.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionReflector.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionReflector.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,93 @@
+package com.pgac.flatfile.morph;
+
+import net.sf.morph.reflect.BeanReflector;
+import net.sf.morph.reflect.MutableIndexedContainerReflector;
+import net.sf.morph.reflect.SizableReflector;
+
+import com.pgac.flatfile.Entity;
+import com.pgac.flatfile.EntityArray;
+import com.pgac.flatfile.IndexedEntityCollection;
+
+/**
+ * IndexedEntityCollection Reflector.
+ */
+public class IndexedEntityCollectionReflector extends
+        BaseEntityCollectionReflector implements
+        MutableIndexedContainerReflector, SizableReflector, BeanReflector {
+    /**
+     * Prototype property constant.
+     */
+    public static final String IMPLICIT_PROPERTY_PROTOTYPE = "prototype";
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.reflect.BaseEntityCollectionReflector#getEntity(java.lang.Object,
+     *      int)
+     */
+    protected Entity getEntity(Object container, int index) throws Exception {
+        return ((IndexedEntityCollection) container).getChild(index);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getReflectableClassesImpl()
+     */
+    protected Class[] getReflectableClassesImpl() throws Exception {
+        return new Class[] { IndexedEntityCollection.class };
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.morph.BaseEntityCollectionReflector#isEntity(java.lang.Object,
+     *      java.lang.String)
+     */
+    protected boolean isEntity(Object bean, String propertyName)
+            throws Exception {
+        if (bean instanceof EntityArray
+                && IMPLICIT_PROPERTY_PROTOTYPE.equals(propertyName)) {
+            return true;
+        }
+        try {
+            int index = Integer.parseInt(propertyName);
+            return index < getSize(bean);
+        } catch (Exception e) {
+            // ignore
+        }
+        return false;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.morph.BaseEntityCollectionReflector#getImpl(java.lang.Object,
+     *      java.lang.String)
+     */
+    protected Object getImpl(Object bean, String propertyName) throws Exception {
+        return super.getImpl(bean, propertyName);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see com.pgac.flatfile.morph.BaseEntityCollectionReflector#getEntity(java.lang.Object, java.lang.String)
+     */
+    protected Entity getEntity(Object bean, String propertyName)
+            throws Exception {
+        if (bean instanceof EntityArray
+                && IMPLICIT_PROPERTY_PROTOTYPE.equals(propertyName)) {
+            return ((EntityArray) bean).getPrototype();
+        }
+        return super.getEntity(bean, propertyName);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see com.pgac.flatfile.morph.BaseEntityCollectionReflector#getSizeImpl(java.lang.Object)
+     */
+    protected int getSizeImpl(Object o) throws Exception {
+        int size = ((IndexedEntityCollection) o).size();
+        return size < 0 ? 0 : size;
+    }
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/IndexedEntityCollectionReflector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/NamedEntityCollectionReflector.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/NamedEntityCollectionReflector.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/NamedEntityCollectionReflector.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/NamedEntityCollectionReflector.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,64 @@
+package com.pgac.flatfile.morph;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import net.sf.morph.reflect.BeanReflector;
+import net.sf.morph.util.ContainerUtils;
+
+import com.pgac.flatfile.Entity;
+import com.pgac.flatfile.NamedEntityCollection;
+
+/**
+ * NamedEntityCollection Reflector.
+ */
+public class NamedEntityCollectionReflector extends
+        BaseEntityCollectionReflector implements BeanReflector {
+    private static final Class[] REFLECTABLE_CLASSES = { NamedEntityCollection.class };
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getReflectableClassesImpl()
+     */
+    protected Class[] getReflectableClassesImpl() throws Exception {
+        return REFLECTABLE_CLASSES;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.morph.BaseEntityCollectionReflector#isEntity(java.lang.Object,
+     *      java.lang.String)
+     */
+    protected boolean isEntity(Object bean, String propertyName)
+            throws Exception {
+        return ContainerUtils.contains(((NamedEntityCollection) bean)
+                .getChildNames(), propertyName);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.reflect.BaseEntityCollectionReflector#getEntity(java.lang.Object,
+     *      java.lang.String)
+     */
+    protected Entity getEntity(Object bean, String propertyName)
+            throws Exception {
+        return ((NamedEntityCollection) bean).getChild(propertyName);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.reflect.reflectors.BaseReflector#getPropertyNamesImpl(java.lang.Object)
+     */
+    protected String[] getPropertyNamesImpl(Object bean) throws Exception {
+        HashSet result = new HashSet(Arrays.asList(super
+                .getPropertyNamesImpl(bean)));
+        result.addAll(Arrays.asList(((NamedEntityCollection) bean)
+                .getChildNames()));
+        return (String[]) result.toArray(new String[result.size()]);
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/NamedEntityCollectionReflector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToByteConverter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToByteConverter.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToByteConverter.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToByteConverter.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,104 @@
+/**
+ * 
+ */
+package com.pgac.flatfile.morph;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Locale;
+
+import net.sf.morph.Defaults;
+import net.sf.morph.transform.DecoratedConverter;
+import net.sf.morph.transform.transformers.BaseTransformer;
+import net.sf.morph.util.ContainerUtils;
+
+/**
+ * Text to byte converter.
+ */
+public class TextToByteConverter extends BaseTransformer implements
+        DecoratedConverter {
+    private DecoratedConverter textConverter;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#convertImpl(java.lang.Class,
+     *      java.lang.Object, java.util.Locale)
+     */
+    protected Object convertImpl(Class destinationClass, Object source,
+            Locale locale) throws Exception {
+        if (isByte(destinationClass)) {
+            byte[] b = (byte[]) getTextConverter().convert(byte[].class,
+                    source, locale);
+            return b == null || b.length == 0 ? null : new Byte(b[0]);
+        }
+        byte[] b = source == null ? null : new byte[] { ((Byte) source)
+                .byteValue() };
+        return getTextConverter().convert(destinationClass, b, locale);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getDestinationClassesImpl()
+     */
+    protected Class[] getDestinationClassesImpl() throws Exception {
+        HashSet s = new HashSet();
+        s.addAll(Arrays.asList(getTextConverter().getDestinationClasses()));
+        s.add(byte.class);
+        s.add(Byte.class);
+        return (Class[]) s.toArray(new Class[s.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl()
+     */
+    protected Class[] getSourceClassesImpl() throws Exception {
+        HashSet s = new HashSet();
+        s.addAll(Arrays.asList(getTextConverter().getSourceClasses()));
+        s.add(byte.class);
+        s.add(Byte.class);
+        return (Class[]) s.toArray(new Class[s.size()]);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.sf.morph.transform.transformers.BaseTransformer#isTransformableImpl(java.lang.Class,
+     *      java.lang.Class)
+     */
+    protected boolean isTransformableImpl(Class destinationType,
+            Class sourceType) throws Exception {
+        DecoratedConverter cnv = getTextConverter();
+        return (isByte(sourceType) && ContainerUtils.contains(cnv
+                .getDestinationClasses(), destinationType))
+                || (isByte(destinationType) && ContainerUtils.contains(cnv
+                        .getSourceClasses(), sourceType));
+    }
+
+    private boolean isByte(Class c) {
+        return c == byte.class || c == Byte.class;
+    }
+
+    /**
+     * Get the DecoratedConverter textConverter.
+     * @return DecoratedConverter
+     */
+    public synchronized DecoratedConverter getTextConverter() {
+        if (textConverter == null) {
+            setTextConverter(Defaults.createTextConverter());
+        }
+        return textConverter;
+    }
+
+    /**
+     * Set the DecoratedConverter textConverter.
+     * @param textConverter DecoratedConverter
+     */
+    public synchronized void setTextConverter(DecoratedConverter textConverter) {
+        this.textConverter = textConverter;
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToByteConverter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToEntityCopier.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToEntityCopier.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToEntityCopier.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToEntityCopier.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,81 @@
+package com.pgac.flatfile.morph;
+
+import java.util.Locale;
+
+import com.pgac.flatfile.Entity;
+
+import net.sf.morph.Defaults;
+import net.sf.morph.transform.DecoratedCopier;
+import net.sf.morph.transform.converters.TextConverter;
+import net.sf.morph.transform.transformers.BaseTransformer;
+
+/**
+ * Copy any text type directly onto an Entity.
+ */
+public class TextToEntityCopier extends BaseTransformer implements
+        DecoratedCopier {
+    private TextConverter textConverter;
+
+    /**
+     * {@inheritDoc}
+     * @see net.sf.morph.transform.transformers.BaseTransformer#copyImpl(java.lang.Object, java.lang.Object, java.util.Locale, java.lang.Integer)
+     */
+    protected void copyImpl(Object destination, Object source, Locale locale,
+            Integer preferredTransformationType) throws Exception {
+        byte[] b = (byte[]) getTextConverter().convert(byte[].class, source,
+                locale);
+        ((Entity) destination).setValue(b);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see net.sf.morph.transform.transformers.BaseTransformer#setSourceClasses(java.lang.Class[])
+     */
+    public synchronized void setSourceClasses(Class[] sourceClasses) {
+        super.setSourceClasses(sourceClasses);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see net.sf.morph.transform.transformers.BaseTransformer#setDestinationClasses(java.lang.Class[])
+     */
+    public synchronized void setDestinationClasses(Class[] destinationClasses) {
+        super.setDestinationClasses(destinationClasses);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getDestinationClassesImpl()
+     */
+    protected Class[] getDestinationClassesImpl() throws Exception {
+        return new Class[] { Entity.class };
+    }
+
+    /**
+     * {@inheritDoc}
+     * @see net.sf.morph.transform.transformers.BaseTransformer#getSourceClassesImpl()
+     */
+    protected Class[] getSourceClassesImpl() throws Exception {
+        return getTextConverter().getSourceClasses();
+    }
+
+    /**
+     * Get the TextConverter textConverter.
+     * @return TextConverter
+     */
+    public synchronized TextConverter getTextConverter() {
+        if (textConverter == null) {
+            setTextConverter(Defaults.createTextConverter());
+        }
+        return textConverter;
+    }
+
+    /**
+     * Set the TextConverter textConverter.
+     * @param textConverter TextConverter
+     */
+    public synchronized void setTextConverter(TextConverter textConverter) {
+        this.textConverter = textConverter;
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/morph/TextToEntityCopier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ApplyOptions.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ApplyOptions.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ApplyOptions.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ApplyOptions.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,58 @@
+package com.pgac.flatfile.util;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sf.morph.lang.languages.SimpleLanguage;
+import net.sf.morph.reflect.Reflector;
+import net.sf.morph.reflect.reflectors.SimpleDelegatingReflector;
+import net.sf.morph.transform.Transformer;
+import net.sf.morph.transform.transformers.SimpleDelegatingTransformer;
+
+import com.pgac.flatfile.morph.EntityCollectionReflector;
+import com.pgac.flatfile.morph.FieldOptionConstantConverter;
+import com.pgac.flatfile.morph.TextToByteConverter;
+
+/**
+ * Utilities for applying options.
+ */
+public abstract class ApplyOptions {
+
+    private static final SimpleLanguage MORPH_LANGUAGE;
+
+    static {
+        MORPH_LANGUAGE = new SimpleLanguage();
+        MORPH_LANGUAGE.setReflector(new SimpleDelegatingReflector(
+                new Reflector[] { new EntityCollectionReflector() }, true));
+        MORPH_LANGUAGE.setConverter(new SimpleDelegatingTransformer(
+                new Transformer[] { new TextToByteConverter(),
+                        new FieldOptionConstantConverter() }, true));
+    }
+
+    /**
+     * Apply the specified option map to <code>o</code>.
+     * @param o Object
+     * @param options
+     * @return <code>o</code>.
+     */
+    public static Object apply(Object o, Map options) {
+        for (Iterator iter = options.entrySet().iterator(); iter.hasNext();) {
+            Map.Entry entry = (Map.Entry) iter.next();
+            apply(o, (String) entry.getKey(), entry.getValue());
+        }
+        return o;
+    }
+
+    /**
+     * Apply the specified option to <code>o</code>.
+     * @param o Object
+     * @param option String option name.
+     * @param value option value.
+     * @return <code>o</code>.
+     */
+    public static Object apply(Object o, String option, Object value) {
+        MORPH_LANGUAGE.set(o, option, value);
+        return o;
+    }
+
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ApplyOptions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/BasicFilterFactory.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/BasicFilterFactory.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/BasicFilterFactory.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/BasicFilterFactory.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,47 @@
+package com.pgac.flatfile.util;
+
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+
+/**
+ * Basic FilterFactory that creates an instance of a given InputStream subclass with a (InputStream) constructor.
+ */
+public class BasicFilterFactory extends FilterFactory {
+    private static final long serialVersionUID = 9080292216759574895L;
+    private static final Class[] PARAMETER_TYPES = new Class[] { InputStream.class };
+    private static final String HIERARCHY_ERROR = " does not inherit from "
+            + InputStream.class.getName();
+
+    private Constructor constructor;
+
+    /**
+     * Create a new BasicFilterFactory.
+     */
+    public BasicFilterFactory(Class clazz) {
+        if (!InputStream.class.isAssignableFrom(clazz)) {
+            throw new IllegalArgumentException(clazz + HIERARCHY_ERROR);
+        }
+        try {
+            constructor = clazz.getConstructor(PARAMETER_TYPES);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(clazz + ": " + e.toString());
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see com.pgac.fixedlength.util.FilterFactory#iGetFilter(java.io.InputStream)
+     */
+    protected InputStream iGetFilter(InputStream markIsSupported) {
+        if (constructor == null) {
+            throw new IllegalStateException();
+        }
+        try {
+            return (InputStream) constructor
+                    .newInstance(new Object[] { markIsSupported });
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/BasicFilterFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ConcatenatedInputStream.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ConcatenatedInputStream.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ConcatenatedInputStream.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ConcatenatedInputStream.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,70 @@
+package com.pgac.flatfile.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.collections.IteratorUtils;
+
+/**
+ * Unified InputStream representation of multiple concatenated InputStreams.
+ */
+public class ConcatenatedInputStream extends InputStream {
+    /** EOF */
+    public static final int EOF = -1;
+
+    private static final String NO_NULL = "null arguments are unacceptable";
+    private static final InputStream AT_EOF = new InputStream() {
+        public int read() throws IOException {
+            return EOF;
+        }
+    };
+
+    private Iterator iter;
+    private InputStream current;
+
+    /**
+     * Create a new ConcatenatedInputStream.
+     * @param src
+     */
+    public ConcatenatedInputStream(List/* <InputStream> */src) {
+        if (src == null) {
+            throw new IllegalArgumentException(NO_NULL);
+        }
+        iter = src.iterator();
+        next();
+    }
+
+    /**
+     * Convenience constructor.
+     * @param is0
+     * @param is1
+     */
+    public ConcatenatedInputStream(InputStream is0, InputStream is1) {
+        if (is0 == null || is1 == null) {
+            throw new IllegalArgumentException(NO_NULL);
+        }
+        // shortcuts:
+        current = is0;
+        iter = IteratorUtils.singletonIterator(is1);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.io.InputStream#read()
+     */
+    public int read() throws IOException {
+        int n = current.read();
+        while (n == EOF && current != AT_EOF) {
+            next();
+            n = current.read();
+        }
+        return n;
+    }
+
+    private void next() {
+        current = iter.hasNext() ? (InputStream) iter.next() : AT_EOF;
+    }
+}
\ No newline at end of file

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ConcatenatedInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/EmptyArray.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/EmptyArray.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/EmptyArray.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/EmptyArray.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,35 @@
+package com.pgac.flatfile.util;
+
+import java.lang.reflect.Array;
+
+import org.apache.commons.collections.map.LRUMap;
+
+/**
+ * Factory class for empty arrays, cached to reduce Object creation.
+ */
+public abstract class EmptyArray {
+    private static final LRUMap INSTANCES = new LRUMap();
+
+    /** Commonly needed empty array type. */
+    public static final Object[] OBJECT = (Object[]) getInstance(Object.class);
+
+    /** Commonly needed empty array type. */
+    public static final Class[] CLASS = (Class[]) getInstance(Class.class);
+
+    /** Commonly needed empty array type. */
+    public static final String[] STRING = (String[]) getInstance(String.class);
+
+    /**
+     * Get an empty array of the specified type.
+     * @param clazz
+     * @return
+     */
+    public static final synchronized Object getInstance(Class clazz) {
+        Object result = INSTANCES.get(clazz);
+        if (result == null) {
+            result = Array.newInstance(clazz, 0);
+            INSTANCES.put(clazz, result);
+        }
+        return result;
+    }
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/EmptyArray.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/FilterFactory.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/FilterFactory.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/FilterFactory.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/FilterFactory.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,28 @@
+package com.pgac.flatfile.util;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.Serializable;
+
+import com.pgac.flatfile.InputFilteringDynamicField;
+
+/**
+ * Filter factory interface designed for use with {@link InputFilteringDynamicField}.
+ */
+public abstract class FilterFactory implements Serializable {
+    /**
+     * Get an InputStream that filters the specified {@link InputStream}
+     * @param is the {@link InputStream} to filter
+     * @return an {@link InputStream}
+     */
+    public final InputStream getFilter(InputStream is) {
+        return iGetFilter(is.markSupported() ? is : new BufferedInputStream(is));
+    }
+
+    /**
+     * Template method to be implemented by subclasses.
+     * @param markIsSupported guaranteed to support mark()/reset().
+     * @return an {@link InputStream}
+     */
+    protected abstract InputStream iGetFilter(InputStream markIsSupported);
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/FilterFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/RepeatingInputStream.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/RepeatingInputStream.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/RepeatingInputStream.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/RepeatingInputStream.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,118 @@
+package com.pgac.flatfile.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+
+/**
+ * Provides factory methods to return InputStreams that return a repeating ordered
+ * sequence of bytes, optionally limiting output to some maximum total size.
+ */
+public abstract class RepeatingInputStream {
+
+    private static class RepeatOneByte extends InputStream {
+        private byte b;
+
+        private RepeatOneByte(byte b) {
+            this.b = b;
+        }
+
+        public int read() throws IOException {
+            return b;
+        }
+    }
+
+    private static class RepeatArray extends InputStream {
+        private byte[] b;
+        private int pos;
+
+        private RepeatArray(byte[] b) {
+            this.b = b;
+        }
+
+        public synchronized int read() throws IOException {
+            try {
+                return b[pos++];
+            } finally {
+                if (pos == b.length) {
+                    pos = 0;
+                }
+            }
+        }
+    }
+
+    private static class LimitedOutput extends InputStream {
+        private static final int EOF = -1;
+
+        private InputStream source;
+        private int bytesToReturn;
+        private int bytesReturned;
+
+        private LimitedOutput(InputStream source, int bytesToReturn) {
+            this.source = source;
+            this.bytesToReturn = bytesToReturn;
+        }
+
+        public int read() throws IOException {
+            if (bytesReturned == bytesToReturn) {
+                return EOF;
+            }
+            try {
+                return source.read();
+            } finally {
+                bytesReturned++;
+            }
+        }
+    }
+
+    /**
+     * Holds cached instances of single-byte RepeatingInputStreams.
+     */
+    // go ahead and init b/c we know we'll want a single-byte instance:
+    private static HashMap/* <Byte, RepeatOneByte> */INSTANCE_MAP = new HashMap();
+
+    /**
+     * Get an InputStream that will return the specified byte forever.
+     * @param b
+     * @return
+     */
+    public static synchronized InputStream getInstance(byte b) {
+        Byte bigByte = new Byte(b);
+        InputStream result = (InputStream) INSTANCE_MAP.get(bigByte);
+        if (result == null) {
+            result = new RepeatOneByte(b);
+            INSTANCE_MAP.put(bigByte, result);
+        }
+        return result;
+    }
+
+    /**
+     * Get an InputStream that will return the specified byte[] forever.
+     * @param b
+     * @return
+     */
+    public static InputStream getInstance(byte[] b) {
+        return b.length == 1 ? getInstance(b[0]) : new RepeatArray(b);
+    }
+
+    /**
+     * Get an InputStream that will return a single byte a limited number of times.
+     * @param b
+     * @param bytesToReturn
+     */
+    public static synchronized InputStream getInstance(byte b, int bytesToReturn) {
+        return new LimitedOutput(getInstance(b), bytesToReturn);
+    }
+
+    /**
+     * Get an InputStream that will return the specified byte sequence
+     * until a total of <code>bytesToReturn</code> bytes have been returned.
+     * @param b
+     * @param bytesToReturn
+     */
+    public static synchronized InputStream getInstance(byte[] b,
+            int bytesToReturn) {
+        return new LimitedOutput(getInstance(b), bytesToReturn);
+    }
+
+}
\ No newline at end of file

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/RepeatingInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ThresholdingInputStream.java
URL: http://svn.apache.org/viewvc/commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ThresholdingInputStream.java?rev=692147&view=auto
==============================================================================
--- commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ThresholdingInputStream.java (added)
+++ commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ThresholdingInputStream.java Thu Sep  4 09:39:28 2008
@@ -0,0 +1,95 @@
+package com.pgac.flatfile.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.input.CountingInputStream;
+
+/**
+ * FilterInputStream that limits the data returned from the proxy.
+ */
+public class ThresholdingInputStream extends CountingInputStream {
+    private static final int EOF = -1;
+
+    private int maximum;
+    private boolean closed;
+
+    /**
+     * Create a new ThresholdingInputStream.
+     * @param in the filtered stream
+     */
+    public ThresholdingInputStream(InputStream in, int maximum) {
+        super(in);
+        this.maximum = maximum;
+    }
+
+    /*
+     * NOTICE: implementing all three read(...) methods such that corresponding
+     * super methods are called
+     */
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.commons.io.input.CountingInputStream#read()
+     */
+    public synchronized int read() throws IOException {
+        assertNotClosed();
+        if (getCount() >= maximum) {
+            return EOF;
+        }
+        return super.read();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.commons.io.input.CountingInputStream#read(byte[], int,
+     *      int)
+     */
+    public synchronized int read(byte[] b, int off, int len) throws IOException {
+        assertNotClosed();
+        int n = maximum - getCount();
+        return n == 0 ? EOF : super.read(b, off, n < len ? n : len);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.commons.io.input.CountingInputStream#read(byte[], int,
+     *      int)
+     */
+    public synchronized int read(byte[] b) throws IOException {
+        assertNotClosed();
+        int n = maximum - getCount();
+        if (n == 0) {
+            return EOF;
+        }
+        if (n < b.length) {
+            byte[] buf = new byte[n];
+            System.arraycopy(b, 0, buf, 0, n);
+            try {
+                return super.read(buf);
+            } finally {
+                System.arraycopy(buf, 0, b, 0, n);
+            }
+        }
+        return super.read(b);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.commons.io.input.ProxyInputStream#close()
+     */
+    public synchronized void close() throws IOException {
+        this.closed = true;
+        super.close();
+    }
+
+    private synchronized void assertNotClosed() throws IOException {
+        if (closed) {
+            throw new IOException("Stream closed");
+        }
+    }
+}

Propchange: commons/sandbox/flatfile/trunk/src/java/com/pgac/flatfile/util/ThresholdingInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message