blob: 75dfe802b24bbfd07f36cf8038253afae4325f90 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.empire.struts2.actionsupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import org.apache.empire.commons.ErrorInfo;
import org.apache.empire.commons.Errors;
import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.data.Column;
import org.apache.empire.data.DataType;
import org.apache.empire.data.Record;
import org.apache.empire.db.DBDatabase;
import org.apache.empire.struts2.jsp.controls.InputControl;
import org.apache.empire.struts2.jsp.controls.InputControlManager;
import org.apache.empire.struts2.web.WebErrors;
public abstract class RecordFormActionSupport extends FormActionSupport
{
protected SessionPersistence persistence; // Session persistence
protected RecordFormActionSupport(ActionBase action, SessionPersistence persistence)
{
this(action, persistence, action.getItemPropertyName());
}
protected RecordFormActionSupport(ActionBase action, SessionPersistence persistence, String propertyName)
{
super(action, propertyName);
// Set Persistence
this.persistence = persistence;
}
public SessionPersistence getPersistence()
{
return persistence;
}
public abstract Record getRecord();
public String getRecordKeyString()
{
Record record = getRecord();
if (record==null || record.isValid()==false)
{ // Check whether we can get the record key from the request or the session
String property = getRecordPropertyName();
String key = getActionParam(property, persistence==SessionPersistence.Key);
if (key!=null || (persistence!=SessionPersistence.Data))
return key; // Return key or null
// Get Record from the session
record = getRecordFromSession();
if (record==null)
return null; // No Record Provided
// We have a record
// setRecord(record);
}
return action.getRecordKeyString(record);
}
public boolean isNewRecord()
{
Record record = getRecord();
if (record==null || record.isValid()==false)
{ // Check whether we can get the record key from the request or the session
String property = getRecordPropertyName();
String key = getActionParam(property, persistence==SessionPersistence.Key);
if (key!=null)
return action.getRecordNewFlagFromString(key); // Return key or null
if (persistence!=SessionPersistence.Data)
return false; // Unknown
// Get Record from the session
record = getRecordFromSession();
if (record==null)
return false; // No Record Provided
// We have a record
// setRecord(record);
}
return record.isNew();
}
/**
* returns the name of a field as used in the form
* @param column
* @return the form name of the record field
*/
public String getRequestFieldName(Column column)
{
String name = column.getName();
if (propertyName!=null && propertyName.length()>0)
return propertyName + "." + name;
return name;
}
// ------- persistence -------
protected Record getRecordFromSession()
{
// Check if session persistence is enabled
if (persistence!=SessionPersistence.Data)
return null;
// GetRecord
Object rec = action.getActionObject(getRecordPropertyName() + ".data");
if (rec==null || !(rec instanceof Record))
{ // Record has not been stored on session
return null;
}
// Done
return (Record)rec;
}
protected void persistOnSession()
{
// Clear Item or data
if (persistence==SessionPersistence.Key)
{
String key = action.getRecordKeyString(getRecord());
action.putActionObject(getRecordPropertyName(), key);
}
else if (persistence==SessionPersistence.Data)
{
action.putActionObject(getRecordPropertyName() + ".data", getRecord());
}
}
protected void removeFromSession()
{
// Clear Item or data
if (persistence==SessionPersistence.Key)
{
action.removeActionObject(getRecordPropertyName());
}
else if (persistence==SessionPersistence.Data)
{
action.removeActionObject(getRecordPropertyName() + ".data");
}
}
// --------------------------- public --------------------------------
/**
* Checks wether or not the record key is supplied
* @param acceptSessionKey true if a key supplied on the session is acceptable or false otherwise
* @return true if the record has a bean associated with it or false otherwiese
*/
public boolean hasActionKey(boolean acceptSessionKey)
{
String property = getRecordPropertyName();
String param = getActionParam(property, (acceptSessionKey && persistence==SessionPersistence.Key));
return (param!=null);
}
/**
* Returns the record key.
* The key may be supplied with the request or with the session.
* @return the record key
*/
public Object[] getActionParamKey()
{
// Get Record Key
String property = getRecordPropertyName();
String param = getActionParam(property, (persistence==SessionPersistence.Key));
return action.getRecordKeyFromString(param);
}
/**
* Returns a flag whether or not the current record is a new record.
* @return true if the record is a new unsaved record.
*/
public boolean getActionParamNewFlag()
{
// Get Record Key
String property = getRecordPropertyName();
return action.getRecordNewFlagFromString( getActionParam(property, false));
}
/**
* loads the data from the form into the current record object
* @return true if all fields supplied with the request have been successfully set on the record
*/
@Override
public boolean loadFormData()
{
Record record = getRecord();
if (record.isValid()==false)
return error(Errors.ObjectNotValid, "record");
// Load Data
clearError();
return setUpdateFields(record);
}
// --------------------------- protected --------------------------------
/**
* overridable: sets the value of single field
*/
protected boolean setRecordFieldValue(int i, Object value, boolean verify)
{
// Check Empty
if (ObjectUtils.isEmpty(value))
value = null;
// Set Value
return getRecord().setValue(i, value);
}
/**
* adds all fields found in the HTTP-JSPRequest for this table to the record
*
* @param rec
* the Record object, contains all fields and the field
* properties
* @param request
* request providing access to the HTTP-JSPRequest parameters
* @return true if all values have been set successfully or otherwise false
*/
protected boolean setUpdateFields(Record record)
{ // Set all field Values
boolean valid = true;
Locale locale = action.getLocale();
String sysdate = DBDatabase.SYSDATE.toString();
Column[] keyColumns = record.getKeyColumns();
// Pull all field values
int fieldCount = record.getFieldCount();
for (int i = 0; i < fieldCount; i++)
{
Column col = record.getColumn(i);
// Check wether it is a key column
if (ObjectUtils.contains(keyColumns, col))
continue;
// Get the value from the input control
Object value = null;
String field = getRequestFieldName(col);
InputControl control = null;
if (record.isFieldReadOnly(col)==false)
control = InputControlManager.getControl(col.getControlType());
// Get Value from Control first
if (control!=null && (value=control.getFieldValue(field, action, locale, col))!=null)
{ // Check for Error
if (value instanceof InputControl.FieldValueError)
{
InputControl.FieldValueError fieldError = (InputControl.FieldValueError)value;
// Error
String errorValue = fieldError.getValue();
addFieldError(field, col, fieldError, errorValue);
setRecordFieldValue(i, errorValue, false);
valid = false;
continue;
}
// Check Value
if (value.equals(InputControl.NULL_VALUE) && col.isRequired())
{ // Oops, columns is required
InputControl.FieldValueError fieldError = new InputControl.FieldValueError(WebErrors.InputValueRequired, null, "", control.getClass());
addFieldError(field, col, fieldError, value);
valid = false;
continue;
}
// Set Value
if (log.isInfoEnabled())
log.info("SetUpdateFields: setting field '" + col.getName() + "' to " + String.valueOf(value));
// Feldwert setzen
if (!setRecordFieldValue(i, value, true))
{ // Force to set field value
if (record instanceof ErrorInfo)
addFieldError(field, col, (ErrorInfo)record, value);
else
addFieldError(field, col, new ActionError(WebErrors.InputInvalidValue), value);
// set Value
setRecordFieldValue(i, value, false);
valid = false;
}
}
else if ((value=action.getRequestParam(field + "!"))!=null)
{ // hidden value
if (col.getDataType()==DataType.DATE || col.getDataType()==DataType.DATETIME)
{ // Special for Dates and timestamps
if (value.equals(sysdate)==false)
{ // Parse Date Time
String format = (col.getDataType()==DataType.DATE) ? "yyyy-MM-dd" : "yyyy-MM-dd HH:mm:ss.S";
SimpleDateFormat sdf = new SimpleDateFormat(format);
try {
value = sdf.parseObject(value.toString());
} catch(ParseException e) {
log.error("Failed to parse date for record", e);
continue;
}
}
}
// Set Value
if (log.isInfoEnabled())
log.info("SetUpdateFields: directly setting field '" + col.getName() + "' to " + String.valueOf(value));
// Has Value changed?
if (ObjectUtils.compareEqual(record.getValue(i), value)==false)
{ // Modify Value
setRecordFieldValue(i, value, false);
}
}
else
{ // value not supplied
continue;
}
}
// Result
if (valid == false)
{ // Fehler
if (log.isInfoEnabled())
log.info("SetUpdateFields: Failed to modify record! At least one field error!");
return false;
}
return success();
}
/**
* this method compares two primary key objects
*
* @param keyColumns
* an array of the primary key columns
* @param currentKey
* the current key object
* @param updateKey
* the comparative value
*/
protected final boolean compareKey(Object[] currentKey, Object[] updateKey)
{ // Compare Keys
if (currentKey==null || currentKey.length!=updateKey.length)
return false;
// Compare Key Values
for (int i = 0; i < currentKey.length; i++)
{ // Check String Values
if (!ObjectUtils.compareEqual(currentKey[i], updateKey[i]))
return false;
}
return true;
}
}