0001: /* ====================================================================
0002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
0003: *
0004: * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
0005: *
0006: * Redistribution and use in source and binary forms, with or without
0007: * modification, are permitted provided that the following conditions
0008: * are met:
0009: *
0010: * 1. Redistributions of source code must retain the above copyright
0011: * notice, this list of conditions and the following disclaimer.
0012: *
0013: * 2. Redistributions in binary form must reproduce the above copyright
0014: * notice, this list of conditions and the following disclaimer in
0015: * the documentation and/or other materials provided with the
0016: * distribution.
0017: *
0018: * 3. The end-user documentation included with the redistribution,
0019: * if any, must include the following acknowledgment:
0020: * "This product includes software developed by Jcorporate Ltd.
0021: * (http://www.jcorporate.com/)."
0022: * Alternately, this acknowledgment may appear in the software itself,
0023: * if and wherever such third-party acknowledgments normally appear.
0024: *
0025: * 4. "Jcorporate" and product names such as "Expresso" must
0026: * not be used to endorse or promote products derived from this
0027: * software without prior written permission. For written permission,
0028: * please contact info@jcorporate.com.
0029: *
0030: * 5. Products derived from this software may not be called "Expresso",
0031: * or other Jcorporate product names; nor may "Expresso" or other
0032: * Jcorporate product names appear in their name, without prior
0033: * written permission of Jcorporate Ltd.
0034: *
0035: * 6. No product derived from this software may compete in the same
0036: * market space, i.e. framework, without prior written permission
0037: * of Jcorporate Ltd. For written permission, please contact
0038: * partners@jcorporate.com.
0039: *
0040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
0044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
0046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0051: * SUCH DAMAGE.
0052: * ====================================================================
0053: *
0054: * This software consists of voluntary contributions made by many
0055: * individuals on behalf of the Jcorporate Ltd. Contributions back
0056: * to the project(s) are encouraged when you make modifications.
0057: * Please send them to support@jcorporate.com. For more information
0058: * on Jcorporate Ltd. and its products, please see
0059: * <http://www.jcorporate.com/>.
0060: *
0061: * Portions of this software are based upon other open source
0062: * products and are subject to their respective licenses.
0063: */
0064: package com.jcorporate.expresso.core.dataobjects.jdbc;
0065:
0066: import com.jcorporate.expresso.core.dataobjects.DataException;
0067: import com.jcorporate.expresso.core.dataobjects.DataFieldMetaData;
0068: import com.jcorporate.expresso.core.dataobjects.DataObject;
0069: import com.jcorporate.expresso.core.dataobjects.DataObjectMetaData;
0070: import com.jcorporate.expresso.core.dataobjects.Defineable;
0071: import com.jcorporate.expresso.core.db.DBException;
0072: import com.jcorporate.expresso.core.i18n.Messages;
0073: import com.jcorporate.expresso.core.misc.StringUtil;
0074:
0075: import java.util.ArrayList;
0076: import java.util.Collections;
0077: import java.util.HashMap;
0078: import java.util.Iterator;
0079: import java.util.List;
0080: import java.util.Locale;
0081: import java.util.Map;
0082: import java.util.Set;
0083: import java.util.StringTokenizer;
0084:
0085: /**
0086: * Not yet released - do not use in your own code yet.
0087: * This object provides an implementation of DataObjectMetaData that is used
0088: * for the various join operations. It's job is to provide the descriptive
0089: * services required for applications such as DBMaint to generically access
0090: * the JoinedDataObject.
0091: *
0092: * @author Michael Rimov
0093: * <p/>
0094: * Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
0095: * @since $DatabaseSchema $Date: 2004/11/18 02:03:27 $
0096: */
0097: public class JoinedDataObjectMetaData implements DataObjectMetaData {
0098:
0099: /**
0100: * Hash that contains the DB objects that relate to make up this query,
0101: * indexed by the "short" name provided by the user.
0102: */
0103: private HashMap myDataObjects = new HashMap();
0104:
0105: /**
0106: * A list of dataobjects as they were added to the join
0107: */
0108: private List dataObjects = new ArrayList();
0109:
0110: /**
0111: * Gives the order of the aliases An arrayList of Strings
0112: */
0113: private List aliasesInOrder = new ArrayList();
0114:
0115: /**
0116: * Fields to retrieve for each DataObject
0117: */
0118: private Map fieldsToRetrieve = new HashMap();
0119:
0120: /**
0121: * Friendly display name of this join.
0122: */
0123: private String description = "Joined Data Object";
0124:
0125: /**
0126: * Use a DISTINCT keyword right after SELECT keyword
0127: */
0128: private boolean selectDistinct = false;
0129:
0130: /**
0131: * List of all the field names for all the data objects.
0132: */
0133: private ArrayList allFieldList = null;
0134:
0135: /**
0136: * List of all the key field names for the data object.
0137: */
0138: private ArrayList keyFieldList = null;
0139:
0140: /**
0141: * Permission overrides
0142: */
0143: private Map permissions = null;
0144:
0145: /**
0146: * List of all fields in a key -> metadata method.
0147: */
0148: HashMap allFieldMap = null;
0149:
0150: /**
0151: * A map keyed by 'foreigndbobj.foreignprimarykey' and pointing to the
0152: * 'local alias'.'foreign key'
0153: */
0154: HashMap primaryToForeignKeyMap = new HashMap();
0155:
0156: /**
0157: * Another map, this time in reverse. Given the local key, get the foreign
0158: * key
0159: */
0160: HashMap foreignKeyToPrimaryKeyMap = new HashMap();
0161:
0162: /**
0163: * Lookup Map of all the relations
0164: */
0165: HashMap relations = new HashMap();
0166:
0167: private List sqlRelationList = new ArrayList();
0168:
0169: /**
0170: * Details
0171: */
0172: private Set allDetails = null;
0173:
0174: /**
0175: * The name of the metadata
0176: */
0177: private String name = "";
0178:
0179: /**
0180: * Default constructor
0181: */
0182: public JoinedDataObjectMetaData() {
0183: }
0184:
0185: public Map getDataObjects() {
0186: return Collections.unmodifiableMap(myDataObjects);
0187: }
0188:
0189: /**
0190: * Retrieves a list of DataObjects that were used in Order
0191: *
0192: * @return java.util.List of JDBCDataObjects
0193: */
0194: public List getDataObjectsInOrder() {
0195: return this .dataObjects;
0196: }
0197:
0198: /**
0199: * Retrieves a list of Aliases in order that they were added
0200: *
0201: * @return java.util.List of Strings
0202: */
0203: public List getAliasesInOrder() {
0204: return this .aliasesInOrder;
0205: }
0206:
0207: /**
0208: * Retrieve the default value for the specified
0209: *
0210: * @param fieldName the name of the field to check
0211: * @return java.lang.String
0212: */
0213: public String getDefaultValue(String fieldName) {
0214: String values[] = this .getObjectAndField(fieldName);
0215: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0216: DataObjectMetaData metadata = oneObj.getMetaData();
0217: return metadata.getDefaultValue(values[1]);
0218: }
0219:
0220: /**
0221: * Add a DB Object to the objects being used for this multidbobj query. The
0222: * object is specified with a full classname, then a "short" name used to
0223: * refer to it in this object. For example, the class name might be
0224: * com.jcorporate.expresso.services.dbobj.SchemaList, the short name might
0225: * be "schema".
0226: *
0227: * @param dataObjectClass java.lang.String
0228: * @param alias java.lang.String
0229: * @param definitionName [optional] The definition name if the DataObject is
0230: * Defineable
0231: * @param fieldExpressionList [optional] pipe-delimited list of fields to
0232: * retrieve for this DataObject
0233: * @throws IllegalArgumentException if the Class is inappropriate for the system.
0234: */
0235: public void addDataObject(Class dataObjectClass,
0236: String definitionName, String alias,
0237: String fieldExpressionList) throws DataException,
0238: IllegalArgumentException {
0239: if (dataObjectClass == null) {
0240: throw new IllegalArgumentException(
0241: "Must specify a class name");
0242: }
0243:
0244: if (StringUtil.notNull(alias).equals("")) {
0245: throw new IllegalArgumentException(
0246: "Must specify a short name");
0247: }
0248:
0249: DataObject oneDBObj = null;
0250:
0251: try {
0252: oneDBObj = (DataObject) dataObjectClass.newInstance();
0253: } catch (InstantiationException ie) {
0254: throw new DataException(":DBObject '"
0255: + dataObjectClass.getName()
0256: + "' cannot be instantiated", ie);
0257: } catch (IllegalAccessException iae) {
0258: throw new DataException(
0259: ":Illegal access loading DBObject '"
0260: + dataObjectClass.getName() + "'", iae);
0261: }
0262:
0263: if (oneDBObj instanceof Defineable) {
0264: ((Defineable) oneDBObj).setDefinitionName(definitionName);
0265: }
0266:
0267: oneDBObj.setAttribute("shortName", alias);
0268: myDataObjects.put(alias, oneDBObj);
0269: this .dataObjects.add(oneDBObj);
0270: this .aliasesInOrder.add(alias);
0271:
0272: if (fieldExpressionList != null) {
0273: ArrayList fields = new ArrayList();
0274: StringTokenizer stok = new StringTokenizer(
0275: fieldExpressionList, "|");
0276: while (stok.hasMoreTokens()) {
0277: String fieldExpression = (String) stok.nextToken();
0278: // test for parentheses. If we find any we are dealing with a
0279: // column expression, e.g SUM(fieldName)
0280: int lastOpen = fieldExpression.lastIndexOf("(");
0281: if (lastOpen == -1) {
0282: fields.add(new FieldList(fieldExpression,
0283: fieldExpression, false));
0284: continue;
0285: }
0286: int firstClosed = fieldExpression.indexOf(")");
0287: if (firstClosed == -1) {
0288: throw new DataException(
0289: ":Invalid expression for DBObject '"
0290: + dataObjectClass.getName());
0291: }
0292:
0293: String fieldName = fieldExpression.substring(
0294: lastOpen + 1, firstClosed);
0295: int comma = fieldName.indexOf(",");
0296: if (comma != -1) {
0297: fieldName = fieldName.substring(comma);
0298: }
0299: JDBCDataObject JDBObj = (JDBCDataObject) oneDBObj;
0300: fieldExpression = StringUtil.replaceStringOnce(
0301: fieldExpression, fieldName, JDBObj
0302: .getJDBCMetaData().getTargetTable()
0303: + "." + fieldName);
0304: fields.add(new FieldList(fieldExpression, fieldName,
0305: true));
0306: }
0307: fieldsToRetrieve.put(alias, fields);
0308: }
0309: }
0310:
0311: /**
0312: * Returns the detail set for the primary data object
0313: *
0314: * @return java.util.Set
0315: */
0316: public synchronized Set getDetailSet() {
0317: if (allDetails == null) {
0318: allDetails = new java.util.HashSet();
0319: for (Iterator i = this .dataObjects.iterator(); i.hasNext();) {
0320: JDBCDataObject oneDataObject = (JDBCDataObject) i
0321: .next();
0322: allDetails.addAll(oneDataObject.getMetaData()
0323: .getDetailSet());
0324: }
0325: }
0326:
0327: return allDetails;
0328: }
0329:
0330: /**
0331: * Retrieve the local key fields.
0332: *
0333: * @param detailName the name of the detail dbobject
0334: * @return java.lang.String
0335: */
0336: public String getDetailFieldsLocal(String detailName) {
0337: if (allDetails == null) {
0338: return "";
0339: }
0340:
0341: int index = 0;
0342: for (Iterator i = this .dataObjects.iterator(); i.hasNext(); index++) {
0343: JDBCDataObject oneDataObject = (JDBCDataObject) i.next();
0344: String detailFields = oneDataObject.getMetaData()
0345: .getDetailFieldsLocal(detailName);
0346:
0347: if (detailFields != null && detailFields.length() > 0) {
0348: String prefix = (String) this .getAliasesInOrder().get(
0349: index)
0350: + ".";
0351: java.lang.StringBuffer returnValue = new java.lang.StringBuffer(
0352: 64);
0353: java.util.StringTokenizer stok = new java.util.StringTokenizer(
0354: detailFields, "|");
0355: boolean needPipe = false;
0356: while (stok.hasMoreTokens()) {
0357: if (needPipe) {
0358: returnValue.append("|");
0359: } else {
0360: needPipe = true;
0361: }
0362: String oneField = stok.nextToken();
0363: returnValue.append(prefix);
0364: returnValue.append(oneField);
0365: }
0366:
0367: return returnValue.toString();
0368: }
0369: }
0370:
0371: return "";
0372: }
0373:
0374: /**
0375: * Retrieve the foreign key fields
0376: *
0377: * @param detailName the name of the detail dbobject
0378: * @return java.lang.String
0379: */
0380: public synchronized String getDetailFieldsForeign(String detailName) {
0381: if (allDetails == null) {
0382: return "";
0383: }
0384:
0385: for (Iterator i = this .dataObjects.iterator(); i.hasNext();) {
0386: JDBCDataObject oneDataObject = (JDBCDataObject) i.next();
0387: String detailFields = oneDataObject.getMetaData()
0388: .getDetailFieldsForeign(detailName);
0389:
0390: if (detailFields != null && detailFields.length() > 0) {
0391: return detailFields;
0392: // String prefix = (String)this.getAliasesInOrder().get(index) + ".";
0393: // java.lang.StringBuffer returnValue = new java.lang.StringBuffer(64);
0394: // java.util.StringTokenizer stok = new java.util.StringTokenizer(detailFields,"|");
0395: // boolean needPipe = false;
0396: // while (stok.hasMoreTokens()) {
0397: // if (needPipe) {
0398: // returnValue.append("|");
0399: // } else {
0400: // needPipe = true;
0401: // }
0402: // String oneField = stok.nextToken();
0403: // returnValue.append(prefix);
0404: // returnValue.append(oneField);
0405: // }
0406: //
0407: // return returnValue.toString();
0408: }
0409: }
0410:
0411: return "";
0412: }
0413:
0414: /**
0415: * Retrieves whether the value is null
0416: *
0417: * @param fieldName the name of the field to check
0418: * @return boolean true if it allows null
0419: */
0420: public boolean isAllowsNull(String fieldName) throws DBException {
0421: String values[] = this .getObjectAndField(fieldName);
0422: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0423: DataObjectMetaData metadata = oneObj.getMetaData();
0424: return metadata.isAllowsNull(values[1]);
0425: }
0426:
0427: /**
0428: * Removes the attribute specified by field name and attrib name
0429: *
0430: * @param fieldName the name of the field to modify
0431: * @param attribName the attribute to remove
0432: */
0433: public void removeAttribute(String fieldName, String attribName) {
0434: String values[] = this .getObjectAndField(fieldName);
0435: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0436: DataObjectMetaData metadata = oneObj.getMetaData();
0437: metadata.removeAttribute(values[1], attribName);
0438: }
0439:
0440: /**
0441: * Sets the attribute for the particular field
0442: *
0443: * @param fieldName the name of the field to modify
0444: * @param attribName the attribute to set
0445: * @param attribValue the value to set the attribute for.
0446: * @throws DBException upon error
0447: */
0448: public void setAttribute(String fieldName, String attribName,
0449: Object attribValue) throws DBException {
0450: String values[] = this .getObjectAndField(fieldName);
0451: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0452: DataObjectMetaData metadata = oneObj.getMetaData();
0453: metadata.setAttribute(values[1], attribName, attribValue);
0454: }
0455:
0456: /**
0457: * Retrieve the attribute for the field
0458: *
0459: * @param fieldName the field name to get the attribute for
0460: * @param attribName the attribute name
0461: * @return Object the attribute value. [May be null]
0462: * @throws DBException upon error
0463: */
0464: public Object getAttribute(String fieldName, String attribName)
0465: throws DBException {
0466: String values[] = this .getObjectAndField(fieldName);
0467: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0468: DataObjectMetaData metadata = oneObj.getMetaData();
0469: return metadata.getAttribute(values[1], attribName);
0470: }
0471:
0472: /**
0473: * Disable change logging of all objects of this type
0474: */
0475: public void disableLogging() {
0476: for (Iterator i = this .myDataObjects.keySet().iterator(); i
0477: .hasNext();) {
0478: String key = (String) i.next();
0479: DataObject value = (DataObject) myDataObjects.get(key);
0480: value.getMetaData().disableLogging();
0481: }
0482: }
0483:
0484: /**
0485: * Enable logging of changes to this object. Change logging writes an entry to
0486: * the ChangeLog object every time an add, update, or delete is made to this
0487: * object. It is used to track important tables, such as user information,
0488: * account information, etc.
0489: */
0490: public void enableLogging() {
0491: for (Iterator i = this .myDataObjects.keySet().iterator(); i
0492: .hasNext();) {
0493: String key = (String) i.next();
0494: DataObject value = (DataObject) myDataObjects.get(key);
0495: value.getMetaData().enableLogging();
0496: }
0497: }
0498:
0499: /**
0500: * Retrieves whether or not change logging is enabled for a particular
0501: * data object
0502: *
0503: * @return boolean true if logging is enabled.
0504: */
0505: public boolean isLoggingEnabled() {
0506: return this .getPrimaryDataObject().getMetaData()
0507: .isLoggingEnabled();
0508: }
0509:
0510: /**
0511: * Check if a certain name is a field (of any kind) in this DBOBject
0512: * since SQL is case insensitive, ignore case of field name for match,
0513: * this method takes longer, so use isField if the field name is known precisely
0514: *
0515: * @param fieldName the name of the field to check
0516: * @return internal format for field name if matched, or null if no match
0517: */
0518: public String isFieldIgnoreCase(String fieldName) {
0519: String values[] = this .getObjectAndField(fieldName);
0520: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0521: DataObjectMetaData metadata = oneObj.getMetaData();
0522: return metadata.isFieldIgnoreCase(values[1]);
0523: }
0524:
0525: /**
0526: * Check if a certain name is a field (of any kind) in this DBOBject
0527: *
0528: * @param fieldName the name of the field to check
0529: * @return true if the field name exists
0530: */
0531: public boolean isField(String fieldName) {
0532: String values[] = this .getObjectAndField(fieldName);
0533: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0534: DataObjectMetaData metadata = oneObj.getMetaData();
0535: return metadata.isField(values[1]);
0536: }
0537:
0538: /**
0539: * Return the "allFields" Hashtable, which contains all of the DBField objects
0540: * that make up this DB object. The field names are of the format [objectalias].[fieldname]
0541: * <p/>
0542: * This does not return foreign fields that are keyed to local fields. They are automatically
0543: * set whenever a foreign key in the local object is set.
0544: *
0545: * @return java.util.HashMap
0546: */
0547: public synchronized HashMap getAllFieldsMap() {
0548: if (this .allFieldMap == null) {
0549: for (Iterator i = this .myDataObjects.keySet().iterator(); i
0550: .hasNext();) {
0551: String key = (String) i.next();
0552:
0553: DataObject oneObj = (DataObject) myDataObjects.get(key);
0554: HashMap fieldMap = oneObj.getMetaData()
0555: .getAllFieldsMap();
0556: for (Iterator j = fieldMap.keySet().iterator(); j
0557: .hasNext();) {
0558: String fieldName = (String) j.next();
0559: DataObjectMetaData metadata = (DataObjectMetaData) fieldMap
0560: .get(fieldName);
0561: String fullFieldName = key + "." + fieldName;
0562: if (this .foreignKeyToPrimaryKeyMap
0563: .containsKey(fullFieldName)) {
0564: continue;
0565: } else if (metadata.getFieldMetadata(fieldName)
0566: .isCharacterLongObjectType()) {
0567: continue;
0568: } else {
0569: this .allFieldMap.put(key + "." + fieldName,
0570: metadata);
0571: }
0572: }
0573:
0574: }
0575: }
0576:
0577: return this .allFieldMap;
0578: }
0579:
0580: /**
0581: * Return the List containing the details of fields to retrieve
0582: * for the DataObject with the given alias
0583: *
0584: * @param alias
0585: * @return the list of FieldList objects with field details
0586: */
0587: public List getFieldsToRetrieve(String alias) {
0588: return (List) this .fieldsToRetrieve.get(alias);
0589: }
0590:
0591: /**
0592: * Return the "allKeys" hash, containing the DBField objects that make up
0593: * the primary key for this db object.
0594: *
0595: * @return java.util.HashMap
0596: */
0597: public HashMap getAllKeysMap() {
0598: return this .getPrimaryDataObject().getMetaData()
0599: .getAllKeysMap();
0600: }
0601:
0602: /**
0603: * return the current object's character set
0604: *
0605: * @return java.lang.String
0606: */
0607: public String getCharset() {
0608: DataObject oneObj = this .getPrimaryDataObject();
0609: return oneObj.getMetaData().getCharset();
0610: }
0611:
0612: /**
0613: * Retrieves the cache size for the primary object
0614: *
0615: * @return int the size of the cache for the object
0616: */
0617: public int getCacheSize() {
0618: DataObject oneObj = this .getPrimaryDataObject();
0619: return oneObj.getMetaData().getCacheSize();
0620: }
0621:
0622: /**
0623: * Sets the cache size for this DBObject
0624: *
0625: * @param newValue the new value. Must be >= -2
0626: * @throws IllegalArgumentException if newValue < -2
0627: */
0628: public void setCacheSize(int newValue) {
0629: DataObject oneObj = this .getPrimaryDataObject();
0630: oneObj.getMetaData().setCacheSize(newValue);
0631: }
0632:
0633: /**
0634: * Retrieve the description of the dataobject join
0635: *
0636: * @return java.lang.String
0637: */
0638: public String getDescription() {
0639: return this .description;
0640: }
0641:
0642: /**
0643: * Retrieve an i18n'ized description as per the locale defined for the
0644: * 'client'
0645: *
0646: * @param l the Locale to use. If null, will use the System default Locale
0647: * @param fieldName the name of the field to retrieve the i18n'ized description
0648: * for.
0649: * @return an i18n'ized string.
0650: */
0651: public String getDescription(java.util.Locale l, String fieldName) {
0652: String values[] = this .getObjectAndField(fieldName);
0653: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0654: DataObjectMetaData metadata = oneObj.getMetaData();
0655: return metadata.getDescription(l, values[1]);
0656: }
0657:
0658: /**
0659: * Get the unlocalized description for a field name
0660: *
0661: * @param fieldName name of the field
0662: * @return java.lang.String
0663: * @throws DBException upon error
0664: */
0665: public String getDescription(String fieldName) throws DBException {
0666: String values[] = this .getObjectAndField(fieldName);
0667: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0668: DataObjectMetaData metadata = oneObj.getMetaData();
0669: return metadata.getDescription(values[1]);
0670: }
0671:
0672: /**
0673: * Retrieve the metadata for the particular field
0674: *
0675: * @param fieldName the name of the field to retrieve the metadata
0676: * @return the Field metadata.
0677: */
0678: public DataFieldMetaData getFieldMetadata(String fieldName) {
0679: String values[] = this .getObjectAndField(fieldName);
0680: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0681: DataObjectMetaData metadata = oneObj.getMetaData();
0682: return metadata.getFieldMetadata(values[1]);
0683: }
0684:
0685: /**
0686: * Retrieve a list of all the field names
0687: *
0688: * @return java.util.ArrayList
0689: */
0690: public synchronized ArrayList getFieldListArray() {
0691:
0692: //
0693: //Check if we need to build the all field list.
0694: //
0695: if (this .allFieldList == null) {
0696: ArrayList newList = new ArrayList(10);
0697: for (Iterator i = this .dataObjects.iterator(); i.hasNext();) {
0698: DataObject oneObj = (DataObject) i.next();
0699: ArrayList fieldList = oneObj.getMetaData()
0700: .getFieldListArray();
0701: String dbobjName = null;
0702:
0703: //
0704: //Find the key for this data object
0705: //
0706: for (Iterator k = this .myDataObjects.keySet()
0707: .iterator(); k.hasNext();) {
0708: String key = (String) k.next();
0709: JDBCDataObject obj = (JDBCDataObject) myDataObjects
0710: .get(key);
0711: //
0712: //We only want to check if it was the same instance we put
0713: //on the map.. we don't care if the objects themselves are
0714: //equal
0715: //
0716: if (oneObj == obj) {
0717: dbobjName = key;
0718: break;
0719: }
0720: }
0721:
0722: //
0723: //
0724: //
0725: if (dbobjName == null) {
0726: throw new IllegalStateException(
0727: "Unable to find short name for: "
0728: + oneObj.getClass().getName());
0729: }
0730:
0731: //
0732: //Iterate through the fields and add them as long as it is a primary
0733: //key in another field.
0734: //
0735: for (Iterator j = fieldList.iterator(); j.hasNext();) {
0736: String fieldName = (String) j.next();
0737: String completeFieldName = dbobjName + "."
0738: + fieldName;
0739: if (this .foreignKeyToPrimaryKeyMap
0740: .containsKey(completeFieldName)) {
0741: continue;
0742: } else if (oneObj.getMetaData().getFieldMetadata(
0743: fieldName).isCharacterLongObjectType()) {
0744: continue;
0745: } else {
0746: newList.add(completeFieldName);
0747: }
0748: }
0749:
0750: }
0751:
0752: this .allFieldList = newList;
0753: }
0754: return allFieldList;
0755: }
0756:
0757: /**
0758: * Retrieves the key field list array... which in reality is the key fields
0759: * of the primary data object
0760: *
0761: * @return java.util.ArrayList
0762: */
0763: public synchronized ArrayList getKeyFieldListArray() {
0764: if (this .keyFieldList == null) {
0765: keyFieldList = new ArrayList(this .getPrimaryDataObject()
0766: .getMetaData().getKeyFieldListArray());
0767: String primaryAlias = this .getPrimaryAlias();
0768: for (int i = 0; i < keyFieldList.size(); i++) {
0769: keyFieldList.set(i, primaryAlias + "."
0770: + (String) keyFieldList.get(i));
0771: }
0772: }
0773: return keyFieldList;
0774: }
0775:
0776: /**
0777: * Return the length of a field
0778: *
0779: * @param fieldName The name of the field
0780: * @return String: The length of the field
0781: * @throws DBException If there is no such field in this object
0782: */
0783: public String getLength(String fieldName) throws DBException {
0784: String values[] = this .getObjectAndField(fieldName);
0785: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0786: DataObjectMetaData metadata = oneObj.getMetaData();
0787: return metadata.getLength(values[1]);
0788: }
0789:
0790: /**
0791: * Return the length of a field as an integer
0792: *
0793: * @param fieldName The name of the field
0794: * @return integer: The length of the field
0795: * @throws DBException If there is no such field in this object
0796: */
0797: public int getLengthInt(String fieldName) throws DBException {
0798: String values[] = this .getObjectAndField(fieldName);
0799: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0800: DataObjectMetaData metadata = oneObj.getMetaData();
0801: return metadata.getLengthInt(values[1]);
0802: }
0803:
0804: /**
0805: * Retrieve the precision of a particular field
0806: *
0807: * @param fieldName The name of the field
0808: * @return integer for demcimal precision of the field
0809: */
0810: public int getPrecision(String fieldName) throws DBException {
0811: String values[] = this .getObjectAndField(fieldName);
0812: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0813: DataObjectMetaData metadata = oneObj.getMetaData();
0814: return metadata.getPrecision(values[1]);
0815: }
0816:
0817: /**
0818: * Get a field's lookup object - this is the name of another database
0819: * object that can be used to look up valid values for this object. The lookup
0820: * object for a field is set in the db objects setupFields method, and is used
0821: * by the DBMaint servlet to provide automatic lookup links for fields.
0822: *
0823: * @param fieldName Field name to check
0824: * @return String specifying the className of the lookup object
0825: * @throws DBException If the specified field does not exist.
0826: */
0827: public String getLookupObject(String fieldName) throws DBException {
0828: String values[] = this .getObjectAndField(fieldName);
0829: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0830: DataObjectMetaData metadata = oneObj.getMetaData();
0831: return metadata.getLookupObject(values[1]);
0832: }
0833:
0834: /**
0835: * When you get a lookup object, to perform a complete mapping between the
0836: * two, you need to know what field name in the remote object maps to this
0837: * field.
0838: *
0839: * @param fieldName the name of the field to look up.
0840: * @return java.lang.String or null if there is no lookup field
0841: * @throws IllegalArgumentException if the field name does not exist
0842: */
0843: public String getLookupField(String fieldName) {
0844: String values[] = this .getObjectAndField(fieldName);
0845: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0846: DataObjectMetaData metadata = oneObj.getMetaData();
0847: return metadata.getLookupField(values[1]);
0848: }
0849:
0850: /**
0851: * Get the name of this object
0852: *
0853: * @return String The database object name, or the table name if none
0854: * has been assigned
0855: */
0856: public String getName() {
0857: return this .name;
0858: }
0859:
0860: /**
0861: * Return the type of a field - this method returns the internal Expresso type
0862: *
0863: * @param fieldName The name of the field
0864: * @return String: The type of the field
0865: * @throws DBException If there is no such field in this object
0866: */
0867: public String getType(String fieldName) throws DBException {
0868: String values[] = this .getObjectAndField(fieldName);
0869: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0870: DataObjectMetaData metadata = oneObj.getMetaData();
0871: return metadata.getType(values[1]);
0872: }
0873:
0874: /**
0875: * This method will return a boolean true if the field is defined in the DBOBject,
0876: * false otherwise.
0877: * Creation date: (8/8/00 11:04:32 AM)
0878: *
0879: * @param fieldName java.lang.String
0880: * @return boolean
0881: */
0882: public boolean hasField(String fieldName) {
0883: String values[] = this .getObjectAndField(fieldName);
0884: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0885: DataObjectMetaData metadata = oneObj.getMetaData();
0886: return metadata.hasField(values[1]);
0887: }
0888:
0889: /**
0890: * Method called to determine if a particular field is multi-valued,
0891: * that is does it have a set of specific values and descriptions
0892: *
0893: * @param fieldName Name of the field
0894: * @return boolean True if the field is multi-valued, false if not
0895: * @throws DBException If there is no such field
0896: */
0897: public boolean isMultiValued(String fieldName) throws DBException {
0898: String values[] = this .getObjectAndField(fieldName);
0899: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0900: DataObjectMetaData metadata = oneObj.getMetaData();
0901: return metadata.isMultiValued(values[1]);
0902: }
0903:
0904: /**
0905: * Is a given field readOnly - these fields are not offered for entry
0906: * when a form is produced by the generic database maintenance servlet
0907: *
0908: * @param fieldName name of the field to check
0909: * @return true of the field is "read only", false if it is not
0910: * @throws DBException Ff there is no such field
0911: */
0912: public boolean isReadOnly(String fieldName) throws DBException {
0913: String values[] = this .getObjectAndField(fieldName);
0914: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0915: DataObjectMetaData metadata = oneObj.getMetaData();
0916: return metadata.isReadOnly(values[1]);
0917: }
0918:
0919: /**
0920: * Is a given field 'secret' - these fields are not shown
0921: * when a list is produced by the generic database maintenance servlet (DBMaint).
0922: * This means that only users with update permission to the record can see the
0923: * value of the specified field.
0924: * <p/>
0925: * see #setSecret(String)
0926: *
0927: * @param fieldName The name of the field to check
0928: * @return True if the field is 'secret', false if it is not
0929: * @throws DBException If there is no such field.
0930: */
0931: public boolean isSecret(String fieldName) throws DBException {
0932: String values[] = this .getObjectAndField(fieldName);
0933: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0934: DataObjectMetaData metadata = oneObj.getMetaData();
0935: return metadata.isSecret(values[1]);
0936: }
0937:
0938: /**
0939: * Is a given field virtual? A virtual field is not stored in the target table
0940: * for this object - it may be computed, or stored in another table.
0941: *
0942: * @param fieldName The name of the field to check
0943: * see #addVirtualField(String, String, int, String)
0944: * @return True of the field is virtual, false if it is not
0945: * @throws DBException If there is no such field
0946: */
0947: public boolean isVirtual(String fieldName) throws DBException {
0948: String values[] = this .getObjectAndField(fieldName);
0949: DataObject oneObj = (DataObject) myDataObjects.get(values[0]);
0950: DataObjectMetaData metadata = oneObj.getMetaData();
0951: return metadata.isVirtual(values[1]);
0952: }
0953:
0954: /**
0955: * Turn on or off the facility to verify that when an update is made that at
0956: * least one record got updated. If this flag is on, and no records get updated,
0957: * the update() method throws an Exception. Note that for some databases, if the
0958: * existing record is not changed (e.g. it was already identical to what
0959: * was being updated) this counts "no update" (notably, mySQL does this).
0960: *
0961: * @param newFlag True to turn on checking, false to turn it off
0962: */
0963: public void setCheckZeroUpdate(boolean newFlag) {
0964: for (Iterator i = this .myDataObjects.values().iterator(); i
0965: .hasNext();) {
0966: DataObject oneObj = (DataObject) i.next();
0967: oneObj.getMetaData().setCheckZeroUpdate(newFlag);
0968: }
0969: }
0970:
0971: /**
0972: * Retrieves whether or not checkZeroUpdate is enabled for this data object
0973: *
0974: * @return true if checkZeroUpdate() is enabled
0975: */
0976: public boolean checkZeroUpdate() {
0977: return this .getPrimaryDataObject().getMetaData()
0978: .checkZeroUpdate();
0979: }
0980:
0981: /**
0982: * Sets the description for the data object join
0983: *
0984: * @param newDescription the description to set for the Join
0985: */
0986: public void setDescription(String newDescription) {
0987: description = newDescription;
0988: }
0989:
0990: /**
0991: * Sets the name for this joined data object metadata... in this case
0992: * the definition name
0993: *
0994: * @param theName the name of the join [Usually =='s the definition]
0995: */
0996: public void setName(String theName) {
0997: this .name = theName;
0998: }
0999:
1000: /**
1001: * Retrieve the schema class name
1002: *
1003: * @return the schema class of for the join
1004: */
1005: public String getSchema() {
1006: return this .getPrimaryDataObject().getMetaData().getSchema();
1007: }
1008:
1009: /**
1010: * Return the Schema Name of the current database object.
1011: *
1012: * @return String: Schema name of the target table of this database object
1013: * @throws DataException upon error
1014: * <p/>
1015: * author Yves Henri AMAIZO <amy_amaizo@compuserve.com>
1016: */
1017: public String getTargetDbSchema() {
1018: return ((JDBCObjectMetaData) this .getPrimaryDataObject()
1019: .getMetaData()).getTargetDbSchema();
1020: } /* getTargetDbSchema() */
1021:
1022: /**
1023: * Return the Schema Name of the current database object.
1024: *
1025: * @return String: Schema name of the target table of this database object
1026: * @throws DataException upon error
1027: * <p/>
1028: * author Yves Henri AMAIZO <amy_amaizo@compuserve.com>
1029: */
1030: public String getTargetDbCatalog() {
1031: return ((JDBCObjectMetaData) this .getPrimaryDataObject()
1032: .getMetaData()).getTargetDbCatalog();
1033: } /* getTargetDbSchema() */
1034:
1035: /**
1036: * Set the target table for this DBObject. Note that an object
1037: * can span tables by the use of virtual fields, but that this table
1038: * is the default table for the object.
1039: *
1040: * @param theTable Table for this object
1041: * @throws DBException author Yves Henri AMAIZO <amy_amaizo@compuserve.com>
1042: */
1043: public String getTargetSQLTable(String dataContext)
1044: throws DataException {
1045: return ((JDBCObjectMetaData) this .getPrimaryDataObject()
1046: .getMetaData()).getTargetSQLTable(this
1047: .getPrimaryDataObject().getDataContext());
1048: }
1049:
1050: /**
1051: * <p>This convenience method iterates through all the
1052: * fields belonging to this <code>DBObject</code>
1053: * returns an array of field names ( <code>String</code> ).</p>
1054: *
1055: * @return String array of all field names in this object.
1056: * <p/>
1057: * author Peter Pilgrim <peter.pilgrim@db.com>
1058: */
1059: public String[] getFields() {
1060: ArrayList list = this .getFieldListArray();
1061:
1062: String returnValue[] = new String[list.size()];
1063:
1064: return (String[]) list.toArray(returnValue);
1065: }
1066:
1067: /**
1068: * Retrieve the table description in a localized way. If l == null, the
1069: * function uses the system locale to generate the value. If unable to
1070: * locate the key in the message bundle, the key becomes the return value.
1071: *
1072: * @param l the Locale to use for rendering the table description
1073: * @return java.lang.String
1074: */
1075: public String getDescription(Locale l) {
1076: String key = this .getDescription();
1077:
1078: if (key == null || key.length() == 0) {
1079: return "Unknown Table";
1080: }
1081:
1082: if (l == null) {
1083: l = Locale.getDefault();
1084: }
1085:
1086: String schema = this .getSchema();
1087: if (schema == null || schema.length() == 0) {
1088: schema = com.jcorporate.expresso.core.ExpressoSchema.class
1089: .getName();
1090: }
1091:
1092: String returnValue;
1093: try {
1094: returnValue = Messages.getString(schema, l, key);
1095: } catch (IllegalArgumentException ex) {
1096: returnValue = key;
1097: }
1098:
1099: return returnValue;
1100:
1101: }
1102:
1103: /**
1104: * Specify that the DISTINCT keyword for unique rows must be specified
1105: * right after the SELECT keyword
1106: *
1107: * @param flag true if DISTINCT supported right after SELECT, false
1108: * (default) otherwise.
1109: */
1110: public void setSelectDistinct(boolean flag) {
1111: selectDistinct = flag;
1112: }
1113:
1114: /**
1115: * Retrieve all the attributes so you can iterate through them.
1116: *
1117: * @param fieldName the name of the field's attributes to retrieve
1118: * @return Set of all attributes
1119: */
1120: public java.util.Set getAllAttributes(String fieldName) {
1121: /**@todo Implement this com.jcorporate.expresso.core.dataobjects.DataObjectMetaData method*/
1122: throw new java.lang.UnsupportedOperationException(
1123: "Method getTransitionsIterator() not yet implemented.");
1124: }
1125:
1126: /**
1127: * Retrieve whether or not the Join should be distinct or not
1128: *
1129: * @return true if the join should be distinct.
1130: */
1131: public boolean isSelectDistinct() {
1132: return selectDistinct;
1133: }
1134:
1135: /**
1136: * Sets how the various dataobjects are connected, key-wise
1137: *
1138: * @param shortName java.lang.String the local short name
1139: * @param foreignKey java.lang.String the local key
1140: * @param shortName2 java.lang.String the foreign short name
1141: * @param primaryKey java.lang.String the foreign key
1142: * @param joinType the type of Join
1143: * @throws DBException upon error
1144: * <p/>
1145: * Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
1146: * @since $DatabaseSchema $Date: 2004/11/18 02:03:27 $
1147: */
1148: public void setForeignKey(String shortName, String foreignKey,
1149: String shortName2, String primaryKey, int joinType)
1150: throws DBException {
1151: JDBCDataObject foreignDBObj = (JDBCDataObject) myDataObjects
1152: .get(shortName);
1153:
1154: if (foreignDBObj == null) {
1155: throw new DBException("DB Object with short name '"
1156: + shortName + "' is not part of this query");
1157: }
1158:
1159: JDBCDataObject primaryDBObj = (JDBCDataObject) myDataObjects
1160: .get(shortName2);
1161:
1162: if (primaryDBObj == null) {
1163: throw new DBException("DB Object with short name '"
1164: + shortName2 + "' is not part of this query");
1165: }
1166:
1167: Relation r = new JoinedDataObjectMetaData.Relation();
1168: r.setLocalAlias(shortName);
1169: r.setLocalKey(foreignKey);
1170: r.setForeignAlias(shortName2);
1171: r.setForeignKey(primaryKey);
1172: r.setJoinType(joinType);
1173:
1174: this .relations.put(shortName + "|" + shortName2, r);
1175:
1176: if (joinType == JoinedDataObject.UNSPECIFIED_JOIN) {
1177: sqlRelationList.add(foreignDBObj.getJDBCMetaData()
1178: .getTargetSQLTable(foreignDBObj.getDataContext())
1179: + "."
1180: + foreignKey
1181: + " = "
1182: + primaryDBObj.getJDBCMetaData().getTargetSQLTable(
1183: foreignDBObj.getDataContext())
1184: + "."
1185: + primaryKey);
1186: }
1187:
1188: String localField = shortName + "." + foreignKey;
1189: String remoteField = shortName2 + "." + primaryKey;
1190:
1191: this .primaryToForeignKeyMap.put(remoteField, localField);
1192: this .foreignKeyToPrimaryKeyMap.put(localField, remoteField);
1193:
1194: }
1195:
1196: /* setForeignKey(String, String, String, String) */
1197:
1198: /**
1199: * Retrieve the relation bean for between two aliases
1200: *
1201: * @param aliaslocal the local alias
1202: * @param aliasJoined the foreign alias
1203: * @return JoinedDataObjectMetaData.Relation or null if the relation doesn't
1204: * exist.
1205: */
1206: public Relation getRelation(String aliaslocal, String aliasJoined) {
1207: return (Relation) relations.get(aliaslocal + "|" + aliasJoined);
1208: }
1209:
1210: /**
1211: * Retrieve a list of all relations
1212: *
1213: * @return java.util.Map
1214: */
1215: public Map getAllRelations() {
1216: return Collections.unmodifiableMap(relations);
1217: }
1218:
1219: /**
1220: * Retrieve a list of precalculated relations for the where clauses.
1221: *
1222: * @return java.util.List
1223: */
1224: public List getSQLRelationList() {
1225: return this .sqlRelationList;
1226: }
1227:
1228: /**
1229: * Creates a new copy of blank data objects for use in the main objects
1230: *
1231: * @return java.util.HashMap
1232: * @throws DataException upon construction error
1233: */
1234: public synchronized HashMap createNestedDataObjects()
1235: throws DataException {
1236: HashMap returnMap = new HashMap(this .myDataObjects.size());
1237:
1238: for (Iterator i = myDataObjects.keySet().iterator(); i
1239: .hasNext();) {
1240: String key = (String) i.next();
1241: JDBCDataObject oneObj = (JDBCDataObject) myDataObjects
1242: .get(key);
1243:
1244: try {
1245: JDBCDataObject newObj = (JDBCDataObject) oneObj
1246: .getClass().newInstance();
1247: if (newObj instanceof Defineable) {
1248: ((Defineable) newObj)
1249: .setDefinitionName(((Defineable) oneObj)
1250: .getDefinitionName());
1251: }
1252: returnMap.put(key, newObj);
1253: } catch (InstantiationException ex) {
1254: throw new DataException(
1255: "Unable to instantiate new Data Object", ex);
1256: } catch (IllegalAccessException ex) {
1257: throw new DataException("Target Class "
1258: + oneObj.getClass()
1259: + " does not have a public default constructor");
1260: }
1261: }
1262:
1263: return returnMap;
1264: }
1265:
1266: /**
1267: * Retrieve the short name of the primary data object. It is the primary
1268: * alias that we set the keys for to form the join.
1269: *
1270: * @return java.lang.String
1271: * @throws IllegalStateException if there are improperly described relations in
1272: * the metadata
1273: */
1274: public String getPrimaryAlias() {
1275: List l = this .getAliasesInOrder();
1276: if (l.size() == 0) {
1277: throw new IllegalArgumentException(
1278: "No 'primary' alias defined!");
1279: }
1280:
1281: return (String) l.get(0);
1282: }
1283:
1284: /**
1285: * Retrieve the primary data object
1286: *
1287: * @return the primary data object
1288: */
1289: private JDBCDataObject getPrimaryDataObject() {
1290: String shortName = this .getPrimaryAlias();
1291: return (JDBCDataObject) this .myDataObjects.get(shortName);
1292: }
1293:
1294: /**
1295: * Utility method Retrieve the object name and the field name
1296: *
1297: * @param fieldName the [dataobject].field
1298: * @return Array of Strings. String[0] = object alias String[1] = Object's Field Name
1299: */
1300: public final String[] getObjectAndField(String fieldName) {
1301: String returnValue[] = new String[2];
1302:
1303: int dotPos = fieldName.indexOf(".");
1304: if (dotPos <= 0 || dotPos == (fieldName.length() - 1)) {
1305: throw new IllegalArgumentException(
1306: "Field name must be of format [dataobject alias].[fieldname]");
1307: }
1308:
1309: returnValue[0] = fieldName.substring(0, dotPos);
1310: DataObject oneObj = (DataObject) myDataObjects
1311: .get(returnValue[0]);
1312:
1313: if (oneObj == null) {
1314: throw new IllegalArgumentException(
1315: "Unable to locate dataobject: " + returnValue[0]);
1316: }
1317:
1318: returnValue[1] = fieldName.substring(dotPos + 1);
1319: return returnValue;
1320: }
1321:
1322: // getter methods for derived classes to retrieve
1323: protected Set getAllDetails() {
1324: return allDetails;
1325: }
1326:
1327: protected HashMap getForeignKeyToPrimaryKeyMap() {
1328: return foreignKeyToPrimaryKeyMap;
1329: }
1330:
1331: //retrieve the 'mydataobjects' table
1332: protected HashMap getMyDataObjects() {
1333: return myDataObjects;
1334: }
1335:
1336: public Map getPermissions() {
1337: return Collections.unmodifiableMap(permissions);
1338: }
1339:
1340: public void setPermissions(Map newPermissions) {
1341: permissions = new HashMap(newPermissions);
1342: }
1343:
1344: protected HashMap getPrimaryToForeignKeyMap() {
1345: return primaryToForeignKeyMap;
1346: }
1347:
1348: protected HashMap getRelations() {
1349: return relations;
1350: }
1351:
1352: protected List getSqlRelationList() {
1353: return sqlRelationList;
1354: }
1355:
1356: /**
1357: * Bean-like class for keeping track of relations
1358: *
1359: * @author Michael Rimov
1360: */
1361: public class Relation {
1362: private String localAlias;
1363: private String foreignAlias;
1364: private String localField;
1365: private String foreignField;
1366: private int joinType = JoinedDataObject.UNSPECIFIED_JOIN;
1367:
1368: /**
1369: * Sets the local alias value
1370: *
1371: * @param newValue java.lang.String an alias name
1372: */
1373: public void setLocalAlias(String newValue) {
1374: this .localAlias = newValue;
1375: }
1376:
1377: /**
1378: * Sets the foreign alias value
1379: *
1380: * @param newValue java.lang.String an alias name
1381: */
1382: public void setForeignAlias(String newValue) {
1383: this .foreignAlias = newValue;
1384: }
1385:
1386: /**
1387: * Set the local key field name
1388: *
1389: * @param newValue java.lang.String
1390: */
1391: public void setLocalKey(String newValue) {
1392: this .localField = newValue;
1393: }
1394:
1395: /**
1396: * Set the foreign key field
1397: *
1398: * @param newValue the new Key field name
1399: */
1400: public void setForeignKey(String newValue) {
1401: this .foreignField = newValue;
1402: }
1403:
1404: public void setJoinType(int newValue) {
1405: this .joinType = newValue;
1406: }
1407:
1408: /**
1409: * Retrieve the local alias
1410: *
1411: * @return the local alias
1412: */
1413: public String getLocalAlias() {
1414: return localAlias;
1415: }
1416:
1417: /**
1418: * Retrieve the foreign alias
1419: *
1420: * @return java.lang.String
1421: */
1422: public String getForeignAlias() {
1423: return this .foreignAlias;
1424: }
1425:
1426: /**
1427: * Retrieve the local field
1428: *
1429: * @return java.lang.String
1430: */
1431: public String getLocalField() {
1432: return this .localField;
1433: }
1434:
1435: /**
1436: * Retrieve the foreign field
1437: *
1438: * @return java.lang.String
1439: */
1440: public String getForeignField() {
1441: return this .foreignField;
1442: }
1443:
1444: public int getJoinType() {
1445: return joinType;
1446: }
1447:
1448: }
1449:
1450: /**
1451: * Bean-like class for keeping track of required fields
1452: *
1453: * @author Malcolm Wise
1454: */
1455: public class FieldList {
1456: private String fieldExpression;
1457: private String fieldName;
1458: private boolean isExpression;
1459:
1460: public FieldList(String fieldExpression, String fieldName,
1461: boolean isExpression) {
1462: this .fieldExpression = fieldExpression;
1463: this .fieldName = fieldName;
1464: this .isExpression = isExpression;
1465: }
1466:
1467: public String getFieldExpression() {
1468: return fieldExpression;
1469: }
1470:
1471: public String getFieldName() {
1472: return fieldName;
1473: }
1474:
1475: public boolean isExpression() {
1476: return isExpression;
1477: }
1478:
1479: }
1480:
1481: }
|