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 java.io.Serializable;
019    import java.util.ArrayList;
020    import java.util.Collection;
021    import java.util.Iterator;
022    
023    /**
024     * A ProcedureDescriptor contains information that is common for all types
025     * of procedures/functions that are used to handle the persistence operations.
026     * <br>
027     * Note: Be careful when use ProcedureDescriptor variables or caching
028     * ProcedureDescriptor 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: ProcedureDescriptor.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
033     */
034    public abstract class ProcedureDescriptor extends DescriptorBase implements Serializable
035    {
036            private static final long serialVersionUID = -8228331122289787173L;
037        //---------------------------------------------------------------
038        /**
039         * The the name of the procedure/function to invoke.
040         */
041        private String name;
042    
043        //---------------------------------------------------------------
044        /**
045         * The the field descriptor that will receive the return value from the procedure/function...
046         */
047        private FieldDescriptor returnValueFieldRef;
048    
049        //---------------------------------------------------------------
050        /**
051         * The class descriptor that this object is related to.
052         */
053        private ClassDescriptor classDescriptor;
054    
055        //---------------------------------------------------------------
056        /**
057         * The argument descriptor lists.
058         */
059        private ArrayList arguments = new ArrayList();
060    
061        //---------------------------------------------------------------
062        /**
063         * Constructor declaration
064         */
065        public ProcedureDescriptor(ClassDescriptor classDescriptor, String name)
066        {
067            this.classDescriptor = classDescriptor;
068            this.name = name;
069        }
070    
071        //---------------------------------------------------------------
072        /**
073         * Retrieve the the name of the procedure/function to invoke.
074         *
075         * @return The current value
076         */
077        public final String getName()
078        {
079            return this.name;
080        }
081    
082        //---------------------------------------------------------------
083        /**
084         * Change the field descriptor that will receive the return value
085         * from the procedure/function..
086         *
087         * @param fieldName the name of the field that will receive the
088         * return value from the procedure/function.
089         */
090        public final void setReturnValueFieldRef(String fieldName)
091        {
092            this.returnValueFieldRef = this.getClassDescriptor().getFieldDescriptorByName(fieldName);
093        }
094    
095        //---------------------------------------------------------------
096        /**
097         * Change the the field descriptor that will receive the return
098         * value from the procedure/function...
099         *
100         * @param fieldDescriptor the field descriptor that will receive the
101         * return value from the procedure/function.
102         */
103        public final void setReturnValueFieldRef(FieldDescriptor fieldDescriptor)
104        {
105            this.returnValueFieldRef = fieldDescriptor;
106        }
107    
108        //---------------------------------------------------------------
109        /**
110         * Retrieve the field descriptor that will receive the return value
111         * from the procedure/function...
112         *
113         * @return The current value
114         */
115        public final FieldDescriptor getReturnValueFieldRef()
116        {
117            return this.returnValueFieldRef;
118        }
119    
120        //---------------------------------------------------------------
121        /**
122         * Is there a return value for this procedure?
123         *
124         * @return <code>true</code> if there is a return value for this
125         * procedure.
126         */
127        public final boolean hasReturnValue()
128        {
129            return (this.returnValueFieldRef != null);
130        }
131    
132        //---------------------------------------------------------------
133        /**
134         * Does this procedure return any values to the 'caller'?
135         *
136         * @return <code>true</code> if the procedure returns at least 1
137         * value that is returned to the caller.
138         */
139        public final boolean hasReturnValues()
140        {
141            if (this.hasReturnValue())
142            {
143                return true;
144            }
145            else
146            {
147                // TODO: We may be able to 'pre-calculate' the results
148                // of this loop by just checking arguments as they are added
149                // The only problem is that the 'isReturnedbyProcedure' property
150                // can be modified once the argument is added to this procedure.
151                // If that occurs, then 'pre-calculated' results will be inacccurate.
152                Iterator iter = this.getArguments().iterator();
153                while (iter.hasNext())
154                {
155                    ArgumentDescriptor arg = (ArgumentDescriptor) iter.next();
156                    if (arg.getIsReturnedByProcedure())
157                    {
158                        return true;
159                    }
160                }
161            }
162            return false;
163        }
164    
165        //---------------------------------------------------------------
166        /**
167         * Retrieve the name of the field descriptor that will receive the
168         * return value from the procedure/function...
169         *
170         * @return The current value
171         */
172        public final String getReturnValueFieldRefName()
173        {
174            if (this.returnValueFieldRef == null)
175            {
176                return null;
177            }
178            else
179            {
180                return this.returnValueFieldRef.getAttributeName();
181            }
182        }
183    
184        //---------------------------------------------------------------
185        /**
186         * Retrieve the class descriptor that this object is related to.
187         *
188         * @return The current value
189         */
190        public final ClassDescriptor getClassDescriptor()
191        {
192            return this.classDescriptor;
193        }
194    
195        /*
196         * @see XmlCapable#toXML()
197         */
198        public abstract String toXML();
199    
200        //---------------------------------------------------------------
201        /**
202         * Add an argument
203         */
204        protected void addArgument(ArgumentDescriptor argument)
205        {
206            this.arguments.add(argument);
207        }
208    
209        //---------------------------------------------------------------
210        /**
211         * Set up arguments for each FieldDescriptor in an array.
212         */
213        protected void addArguments(FieldDescriptor field[])
214        {
215            for (int i = 0; i < field.length; i++)
216            {
217                ArgumentDescriptor arg = new ArgumentDescriptor(this);
218                arg.setValue(field[i].getAttributeName(), false);
219                this.addArgument(arg);
220            }
221        }
222    
223        //---------------------------------------------------------------
224        /**
225         * Get the argument descriptors for this procedure.
226         */
227        public final Collection getArguments()
228        {
229            return this.arguments;
230        }
231    
232        //---------------------------------------------------------------
233        /**
234         * Retrieves the number of arguments that are passed to the
235         * procedure that this descriptor represents.
236         * <p>
237         * Note: The value returned by this method does not reflect
238         * the presence of any return value for the procedure
239         */
240        public final int getArgumentCount()
241        {
242            return this.arguments.size();
243        }
244    }