All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dooapp.gaedo.blueprints.transformers.DateLiteralTransformer Maven / Gradle / Ivy

package com.dooapp.gaedo.blueprints.transformers;

import java.text.ParseException;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.WeakHashMap;

import com.dooapp.gaedo.blueprints.GraphDatabaseDriver;
import com.dooapp.gaedo.blueprints.ObjectCache;
import com.dooapp.gaedo.blueprints.Properties;
import com.dooapp.gaedo.utils.date.DateFormatThreadedLoader;
import com.tinkerpop.blueprints.Vertex;

/**
 * As SimpleDateFormat is not thread-safe and construction heavy, see here
 * (http:
 * //www.jmdoudoux.fr/java/dej/chap-utilisation_dates.htm#utilisation_dates-3)
 * for the why of this pattern
 *
 * Furthermore, used pattern is ISO standard (see there : http://www.fileformat.info/tip/java/simpledateformat.htm)
 *
 * @author ndx
 *
 */
public class DateLiteralTransformer extends AbstractSimpleLiteralTransformer implements LiteralTransformer {

	/**
	 * Map linking date format specification (a uri like xsd:date or http://www.w3.org/2001/XMLSchema#date) to the format string used to parse it.
	 */
	private static final Map FORMATS = new LinkedHashMap();

	static {
		FORMATS.put("xsd:date", "yyyy-MM-dd'T'HH:mm:ssz");
		FORMATS.put("http://www.w3.org/2001/XMLSchema#date", "yyy-MM-dd");
	}


	/**
	 * A map allowing lazy loading of those inconvenient threaded loaders.
	 */
	private static final Map loaders = new TreeMap();

	/**
	 * Cache linking dates to their associated format definition.
	 * As the dates are in memory, and the formats are constants, this weak hash map should have very low memory impact.
	 */
	private static Map dateCache = new WeakHashMap();

	public static DateFormatThreadedLoader getLoader(String format) {
		if(!loaders.containsKey(format))
			loaders.put(format, new DateFormatThreadedLoader(format));
		return loaders.get(format);
	}

	public DateLiteralTransformer() {
		super(Date.class);
	}

	@Override
	public String valueToString(Date value) {
		// fallback value
		String format = getTypeOf(value);
		return getLoader(FORMATS.get(format)).format(value);
	}

	@Override
	public Date loadObjectFromVertex(GraphDatabaseDriver driver, Class valueClass, Vertex key, ObjectCache objectCache) {
		String property = driver.getValue(key).toString();
		String type = key.getProperty(Properties.type.name()).toString();
		try {
			Date returned = getLoader(FORMATS.get(type)).parse(property);
			dateCache.put(returned, type);
			return returned;
		} catch (ParseException e) {
			throw new BadLiteralException("\"" + property + "\" can't be efficiently parsed from a \""+type+"\" supposed to contain a date");
		}
	}

	/**
	 * Type of date depends upon the date
	 * @param value
	 * @return
	 * @see com.dooapp.gaedo.blueprints.transformers.AbstractLiteralTransformer#getTypeOf(java.lang.Object)
	 */
	@Override
	public String getTypeOf(Object value) {
		String format = "xsd:date";
		if(dateCache.containsKey(value)) {
			format = dateCache.get(value);
		}
		dateCache.put((Date) value, format);
		return format;
	}

	/**
	 * Load value using the first format that may work. This is unfortunatly not optimal.
	 * @param valueClass
	 * @param valueString
	 * @return
	 * @see com.dooapp.gaedo.blueprints.transformers.AbstractLiteralTransformer#loadValueFromString(java.lang.Class, java.lang.String)
	 */
	@Override
	protected Date loadValueFromString(Class valueClass, String valueString) {
		for(Map.Entry format : FORMATS.entrySet()) {
			try {
				DateFormatThreadedLoader parser = getLoader(format.getValue());
				Date parsed = parser.parse(valueString);
				dateCache.put(parsed, format.getKey());
				return parsed;
			} catch(ParseException e) {
				// unable to parse ? No problem, we'll just use next parser
			}
		}
		// if value can't be loaded, well, delegate to superclass (it will fail for sure)
		return super.loadValueFromString(valueClass, valueString);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy