/*
This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
Software Foundation; either version 3 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along
with this program; if not, see http://www.gnu.org/licenses or write to the Free
Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
package com.servoy.j2db.dataprocessing;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Properties;
import javax.swing.JFormattedTextField.AbstractFormatter;
import org.mozilla.javascript.Scriptable;
import com.servoy.base.util.ITagResolver;
import com.servoy.j2db.persistence.IColumnTypes;
import com.servoy.j2db.scripting.ScriptVariableScope;
import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.FormatParser.ParsedFormat;
import com.servoy.j2db.util.RoundHalfUpDecimalFormat;
import com.servoy.j2db.util.Settings;
/**
* Resolver class for tags in text
* @author rgansevles
*/
public class TagResolver
{
private static class RecordTagResolver implements ITagResolver
{
private final IRecordInternal record;
public RecordTagResolver(IRecordInternal record)
{
this.record = record;
}
public String getStringValue(String dataProviderID)
{
if (record == null) return null;
Object value = record.getValue(dataProviderID);
return formatObject(value, record.getParentFoundSet().getFoundSetManager().getApplication().getLocale(), (value == null) ? null
: record.getParentFoundSet().getFoundSetManager().getApplication().getSettings());
}
}
private static class ScriptableTagResolver implements ITagResolver
{
private final Scriptable scriptobj;
private final Locale locale;
public ScriptableTagResolver(Scriptable obj, Locale locale)
{
this.scriptobj = obj;
this.locale = locale;
}
public String getStringValue(String dataProviderID)
{
if (scriptobj == null) return null;
Object value = ScriptVariableScope.unwrap(scriptobj.get(dataProviderID, scriptobj));
return formatObject(value, locale, (value == null) ? null : Settings.getInstance());
}
}
/**
* Factory method to create a resolver.
*
* @param o
* @return resolver
*/
public static ITagResolver createResolver(IRecordInternal o)
{
return new RecordTagResolver(o);
}
/**
* Factory method to create a resolver.
*
* @param o
* @return resolver
*/
public static ITagResolver createResolver(Scriptable o, Locale locale)
{
return new ScriptableTagResolver(o, locale);
}
public static String formatObject(Object value, Locale locale, ParsedFormat format, AbstractFormatter maskFormatter)
{
if (format == null || value == null || value == Scriptable.NOT_FOUND)
{
return null;
}
if (value instanceof String)
{
if (format.isAllLowerCase())
{
return value.toString().toLowerCase();
}
else if (format.isAllUpperCase())
{
return value.toString().toUpperCase();
}
else if (format.getDisplayFormat() != null)
{
try
{
return maskFormatter.valueToString(value);
}
catch (ParseException ex)
{
Debug.error(ex);
}
}
}
if (format.getDisplayFormat() == null)
{
return value.toString();
}
if (value instanceof Date)
{
return new SimpleDateFormat(format.getDisplayFormat(), locale).format(value);
}
if (value instanceof Number)
{
return new DecimalFormat(format.getDisplayFormat(), RoundHalfUpDecimalFormat.getDecimalFormatSymbols(locale)).format(value);
}
return value.toString();
}
public static String formatObject(Object value, Locale locale, Properties settings)
{
return formatObject(value, null, locale, settings);
}
public static String formatObject(Object value, String format, Locale locale, Properties settings)
{
if (value == null || value == Scriptable.NOT_FOUND)
{
return null;
}
String formatString = (format != null) ? format : getFormatString(value.getClass(), settings);
if (formatString == null)
{
return value.toString();
}
if (value instanceof Date)
{
return new SimpleDateFormat(formatString).format(value);
}
if (value instanceof Number /* Integer extends Number */)
{
return new DecimalFormat(formatString, RoundHalfUpDecimalFormat.getDecimalFormatSymbols(locale)).format(value);
}
return value.toString();
}
/**
* Get the format string for an object based on the settings.
*
* @param clazz
* @param settings
* @return
*/
public static String getFormatString(Class clazz, Properties settings)
{
String formatString = null;
if (Date.class.isAssignableFrom(clazz))
{
String pattern = settings.getProperty("locale.dateformat"); //$NON-NLS-1$
// Note: new SimpleDateFormat() uses Locale.getDefault()
formatString = (pattern == null || pattern.trim().length() == 0) ? new SimpleDateFormat().toPattern() : pattern;
}
// Note that Integer extends Number, so first check for Integer, then for Number
else if (Integer.class.isAssignableFrom(clazz) || Long.class.isAssignableFrom(clazz))
{
String pattern = settings.getProperty("locale.integerformat"); //$NON-NLS-1$
// Note: new DecimalFormat() uses Locale.getDefault()
formatString = (pattern == null || pattern.trim().length() == 0) ? new DecimalFormat().toPattern() : pattern;
}
else if (Number.class.isAssignableFrom(clazz))
{
String pattern = settings.getProperty("locale.numberformat"); //$NON-NLS-1$
// Note: new DecimalFormat() uses Locale.getDefault()
formatString = (pattern == null || pattern.trim().length() == 0) ? new DecimalFormat().toPattern() : pattern;
}
return formatString;
}
public static String getDefaultFormatForType(Properties settings, int type)
{
switch (type)
{
case IColumnTypes.DATETIME :
return getFormatString(Date.class, settings);
case IColumnTypes.TEXT :
return getFormatString(String.class, settings);
case IColumnTypes.NUMBER :
return getFormatString(Number.class, settings);
case IColumnTypes.INTEGER :
return getFormatString(Integer.class, settings);
case IColumnTypes.MEDIA :
return getFormatString(byte[].class, settings);
default :
return null;
}
}
}