001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049:
050: package org.jaffa.rules.fieldvalidators;
051:
052: import org.apache.log4j.Logger;
053: import org.jaffa.datatypes.ValidationException;
054: import org.jaffa.exceptions.FrameworkException;
055: import org.jaffa.persistence.UOW;
056: import org.jaffa.persistence.Criteria;
057: import java.util.*;
058: import org.jaffa.datatypes.exceptions.InvalidGenericForeignKeyException;
059: import org.jaffa.util.BeanHelper;
060:
061: /**
062: * This validates a field against a set of valid values for that field, as listed in a database table
063: * For eg. Lets assume that there is database table 'VALID_FIELD_VALUE' which holds a set of valid values for certain fields in the system.
064: * The structure of this table 'VALID_FIELD_VALUE' in oracle can be like -
065: * TABLE_NAME NOT NULL VARCHAR2(20)
066: * FIELD_NAME NOT NULL VARCHAR2(30)
067: * LEGAL_VALUE NOT NULL VARCHAR2(20)
068: *
069: * This table can hold values like -
070: * TABLE_NAME FIELD_NAME LEGAL_VALUE
071: * ========== ========== ===========
072: * USER DEPARTMENT ACCOUNTS
073: * USER DEPARTMENT ENGINEERING
074: * USER DEPARTMENT PERSONNEL
075: * ITEM TYPE CONSUMABLE
076: * ITEM TYPE NON-CONSUMABLE
077: *
078: * This way, the table can hold valid values for the different fields
079: *
080: * The generic implementation provides the ValidFieldValue domain class and its mapping file. Tweak its mapping file to map it to the correct table and fields.
081: * Or specify your own domain class.
082: * The GenericForeignKeyFieldValidator definition in validators.xml requires the appropriate values to be passed in parameters.
083: */
084: public class GenericForeignKeyFieldValidator extends
085: AbstractFieldValidator {
086:
087: private static final Logger log = Logger
088: .getLogger(GenericForeignKeyFieldValidator.class);
089: private String m_domainClassName;
090: private String m_fieldNameForTable;
091: private String m_fieldNameForField;
092: private String m_fieldNameForValue;
093: private String m_tableName;
094: private String m_fieldName;
095:
096: /** Getter for property domainClassName.
097: * @return Value of property domainClassName.
098: */
099: public String getDomainClassName() {
100: return m_domainClassName;
101: }
102:
103: /** Setter for property domainClassName.
104: * @param domainClassName New value of property domainClassName.
105: */
106: public void setDomainClassName(String domainClassName) {
107: m_domainClassName = domainClassName;
108: }
109:
110: /** Getter for property fieldNameForTable.
111: * @return Value of property fieldNameForTable.
112: */
113: public String getFieldNameForTable() {
114: return m_fieldNameForTable;
115: }
116:
117: /** Setter for property fieldNameForTable.
118: * @param fieldNameForTable New value of property fieldNameForTable.
119: */
120: public void setFieldNameForTable(String fieldNameForTable) {
121: m_fieldNameForTable = fieldNameForTable;
122: }
123:
124: /** Getter for property fieldNameForField.
125: * @return Value of property fieldNameForField.
126: */
127: public String getFieldNameForField() {
128: return m_fieldNameForField;
129: }
130:
131: /** Setter for property fieldNameForField.
132: * @param fieldNameForField New value of property fieldNameForField.
133: */
134: public void setFieldNameForField(String fieldNameForField) {
135: m_fieldNameForField = fieldNameForField;
136: }
137:
138: /** Getter for property fieldNameForValue.
139: * @return Value of property fieldNameForValue.
140: */
141: public String getFieldNameForValue() {
142: return m_fieldNameForValue;
143: }
144:
145: /** Setter for property fieldNameForValue.
146: * @param fieldNameForValue New value of property fieldNameForValue.
147: */
148: public void setFieldNameForValue(String fieldNameForValue) {
149: m_fieldNameForValue = fieldNameForValue;
150: }
151:
152: /** Getter for property tableName.
153: * @return Value of property tableName.
154: */
155: public String getTableName() {
156: return m_tableName;
157: }
158:
159: /** Setter for property tableName.
160: * @param tableName New value of property tableName.
161: */
162: public void setTableName(String tableName) {
163: m_tableName = tableName;
164: }
165:
166: /** Getter for property fieldName.
167: * @return Value of property fieldName.
168: */
169: public String getFieldName() {
170: return m_fieldName;
171: }
172:
173: /** Setter for property fieldName.
174: * @param fieldName New value of property fieldName.
175: */
176: public void setFieldName(String fieldName) {
177: m_fieldName = fieldName;
178: }
179:
180: /** The RulesEngine will invoke this method to perform the field validation.
181: * @throws ValidationException if any validation rule fails.
182: * @throws FrameworkException if any framework error occurs.
183: */
184: public void validate() throws ValidationException,
185: FrameworkException {
186: if (getValue() != null) {
187: UOW uow = getUow();
188: boolean localUow = (uow == null);
189: try {
190: if (localUow)
191: uow = new UOW();
192:
193: Criteria c = new Criteria();
194: c.setTable(getDomainClassName());
195: c.addCriteria(getFieldNameForTable(), getTableName());
196: c.addCriteria(getFieldNameForField(), getFieldName());
197: c.addCriteria(getFieldNameForValue(), getValue()
198: .toString());
199: Collection col = uow.query(c);
200: if (col.size() == 0) {
201: // Invalid value. Display the list of valid values in the error message
202: StringBuffer validValues = new StringBuffer();
203: c = new Criteria();
204: c.setTable(getDomainClassName());
205: c.addCriteria(getFieldNameForTable(),
206: getTableName());
207: c.addCriteria(getFieldNameForField(),
208: getFieldName());
209: c.addOrderBy(getFieldNameForValue(),
210: Criteria.ORDER_BY_ASC);
211: for (Iterator i = uow.query(c).iterator(); i
212: .hasNext();) {
213: try {
214: Object value = BeanHelper.getField(
215: i.next(), getFieldNameForValue());
216: if (validValues.length() > 0)
217: validValues.append(',');
218: validValues.append(value);
219: } catch (Exception e) {
220: // do nothing
221: }
222: }
223: String str = "Generic ForeignKey validation failed for the value '"
224: + getValue()
225: + "' against the table/field - "
226: + getTableName()
227: + '/'
228: + getFieldName()
229: + ". Valid values are "
230: + validValues.toString();
231: log.error(str);
232: throw new InvalidGenericForeignKeyException(
233: getLabelToken(), new Object[] {
234: getTableName(), getFieldName(),
235: validValues.toString() });
236: }
237: } finally {
238: if (localUow && uow != null)
239: uow.rollback();
240: }
241: }
242: }
243:
244: }
|