001    package org.apache.ojb.broker.metadata;
002    
003    /* Copyright 2003-2005 The Apache Software Foundation
004     *
005     * Licensed under the Apache License, Version 2.0 (the "License");
006     * you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    import org.apache.commons.lang.builder.ToStringBuilder;
019    import org.apache.commons.lang.builder.ToStringStyle;
020    import org.apache.ojb.broker.accesslayer.conversions.FieldConversion;
021    import java.io.Serializable;
022    
023    /**
024     * An ArgumentDescriptor contains information that defines a single argument
025     * that is passed to a procedure/function.
026     * <br>
027     * Note: Be careful when use ArgumentDescriptor variables or caching
028     * ArgumentDescriptor instances, because instances could become invalid
029     * during runtime (see {@link MetadataManager}).
030     *
031     * @author <a href="mailto:rongallagher@bellsouth.net">Ron Gallagher<a>
032     * @version $Id: ArgumentDescriptor.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
033     */
034    public final class ArgumentDescriptor extends DescriptorBase implements XmlCapable, Serializable
035    {
036            private static final long serialVersionUID = 5205304260023247711L;
037    
038        private static final int SOURCE_NULL = 0;
039        private static final int SOURCE_FIELD = 1;
040        private static final int SOURCE_VALUE = 2;
041        private int fieldSource = SOURCE_NULL;
042        private String constantValue = null;
043        private String fieldRefName = null;
044        private boolean returnedByProcedure = false;
045    
046        //---------------------------------------------------------------
047        /**
048         * The procedure descriptor that this object is related to.
049         */
050        private ProcedureDescriptor procedureDescriptor;
051    
052        //---------------------------------------------------------------
053        /**
054         * Constructor declaration.  By default, this object will be configured
055         * so that the value returned by {@link #fieldSource} will be null.  To
056         * change this, call either version of the setValue method.
057         *
058         * @see #setValue()
059         * @see #setValue(String)
060         * @see #setValue(String,boolean)
061         */
062        public ArgumentDescriptor(ProcedureDescriptor procedureDescriptor)
063        {
064            this.procedureDescriptor = procedureDescriptor;
065            this.setValue();
066        }
067    
068        /**
069         * Sets up this object to represent a null value.
070         */
071        public void setValue()
072        {
073            this.fieldSource = SOURCE_NULL;
074            this.fieldRefName = null;
075            this.returnedByProcedure = false;
076            this.constantValue = null;
077        }
078    
079        /**
080         * Sets up this object to represent a value that is derived from a field
081         * in the corresponding class-descriptor.
082         * <p>
083         * If the value of <code>fieldRefName</code> is blank or refers to an
084         * invalid field reference, then the value of the corresponding argument
085         * will be set to null. In this case, {@link #getIsReturnedByProcedure}
086         * will be set to <code>false</code>, regardless of the value of the
087         * <code>returnedByProcedure</code> argument.
088         *
089         * @param fieldRefName the name of the field reference that provides the
090         *          value of this argument.
091         * @param returnedByProcedure indicates that the value of the argument
092         *          is returned by the procedure that is invoked.
093         */
094        public void setValue(String fieldRefName, boolean returnedByProcedure)
095        {
096            this.fieldSource = SOURCE_FIELD;
097            this.fieldRefName = fieldRefName;
098            this.returnedByProcedure = returnedByProcedure;
099            this.constantValue = null;
100    
101            // If the field reference is not valid, then disregard the value
102            // of the returnedByProcedure argument.
103            if (this.getFieldRef() == null)
104            {
105                this.returnedByProcedure = false;
106            }
107    
108            // If the field reference is not valid, then disregard the value
109            // of the returnedByProcedure argument.
110            if (this.getFieldRef() == null)
111            {
112                this.returnedByProcedure = false;
113            }
114        }
115    
116        /**
117         * Sets up this object to represent an argument that will be set to a
118         * constant value.
119         *
120         * @param constantValue the constant value.
121         */
122        public void setValue(String constantValue)
123        {
124            this.fieldSource = SOURCE_VALUE;
125            this.fieldRefName = null;
126            this.returnedByProcedure = false;
127            this.constantValue = constantValue;
128        }
129    
130        public boolean getIsReturnedByProcedure()
131        {
132            return this.returnedByProcedure;
133        }
134    
135        public Object getValue(Object objekt)
136        {
137            switch (this.fieldSource)
138            {
139                case SOURCE_FIELD :
140                    if (objekt == null)
141                    {
142                        return null;
143                    }
144                    else
145                    {
146                        FieldDescriptor fd = this.getFieldRef();
147                        Object value = null;
148                        FieldConversion conversion = null;
149                        if (fd != null)
150                        {
151                            conversion = fd.getFieldConversion();
152                            value = fd.getPersistentField().get(objekt);
153                            if (conversion != null)
154                            {
155                                value = conversion.javaToSql(value);
156                            }
157                        }
158                        return value;
159                    }
160                case SOURCE_VALUE :
161                    return this.constantValue;
162                case SOURCE_NULL :
163                    return null;
164                default :
165                    return null;
166            }
167        }
168    
169        public void saveValue(Object objekt, Object value)
170        {
171            if ((this.fieldSource == SOURCE_FIELD) && (this.returnedByProcedure))
172            {
173                FieldDescriptor fd = this.getFieldRef();
174                FieldConversion conversion = null;
175                if (fd != null)
176                {
177                    conversion = fd.getFieldConversion();
178                    if (conversion == null)
179                    {
180                        fd.getPersistentField().set(objekt, value);
181                    }
182                    else
183                    {
184                        fd.getPersistentField().set(objekt, conversion.sqlToJava(value));
185                    }
186                }
187            }
188        }
189    
190        //---------------------------------------------------------------
191        /**
192         * Retrieve the field descriptor that this argument is related to.
193         * <p>
194         * This reference can only be set via the {@link #setValue(String,boolean)}
195         * method.
196         * @return The current value
197         */
198        public final FieldDescriptor getFieldRef()
199        {
200            if (this.fieldSource == SOURCE_FIELD)
201            {
202                return this.getProcedureDescriptor().getClassDescriptor().getFieldDescriptorByName(
203                    this.fieldRefName);
204            }
205            else
206            {
207                return null;
208            }
209        }
210    
211        /**
212         * Retrieve the jdbc type for the field descriptor that is related
213         * to this argument.
214         */
215        public final int getJdbcType()
216        {
217            switch (this.fieldSource)
218            {
219                case SOURCE_FIELD :
220                    return this.getFieldRef().getJdbcType().getType();
221                case SOURCE_NULL :
222                    return java.sql.Types.NULL;
223                case SOURCE_VALUE :
224                    return java.sql.Types.VARCHAR;
225                default :
226                    return java.sql.Types.NULL;
227            }
228        }
229    
230        //---------------------------------------------------------------
231        /**
232         * Retrieve the procedure descriptor that this object is related to.
233         *
234         * @return The current value
235         */
236        public final ProcedureDescriptor getProcedureDescriptor()
237        {
238            return this.procedureDescriptor;
239        }
240    
241        /*
242         * @see XmlCapable#toXML()
243         */
244        public String toXML()
245        {
246            String eol = System.getProperty("line.separator");
247            RepositoryTags tags = RepositoryTags.getInstance();
248    
249            // The result
250            String result = "     ";
251    
252            switch (this.fieldSource)
253            {
254                case SOURCE_FIELD :
255                    result += " " + tags.getOpeningTagNonClosingById(RUNTIME_ARGUMENT);
256                    result += " " + tags.getAttribute(FIELD_REF, this.fieldRefName);
257                    result += " " + tags.getAttribute(RETURN, String.valueOf(this.returnedByProcedure));
258                    result += "/>";
259                    break;
260                case SOURCE_VALUE :
261                    result += " " + tags.getOpeningTagNonClosingById(CONSTANT_ARGUMENT);
262                    result += " " + tags.getAttribute(VALUE, this.constantValue);
263                    result += "/>";
264                    break;
265                case SOURCE_NULL :
266                    result += " " + tags.getOpeningTagNonClosingById(RUNTIME_ARGUMENT);
267                    result += "/>";
268                    break;
269                default :
270                    break;
271            }
272    
273            // Return the result.
274            return (result + eol);
275        }
276    
277        //---------------------------------------------------------------
278        /**
279         * Provide a string representation of this object
280         *
281         * @return a string representation of this object
282         */
283        public String toString()
284        {
285            ToStringBuilder buf = new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE);
286            switch (this.fieldSource)
287            {
288                case SOURCE_FIELD :
289                    {
290                        buf.append("fieldRefName", this.fieldRefName);
291                        buf.append("returnedByProcedure", this.returnedByProcedure);
292                        break;
293                    }
294                case SOURCE_NULL :
295                    {
296                        break;
297                    }
298                case SOURCE_VALUE :
299                    {
300                        buf.append("constantValue", this.constantValue);
301                        break;
302                    }
303            }
304            return buf.toString();
305        }
306    }