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 }