001    package org.apache.fulcrum.intake.model;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.lang.reflect.Constructor;
023    import java.util.HashMap;
024    import java.util.Map;
025    
026    import org.apache.fulcrum.intake.IntakeException;
027    import org.apache.fulcrum.intake.xmlmodel.XmlField;
028    
029    /**
030     * Creates Field objects.
031     *
032     * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
033     * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
034     * @author <a href="mailto:Colin.Chalmers@maxware.nl">Colin Chalmers</a>
035     * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
036     * @version $Id: FieldFactory.java 670328 2008-06-22 09:34:11Z tv $
037     */
038    public abstract class FieldFactory
039    {
040        private static Map fieldCtors = initFieldCtors();
041    
042        private static Map initFieldCtors()
043        {
044            fieldCtors = new HashMap();
045    
046            fieldCtors.put("int", new FieldFactory.FieldCtor()
047            {
048                public Field getInstance(XmlField f, Group g)
049                        throws IntakeException
050                {
051                    return new IntegerField(f, g);
052                }
053            }
054            );
055            fieldCtors.put("boolean", new FieldFactory.FieldCtor()
056            {
057                public Field getInstance(XmlField f, Group g)
058                        throws IntakeException
059                {
060                    return new BooleanField(f, g);
061                }
062            }
063            );
064            fieldCtors.put("String", new FieldFactory.FieldCtor()
065            {
066                public Field getInstance(XmlField f, Group g)
067                        throws IntakeException
068                {
069                    return new StringField(f, g);
070                }
071            }
072            );
073            fieldCtors.put("BigDecimal", new FieldFactory.FieldCtor()
074            {
075                public Field getInstance(XmlField f, Group g)
076                        throws IntakeException
077                {
078                    return new BigDecimalField(f, g);
079                }
080            }
081            );
082            fieldCtors.put("FileItem", new FieldFactory.FieldCtor()
083            {
084                public Field getInstance(XmlField f, Group g)
085                        throws IntakeException
086                {
087                    return new FileItemField(f, g);
088                }
089            }
090            );
091            fieldCtors.put("DateString", new FieldFactory.FieldCtor()
092            {
093                public Field getInstance(XmlField f, Group g)
094                        throws IntakeException
095                {
096                    return new DateStringField(f, g);
097                }
098            }
099            );
100            fieldCtors.put("float", new FieldFactory.FieldCtor()
101            {
102                public Field getInstance(XmlField f, Group g)
103                        throws IntakeException
104                {
105                    return new FloatField(f, g);
106                }
107            }
108            );
109            fieldCtors.put("double", new FieldFactory.FieldCtor()
110            {
111                public Field getInstance(XmlField f, Group g)
112                        throws IntakeException
113                {
114                    return new DoubleField(f, g);
115                }
116            }
117            );
118            fieldCtors.put("short", new FieldFactory.FieldCtor()
119            {
120                public Field getInstance(XmlField f, Group g)
121                        throws IntakeException
122                {
123                    return new ShortField(f, g);
124                }
125            }
126            );
127            fieldCtors.put("long", new FieldFactory.FieldCtor()
128            {
129                public Field getInstance(XmlField f, Group g)
130                        throws IntakeException
131                {
132                    return new LongField(f, g);
133                }
134            }
135            );
136            fieldCtors.put("custom", new FieldFactory.FieldCtor()
137            {
138                public Field getInstance(XmlField f, Group g)
139                        throws IntakeException
140                {
141                    String fieldClass = f.getFieldClass();
142    
143                    if (fieldClass != null
144                            && fieldClass.indexOf('.') == -1)
145                    {
146                        fieldClass = Field.defaultFieldPackage + fieldClass;
147                    }
148    
149                    if (fieldClass != null)
150                    {
151                        Class field;
152    
153                        try
154                        {
155                            field = Class.forName(fieldClass);
156                            Constructor constructor =
157                                field.getConstructor(new Class[] { XmlField.class, Group.class });
158    
159                            return (Field)constructor.newInstance(new Object[] { f, g });
160                        }
161                        catch (ClassNotFoundException e)
162                        {
163                            throw new IntakeException(
164                                    "Could not load Field class("
165                                    + fieldClass + ")", e);
166                        }
167                        catch (Exception e)
168                        {
169                            throw new IntakeException(
170                                    "Could not create new instance of Field("
171                                    + fieldClass + ")", e);
172                        }
173                    }
174                    else
175                    {
176                        throw new IntakeException(
177                                "Custom field types must define a fieldClass");
178                    }
179                }
180            }
181            );
182            return fieldCtors;
183        }
184    
185        protected static abstract class FieldCtor
186        {
187            public Field getInstance(XmlField f, Group g) throws IntakeException
188            {
189                return null;
190            }
191        }
192    
193        /**
194         * Creates a Field object appropriate for the type specified
195         * in the xml file.
196         *
197         * @param xmlField a <code>XmlField</code> value
198         * @return a <code>Field</code> value
199         * @throws IntakeException indicates that an unknown type was specified for a field.
200         */
201        public static final Field getInstance(XmlField xmlField, Group xmlGroup)
202                throws IntakeException
203        {
204            FieldCtor fieldCtor = null;
205            Field field = null;
206            String type = xmlField.getType();
207    
208            fieldCtor = (FieldCtor) fieldCtors.get(type);
209            if (fieldCtor == null)
210            {
211                throw new IntakeException("An Unsupported type has been specified for " +
212                        xmlField.getName() + " in group " + xmlGroup.getIntakeGroupName() + " type = " + type);
213            }
214            else
215            {
216                field = fieldCtor.getInstance(xmlField, xmlGroup);
217            }
218    
219            return field;
220        }
221    }