IssueField.java
/*
* This software was designed and created by Jason Carroll.
* Copyright (c) 2002, 2003, 2004 Jason Carroll.
* The author can be reached at jcarroll@cowsultants.com
* ITracker website: http://www.cowsultants.com
* ITracker forums: http://www.cowsultants.com/phpBB/index.php
*
* This program is free software; you can redistribute it and/or modify
* it only under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
package org.itracker.model;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.log4j.Logger;
import org.itracker.IssueException;
import org.itracker.core.resources.ITrackerResources;
import org.itracker.model.CustomField.Type;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
/**
* A CustomField with its value for an Issue.
* <p/>
* <p>
* An IssueField can only belong to 1 Issue (composition).
* </p>
*
* @author ready
* @see CustomField
*/
public class IssueField extends AbstractEntity {
/**
*
*/
private static final long serialVersionUID = 1L;
private static transient final Logger log = Logger
.getLogger(IssueField.class);
private Issue issue;
private CustomField customField;
private String stringValue;
private Integer intValue;
private Date dateValue;
/**
* Default constructor (required by Hibernate).
* <p/>
* <p>
* PENDING: should be <code>private</code> so that it can only be used by
* Hibernate, to ensure that the fields which form an instance's identity
* are always initialized/never <tt>null</tt>.
* </p>
*/
public IssueField() {
}
public IssueField(Issue issue, CustomField field) {
setIssue(issue);
setCustomField(field);
}
public Issue getIssue() {
return issue;
}
public void setIssue(Issue issue) {
if (issue == null) {
throw new IllegalArgumentException("null issue");
}
this.issue = issue;
}
public CustomField getCustomField() {
return customField;
}
public void setCustomField(CustomField customField) {
if (customField == null) {
throw new IllegalArgumentException("null customField");
}
this.customField = customField;
}
public String getStringValue() {
if (null != this.getCustomField() && Type.DATE == this.getCustomField().getFieldType()) {
this.stringValue = "";
if (null != this.dateValue) {
String stringValue = formatDate(ITrackerResources.getBundle(ITrackerResources.BASE_LOCALE));
this.stringValue = stringValue;
}
}
return stringValue;
}
public void setStringValue(String stringValue) {
this.stringValue = stringValue;
}
public Integer getIntValue() {
return intValue;
}
public void setIntValue(Integer intValue) {
this.intValue = intValue;
}
public Date getDateValue() {
if (null == dateValue)
return null;
return new Date(dateValue.getTime());
}
public void setDateValue(Date dateValue) {
if (null == dateValue) {
this.dateValue = null;
} else {
this.dateValue = new Date(dateValue.getTime());
this.stringValue = formatDate(ITrackerResources.getBundle());
}
}
/**
* Gets the custom field value as a String.
*
* @param locale the locale used for any string formatting
* @return the current value of this field
*/
public String getValue(Locale locale) {
// only date fields are currently localizable
if (getCustomField().getFieldType() == Type.DATE) {
return getValue(ITrackerResources.getBundle(locale));
} else if (getCustomField().getFieldType() == Type.INTEGER) {
return String.valueOf(getIntValue());
}
return getStringValue();
}
/**
* Gets the custom field value as a String.
*
* @param bundle a resource bundle to use for any string formatting
* @param locale a locale to use for any string formatting
* @return the current value of this field
* @deprecated use getValue(ResourceBundle bundle) instead, locale is taken
* from bundle
*/
public String getValue(ResourceBundle bundle, Locale locale) {
if (log.isDebugEnabled()) {
log.debug("getValue: called with bundle: " + bundle + ", locale: "
+ locale);
}
return getValue(bundle);
}
/**
* Gets the custom field value as a String.
*
* @param bundle a resource bundle to use for any string formatting
* @return the current value of this field
* @deprecated this can not be in the entity, replace by Utility or service.
*/
public String getValue(ResourceBundle bundle) {
// skip this code, it's not approved
Locale locale = bundle.getLocale();
if (log.isDebugEnabled()) {
log.debug("getValue: called with bundle: " + bundle + ", locale: "
+ locale);
}
switch (customField.getFieldType()) {
case INTEGER:
if (log.isDebugEnabled()) {
log
.debug("getValue: type was INTEGER, value: "
+ this.intValue);
}
return String.valueOf(this.intValue);
case DATE:
if (log.isDebugEnabled()) {
log.debug("getValue: type was DATE, value: " + this.dateValue);
}
if (!customField.isRequired() && this.dateValue == null) {
if (log.isDebugEnabled()) {
log.debug("getValue: value was null and not required");
}
return null;
}
if (this.dateValue == null) {
this.dateValue = new Date();
}
return formatDate(bundle);
default:
return this.stringValue;
}
}
private String formatDate(ResourceBundle bundle) {
assert (dateValue != null) : "dateValue failed";
try {
SimpleDateFormat sdf =
new SimpleDateFormat(bundle
.getString("itracker.dateformat."
+ customField.getDateFormat()), bundle.getLocale());
if (log.isDebugEnabled()) {
log.debug("getValue: dateFormat from itracker configuration "
+ sdf.toPattern());
}
// sdf = new SimpleDateFormat(dateFormat, locale);
String formattedDate = sdf.format(this.dateValue);
if (log.isDebugEnabled()) {
log.debug("getValue: formated date " + this.dateValue
+ " to " + formattedDate);
}
return formattedDate;
} catch (NullPointerException ne) {
log.debug("getValue: ", ne);
if (dateValue == null) {
log.warn("getValue: failed to format date, null for "
+ customField);
}
return "";
}
}
/**
* Sets the custom field value.
* <p/>
* <p>
* Takes a string and then converts the value to the appropriate type based
* on the defined field type.
* </p>
* <p/>
* TODO : throw IllegalArgumentException instead of IssueException ?
*
* @param value the value to set this field to as a string
* @param locale the locale used for any string formatting
* @param bundle the ResourceBundle used for any string formatting
* @throws org.itracker.IssueException represents an error formatting or parsing the value
* @deprecated locale is redundant set, in bundle and as separate parameter.
* use {@link IssueField#setValue(String, ResourceBundle)}
* instead
*/
public void setValue(String value, Locale locale, ResourceBundle bundle)
throws IssueException {
this.stringValue = null;
this.intValue = 0;
this.dateValue = null;
if (value != null && value.trim().length() > 0) {
switch (customField.getFieldType()) {
case INTEGER:
setStringValue(value);
try {
setIntValue(Integer.parseInt(value));
} catch (NumberFormatException nfe) {
throw new IssueException("Invalid integer.",
IssueException.TYPE_CF_PARSE_NUM);
}
break;
case DATE:
setStringValue(value);
try {
if (null == locale) {
locale = bundle.getLocale();
}
SimpleDateFormat sdf = // CustomField.DEFAULT_DATE_FORMAT;
new SimpleDateFormat(bundle
.getString("itracker.dateformat."
+ customField.getDateFormat()), locale);
Date dateValue = sdf.parse(value);
if (dateValue != null) {
setDateValue(dateValue);
} else {
log.error("setValue: caught exception for date "
+ value);
throw new IssueException("Invalid date.",
IssueException.TYPE_CF_PARSE_DATE);
}
} catch (Exception ex) {
log.error("setValue: caught exception for date " + value,
ex);
throw new IssueException("Invalid date format.",
IssueException.TYPE_CF_PARSE_DATE);
}
break;
default:
setStringValue(value);
}
} else {
// reset value
setStringValue("");
setDateValue(null);
setIntValue(0);
}
}
/**
* Sets the custom field value.
* <p/>
* <p>
* Takes a string and then converts the value to the appropriate type based
* on the defined field type.
* </p>
* <p/>
* TODO : throw IllegalArgumentException instead of IssueException ?
*
* @param value the value to set this field to as a string
* @param bundle the ResourceBundle used for any string formatting
* @throws IssueException represents an error formatting or parsing the value
*/
public void setValue(String value, ResourceBundle bundle)
throws IssueException {
setValue(value, bundle.getLocale(), bundle);
}
@Override
public String toString() {
return new ToStringBuilder(this).append("id", getId()).append("issue",
getIssue()).append("customField", getCustomField()).toString();
}
}