org.wicketstuff.gchart.DataCell Maven / Gradle / Ivy
Show all versions of wicket-gchart Show documentation
/*
* Licensed 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.wicketstuff.gchart;
import java.text.DateFormat;
import java.text.Format;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.wicket.ajax.json.JSONFunction;
import org.apache.wicket.util.io.IClusterable;
import com.github.openjson.JSONObject;
/**
* Cell object for data values with more features.
*
* @author Dieter Tremel
*/
public class DataCell implements IClusterable, Jsonable {
private static final long serialVersionUID = 1L;
private Object value;
private Format format;
private String formatted;
private Map properties = null;
public DataCell(Object value) {
this.value = value;
this.formatted = null;
}
public DataCell(Object value, Format format) {
this.value = value;
this.formatted = null;
this.format = format;
}
public DataCell(Object value, String formatted) {
this.value = value;
this.formatted = formatted;
}
public DataCell(Object value, String formatted, Map properties) {
this.value = value;
this.formatted = formatted;
this.properties = properties;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public Format getFormat() {
return format;
}
/**
* Format used for calculating the value to a String used for rendering of
* {@code f} in JavaScript.
*
* @param format The format to applied if the formatted value of the
* instance is null. For Number this can be a DecimalFormat, for Dates for
* instance a SimpleDateFormat.
*/
public void setFormat(Format format) {
this.format = format;
}
/**
* Return the formatted value. If this is null, null is also returned and
* there should be no rendering of {@code f} in JavaScript. In this case
* format conversion is done by Google chart lib. See therefor {@link Chart#getLocale()
* }.
*
* If {@link #getFormat() } is not null and the formatted field is null, the
* format is applied to the value. If formatted field is not null this is
* returned without change, so a single DataCell can override the Formatter.
*
* @return Field formatted if field format is null. If field format is not
* null and field formatted is null, the format is applied to the value and
* the result is returned.
*/
public String getFormatted() {
if (formatted == null && format != null) {
// TODO Check if Format crashes if value is null. Should we return null in this case?
if (format instanceof DateFormat && value instanceof Calendar) {
return format.format(((Calendar) value).getTime());
} else {
return format.format(value);
}
} else {
return formatted;
}
}
public void setFormatted(String formatted) {
this.formatted = formatted;
}
public Map getProperties() {
if (properties == null) {
properties = new HashMap<>(8);
}
return properties;
}
@Override
public JSONObject toJSON() {
JSONObject cell = new JSONObject();
cell.put("v", getJsValue(value));
final String formattedVal = getFormatted();
if (formattedVal != null) {
cell.put("f", formattedVal);
}
if (properties != null && !properties.isEmpty()) {
cell.put("p", new JSONObject(properties));
}
return cell;
}
/**
* Create a representation of a Java object suitable for a put operation to
* a {@link JSONObject}. For simple types like String and Number the object
* is returned unmodified.
*
* Booleans are rendered as String {@code "true"} or {@code "false"}
*
* Dates or Calendars are rendered as JsonFunction {@code "Date()"} by use
* of {@link #createJsDate(java.util.Calendar) }.
*
* {@link TimeOfDay} are rendered as JSONArray by use of {@link TimeOfDay#getTimeOfDayArray()
* }.
*
* @param val The object to convert to.
* @return JSON compatible wrapping of the value or the value itself for
* simple types.
*/
public static Object getJsValue(Object val) {
// if (val == null) {
// return JSONObject.NULL;
// }
// use real null value instead
if (val instanceof Boolean) {
return ((Boolean) val).toString();
}
if (val instanceof Date) {
return createJsDate((Date) val);
}
if (val instanceof Calendar) {
return createJsDate((Calendar) val);
}
if (val instanceof TimeOfDay) {
return ((TimeOfDay) val).getTimeOfDayArray();
}
// if(val instanceof String || val instanceof Number)
return val;
}
/**
* Convert a Calendar object to a JavaScript {@code Date()} call that
* generates the same value. Return as a human readable JsonFunction
* ({@code new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]])})
* for rendering in JSONObjects.
*
* @param cal Calender value to render.
* @return JavaScript Date function for the value.
*/
public static JSONFunction createExplicitJsDate(Calendar cal) {
StringBuilder sb = new StringBuilder("new Date(");
sb.append(cal.get(Calendar.YEAR));
sb.append(", ").append(cal.get(Calendar.MONTH));
sb.append(", ").append(cal.get(Calendar.DAY_OF_MONTH));
sb.append(", ").append(cal.get(Calendar.HOUR_OF_DAY));
sb.append(", ").append(cal.get(Calendar.MINUTE));
if ((cal.isSet(Calendar.SECOND) && cal.get(Calendar.SECOND) != 0)
|| (cal.isSet(Calendar.MILLISECOND) && cal.get(Calendar.MILLISECOND) != 0)) {
sb.append(", ").append(cal.get(Calendar.SECOND));
}
if (cal.isSet(Calendar.MILLISECOND) && cal.get(Calendar.MILLISECOND) != 0) {
sb.append(", ").append(cal.get(Calendar.MILLISECOND));
}
sb.append(")");
return new JSONFunction(sb.toString());
}
/**
* Convert a Calendar object to a JavaScript {@code Date()} call that
* generates the same value. Return as a
* JsonFunction({@code new Date(value);}) (milliseconds since epoch) for
* rendering in JSONObjects .
*
* @param cal Calender value to render.
* @return JavaScript Date function for the value.
*/
public static JSONFunction createJsDate(Calendar cal) {
StringBuilder sb = new StringBuilder("new Date(");
sb.append(cal.getTimeInMillis());
sb.append(")");
return new JSONFunction(sb.toString());
}
/**
* Convert a Date object to a JavaScript {@code Date()} call that generates
* the same value. Return as a
* JsonFunction({@code new Date(value);})(milliseconds since epoch) for
* rendering in JSONObjects.
*
* @param date Date value to render.
* @return JavaScript Date function for the value.
*/
public static JSONFunction createJsDate(Date date) {
StringBuilder sb = new StringBuilder("new Date(");
sb.append(date.getTime());
sb.append(")");
return new JSONFunction(sb.toString());
}
}