001: /**
002: * Objective Database Abstraction Layer (ODAL)
003: * Copyright (c) 2004, The ODAL Development Group
004: * All rights reserved.
005: * For definition of the ODAL Development Group please refer to LICENCE.txt file
006: *
007: * Distributable under LGPL license.
008: * See terms of license at gnu.org.
009: */package com.completex.objective.components.persistency;
010:
011: import com.completex.objective.components.persistency.core.DatabasePolicy;
012: import com.completex.objective.util.PropertyMap;
013:
014: import java.util.Map;
015:
016: /**
017: * Represents stored procedure ccall parameter
018: *
019: * @author Gennady Krizhevsky
020: */
021: public class CallParameter extends Parameter {
022:
023: public static final String TAG_REF_CURSOR = "refCursor";
024: public static final String TAG_MODE = "mode";
025: public static final String TAG_JDBC_TYPE = "jdbcType";
026:
027: /**
028: * Marker for reference cursor. When setting refernce cursor parameter
029: * always use CallParameter.PARAMETER_REF_CURSOR
030: */
031: public static final RefCursorParameter PARAMETER_REF_CURSOR = new RefCursorParameter();
032:
033: /**
034: * Marker for IN call parameter
035: */
036: public static final Mode MODE_IN = Mode.IN;
037: /**
038: * Marker for OUT call parameter
039: */
040: public static final Mode MODE_OUT = Mode.OUT;
041: /**
042: * Marker for IN and OUT call parameter
043: */
044: public static final Mode MODE_INOUT = Mode.INOUT;
045:
046: private static final Mode[] MODES = new Mode[] { MODE_IN, MODE_OUT,
047: MODE_INOUT };
048:
049: private Mode mode;
050: private int jdbcScale = -1;
051: private boolean skipBackPopulation;
052:
053: public CallParameter(Map parameter) {
054: super (parameter);
055: }
056:
057: /**
058: * Creates new call parameter in default mode - MODE_INOUT
059: *
060: * @see Mode
061: * @see CallParameter#MODE_INOUT
062: */
063: public CallParameter() {
064: mode = MODE_INOUT;
065: }
066:
067: /**
068: * @param value value of this parameter. Setting it in constructor only makes sense for
069: * IN parameters
070: * @param mode one of CallParameter.MODE_XXX fields
071: * @param jdbcType one of java.sql.Types types
072: * @see java.sql.Types
073: */
074: public CallParameter(Object value, Mode mode, int jdbcType) {
075: super (value);
076: setMode(mode);
077: setJdbcAttributes(jdbcType, null);
078: }
079:
080: /**
081: * Note that jdbcType and jdbcTypeName are only used for OUT parameters
082: *
083: * @param value value value of this parameter. Setting it in constructor only makes sense for
084: * IN parameters
085: * @param mode mode one of CallParameter.MODE_XXX fields
086: * @param jdbcType one of java.sql.Types types
087: * @param jdbcTypeName the fully-qualified name of an SQL structured type
088: * @see java.sql.Types
089: */
090: public CallParameter(Object value, Mode mode, int jdbcType,
091: String jdbcTypeName) {
092: super (value);
093: setMode(mode);
094: setJdbcAttributes(jdbcType, jdbcTypeName);
095: }
096:
097: /**
098: * @param value value value of this parameter. Setting it in constructor only makes sense for
099: * IN parameters
100: * @param mode mode one of CallParameter.MODE_XXX fields
101: * @param type column type of the field this parameter corresponds to
102: * @see java.sql.Types
103: */
104: public CallParameter(Object value, Mode mode, ColumnType type) {
105: super (type, value);
106: setMode(mode);
107: if (type.getDefaultJdbcType() == 0) {
108: throw new OdalRuntimePersistencyException(
109: "Column type ["
110: + type
111: + "] does not provide DefaultJdbcType which is why this constuctor cannot be used");
112: }
113: setJdbcAttributes(type.getDefaultJdbcType(), null);
114: }
115:
116: /**
117: * Note that one may need both ColumnType and jdbcType/jdbcTypeName set. Even though ColumnType
118: * has jdbcType inside it works rather as a default one.
119: * In case the parameter one is set it will take precedence.
120: * We can take as an example when it would we beneficial to have both set the case when
121: * the object field is described as being of ColumnType.OBJECT type but when retrieving
122: * java.sql.Types.Clob is specified and the object field will actually be set to Clob.
123: *
124: * @param value value value of this parameter. Setting it in constructor only makes sense for
125: * IN parameters
126: * @param mode mode one of CallParameter.MODE_XXX fields
127: * @param type column type of the field this parameter corresponds to
128: * @param jdbcType one of java.sql.Types types
129: * @param jdbcTypeName the fully-qualified name of an SQL structured type
130: * @see java.sql.Types
131: */
132: public CallParameter(Object value, Mode mode, ColumnType type,
133: int jdbcType, String jdbcTypeName) {
134: super (type, value);
135: setMode(mode);
136: setJdbcAttributes(jdbcType, jdbcTypeName);
137: }
138:
139: /**
140: * Sets value for OUT parameter. It is called by Persistency after the retrieval.
141: *
142: * @param value retrieved value
143: * @throws OdalRuntimePersistencyException
144: * if this is not OUT parameter
145: */
146: public void setOutValue(Object value) {
147: if (isOut()) {
148: setValue(value);
149: } else {
150: throw new OdalRuntimePersistencyException(
151: "Cannot set IN parameter: only OUT ones can be set with this method");
152: }
153: }
154:
155: private void setJdbcAttributes(int jdbcType, String jdbcTypeName) {
156: if (jdbcType == 0) {
157: throw new OdalRuntimePersistencyException(
158: "jdbcType must be specified");
159: }
160: setJdbcType(jdbcType);
161: setJdbcTypeName(jdbcTypeName);
162: }
163:
164: /**
165: * Returns scale the desired number of digits to the right of the
166: * decimal point. It must be greater than or equal to zero.
167: *
168: * @return scale - the desired number of digits to the right of the
169: * decimal point. It must be greater than or equal to zero.
170: */
171: public int getJdbcScale() {
172: return jdbcScale;
173: }
174:
175: /**
176: * Sets scale - the desired number of digits to the right of the
177: * decimal point. It must be greater than or equal to zero.
178: *
179: * @param jdbcScale the desired number of digits to the right of the
180: * decimal point. It must be greater than or equal to zero.
181: */
182: public void setJdbcScale(int jdbcScale) {
183: this .jdbcScale = jdbcScale;
184: }
185:
186: /**
187: * Returns jdbcType one of java.sql.Types types
188: *
189: * @param policy
190: * @return jdbcType one of java.sql.Types types
191: */
192: public int getJdbcType(DatabasePolicy policy) {
193: return getJdbcType();
194: }
195:
196: /**
197: * Returns jdbcTypeName the fully-qualified name of an SQL structured type
198: *
199: * @param policy
200: * @return jdbcTypeName the fully-qualified name of an SQL structured type
201: */
202: public String getJdbcTypeName(DatabasePolicy policy) {
203: return getJdbcTypeName();
204: }
205:
206: /**
207: * Returns true if the value population for OUT parameter is not needed or desirable
208: *
209: * @return true if the value population for OUT parameter is not needed or desirable
210: */
211: public boolean isSkipBackPopulation() {
212: return skipBackPopulation;
213: }
214:
215: /**
216: * Sets true if the value population for OUT parameter is not needed or desirable
217: *
218: * @param skipBackPopulation true if the value population for OUT parameter is not needed or desirable
219: */
220: public void setSkipBackPopulation(boolean skipBackPopulation) {
221: this .skipBackPopulation = skipBackPopulation;
222: }
223:
224: /**
225: * Returns mode that defines this parameters as being IN/OUT or INOUT - one of CallParameter.MODE_XXX fields
226: *
227: * @return mode that defines this parameters as being IN/OUT or INOUT - one of CallParameter.MODE_XXX fields
228: */
229: public Mode getMode() {
230: return mode;
231: }
232:
233: /**
234: * Sets mode that defines this parameters as being IN/OUT or INOUT - one of CallParameter.MODE_XXX fields
235: *
236: * @param mode mode that defines this parameters as being IN/OUT or INOUT - one of CallParameter.MODE_XXX fields
237: */
238: public void setMode(Mode mode) {
239: if (mode != null) {
240: this .mode = mode;
241: }
242: }
243:
244: /**
245: * Returns true if mode == MODE_IN || mode == MODE_INOUT.
246: *
247: * @return true if mode == MODE_IN || mode == MODE_INOUT.
248: */
249: public boolean isIn() {
250: return mode == MODE_IN || mode == MODE_INOUT;
251: }
252:
253: /**
254: * Returns true if mode == MODE_OUT || mode == MODE_INOUT.
255: *
256: * @return true if mode == MODE_OUT || mode == MODE_INOUT.
257: */
258: public boolean isOut() {
259: return mode == MODE_OUT || mode == MODE_INOUT;
260: }
261:
262: /**
263: * Returns true if this is reference cursor OUT parameter
264: *
265: * @return true if this is reference cursor OUT parameter
266: */
267: public boolean isRefCursor() {
268: return this == PARAMETER_REF_CURSOR;
269: }
270:
271: /**
272: * Mode by its name
273: *
274: * @param name mode name
275: * @return Mode by its name
276: */
277: public static Mode toMode(String name) {
278: Mode mode = null;
279: if (name != null) {
280: for (int i = 0; i < MODES.length; i++) {
281: if (MODES[i].getName().equalsIgnoreCase(name)) {
282: mode = MODES[i];
283: break;
284: }
285: }
286: }
287: return mode;
288: }
289:
290: /**
291: * @see Parameter#fromMap0(java.util.Map)
292: */
293: protected PropertyMap fromMap0(Map parameter) {
294: PropertyMap parameterMap = super .fromMap0(parameter);
295: String modeProperty = parameterMap.getProperty(TAG_MODE);
296: this .mode = toMode(modeProperty);
297: setJdbcType(parameterMap.getInt(TAG_JDBC_TYPE, 0));
298: return parameterMap;
299: }
300:
301: //
302: //
303: // Util classes:
304: //
305: //
306:
307: /**
308: * Defines parameter as being IN, OUT or INOUT
309: */
310: public static class Mode {
311: protected static final Mode IN = new Mode("IN");
312: protected static final Mode OUT = new Mode("OUT");
313: protected static final Mode INOUT = new Mode("INOUT");
314:
315: private String name;
316:
317: protected Mode(String name) {
318: this .name = name;
319: }
320:
321: public String toString() {
322: return name;
323: }
324:
325: public String getName() {
326: return name;
327: }
328: }
329:
330: /**
331: * Reference cursor OUT parameter implementation
332: */
333: public static class RefCursorParameter extends CallParameter {
334: RefCursorParameter() {
335: setMode(Mode.OUT);
336: setSkipBackPopulation(true);
337: }
338:
339: public int getJdbcType(DatabasePolicy policy) {
340: return policy.getRefCursorJdbcType();
341: }
342: }
343: }
|