Issue #2081 Created custom dataURI field converter interface for use with DataTime so toString can be left unchanged (with spaces) and dataTimes in the dataURI will also be left unchanged (with underscores). Refactored DataURIUtil to support these new field converters.

Change-Id: I0a3983b04a475f6fcf5f70ee89cecf6dd2e67676

Former-commit-id: 1bc2e9aa2b [formerly 1bc2e9aa2b [formerly 86788ab1704c381fc2d26b1891e37aed7367fd3d]]
Former-commit-id: 782ec43213
Former-commit-id: d1e5c9d9e2
This commit is contained in:
Max Schenkelberg 2013-10-04 13:56:24 -05:00
parent 0f3b5172d4
commit 1cc4b105e9
8 changed files with 404 additions and 222 deletions

View file

@ -36,7 +36,6 @@ import javax.xml.bind.annotation.XmlRootElement;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.annotations.DataURIConfig;
import com.raytheon.uf.common.dataplugin.persist.IPersistable;
import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject;
import com.raytheon.uf.common.pointdata.IPointData;
@ -72,7 +71,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@DynamicSerialize
@DataURIConfig(persistentIndex = 2)
public abstract class BufrMosData extends PersistablePluginDataObject implements
IPersistable, IPointData {

View file

@ -32,7 +32,6 @@ import javax.xml.bind.annotation.XmlRootElement;
import org.hibernate.annotations.Index;
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.annotations.DataURIConfig;
import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
@ -62,7 +61,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@DynamicSerialize
@DataURIConfig(persistentIndex = 4)
public class BufrMosDataLocation extends PersistableDataObject {
private static final long serialVersionUID = 1L;

View file

@ -40,6 +40,7 @@ import javax.xml.bind.annotation.XmlElement;
import org.hibernate.annotations.Index;
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
import com.raytheon.uf.common.dataplugin.annotations.DataURIFieldConverter;
import com.raytheon.uf.common.dataplugin.annotations.DataURIUtil;
import com.raytheon.uf.common.dataplugin.persist.DefaultPathProvider;
import com.raytheon.uf.common.dataplugin.persist.IHDFFilePathProvider;
@ -116,6 +117,22 @@ public abstract class PluginDataObject extends PersistableDataObject implements
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(PluginDataObject.class);
public static final class DataTimeURIConverter implements
DataURIFieldConverter {
@Override
public String toString(Object field) {
if (field instanceof DataTime) {
return ((DataTime) field).getURIString();
}
return null;
}
@Override
public Object fromString(String string) {
return new DataTime(string);
}
}
private static final long serialVersionUID = 1L;
public static final String PLUGIN_NAME_ID = "pluginName";
@ -134,7 +151,7 @@ public abstract class PluginDataObject extends PersistableDataObject implements
@Embedded
@XmlElement
@DynamicSerializeElement
@DataURI(position = 0)
@DataURI(position = 0, converter = DataTimeURIConverter.class)
protected DataTime dataTime;
/** The timestamp denoting when this record was inserted into the database */

View file

@ -42,6 +42,22 @@ import java.lang.annotation.Target;
@Target(ElementType.FIELD)
public @interface DataURI {
/** Class used to specify non-implemented default converter */
public static final class NotImplementedFieldConverter implements
DataURIFieldConverter {
@Override
public String toString(Object field) {
throw new UnsupportedOperationException();
}
@Override
public Object fromString(String string) {
throw new UnsupportedOperationException();
}
}
public static final Class<NotImplementedFieldConverter> NO_CONVERTER = NotImplementedFieldConverter.class;
public static final String SEPARATOR = "/";
/**
@ -53,9 +69,18 @@ public @interface DataURI {
/**
* Denotes if this is an embedded dataURI meaning that the actual dataURI
* elements are defined by this field class
* elements are defined by this field class. This field is mutualy exclusive
* with {@link #converter()}
*
* @return True if embedded, else false
*/
boolean embedded() default false;
/**
* {@link DataURIFieldConverter} to be used to convert to/from uri string.
* Mutually exclusive with {@link #embedded()}
*
* @return
*/
Class<? extends DataURIFieldConverter> converter() default NotImplementedFieldConverter.class;
}

View file

@ -19,38 +19,41 @@
**/
package com.raytheon.uf.common.dataplugin.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Provides configuration parameters at a class level for data uris
* Interface classes can register for converting {@link DataURI} annotated
* fields to and from {@link String}s
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 2, 2009 chammack Initial creation
* Oct 3, 2013 2081 mschenke Initial creation
*
* </pre>
*
* @author chammack
* @author mschenke
* @version 1.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DataURIConfig {
public interface DataURIFieldConverter {
/**
* Configures the index in the datauri which is used inside of the
* persistent file vs. in the file structure
* Converts field object to a String for the DataURI
*
* Elements before this index will be represented in the file structure,
* elements after will be represented inside the file metadata
*
* @return the index
* @param field
* @return
*/
public int persistentIndex() default 0;
public String toString(Object field);
/**
* Converts String returned from {@link #toString()} back into a field
* object
*
* @param string
* @return
*/
public Object fromString(String string);
}

View file

@ -57,6 +57,7 @@ import com.raytheon.uf.common.util.ConvertUtil;
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract and removed setPluginName.
* Sep 24, 2013 2081 mschenke Removed special handling of spaces and only handle
* {@link DataURI#SEPARATOR} specially
* Oct 4, 2013 2081 mschenke Refactored for custom uri field conversion
*
* </pre>
*
@ -90,26 +91,12 @@ public class DataURIUtil {
private static final Pattern DATAURI_SEPARATOR_CHAR_ENCODED_PATTERN = Pattern
.compile(DATAURI_SEPARATOR_CHAR_ENCODED);
/*
* Compares two fields with the DataURI annotations based off the position.
*/
private static final Comparator<Field> dataURIAnnotationComparator = new Comparator<Field>() {
@Override
public int compare(Field f1, Field f2) {
int i1 = f1.getAnnotation(DataURI.class).position();
int i2 = f2.getAnnotation(DataURI.class).position();
return (i1 < i2 ? -1 : (i1 == i2 ? 0 : 1));
}
};
private static IPluginClassMapper classMapper;
/*
* Internal cache to avoid constant reflection
*/
private static Map<Class<?>, DataURIFieldAccess[]> uriFieldMap = new ConcurrentHashMap<Class<?>, DataURIFieldAccess[]>();
private static Map<Class<?>, DataURIFieldAccessCache> uriFieldMap = new ConcurrentHashMap<Class<?>, DataURIFieldAccessCache>();
/**
* The classMapper needs to be injected to allow this class to create new
@ -130,10 +117,11 @@ public class DataURIUtil {
*/
public static String createDataURI(PluginDataObject pdo)
throws PluginException {
DataURIFieldAccessCache cache = getAccessCache(pdo.getClass());
StringBuilder uri = new StringBuilder(160);
addToDataURI(uri, pdo.getPluginName());
for (DataURIFieldAccess access : getAccess(pdo.getClass())) {
addToDataURI(uri, access.getFieldValue(pdo));
for (DataURIFieldAccess access : cache.getDataURIFields()) {
addToDataURI(uri, access.getFieldString(pdo));
}
return uri.toString();
}
@ -147,11 +135,13 @@ public class DataURIUtil {
*/
public static String createDataURI(Map<String, Object> dataMap)
throws PluginException {
String pluginName = dataMap.get(PLUGIN_NAME_KEY).toString();
String pluginName = (String) dataMap.get(PLUGIN_NAME_KEY);
DataURIFieldAccessCache cache = getAccessCache(pluginName);
StringBuilder uri = new StringBuilder(160);
addToDataURI(uri, pluginName);
for (DataURIFieldAccess access : getAccess(pluginName)) {
addToDataURI(uri, dataMap.get(access.getFieldName()));
for (DataURIFieldAccess access : cache.getDataURIFields()) {
addToDataURI(uri,
access.toFieldString(dataMap.get(access.getFieldName())));
}
return uri.toString();
}
@ -159,20 +149,12 @@ public class DataURIUtil {
/*
* Properly formats an arbitrary object into a dataURI.
*/
private static void addToDataURI(StringBuilder uri, Object property) {
String propertyString;
if (property instanceof Calendar) {
propertyString = TimeUtil.formatCalendar((Calendar) property);
} else {
propertyString = String.valueOf(property);
}
private static void addToDataURI(StringBuilder uri, String property) {
// This is done so if the property actually contained '%2F' that
// wouldn't get converted to '/' when tokenized. %2F becomes %252F
// because the '%' is replaced with '%25'
String escapeCharEscaped = DATAURI_SEPARATED_ESCAPE_CHAR_PATTERN
.matcher(propertyString).replaceAll(
DATAURI_SEPARATOR_CHAR_ENCODED);
.matcher(property).replaceAll(DATAURI_SEPARATOR_CHAR_ENCODED);
// Now replace any '/' with %2F to escape slashes in the property
String fullyEscapedProperty = DATAURI_SEPARATOR_PATTERN.matcher(
escapeCharEscaped).replaceAll(DATAURI_SEPARATOR_ENCODED);
@ -189,16 +171,18 @@ public class DataURIUtil {
*/
public static Map<String, Object> createDataURIMap(String dataURI)
throws PluginException {
List<String> tokens = tokenizeURI(dataURI);
String[] tokens = tokenizeURI(dataURI);
Map<String, Object> dataMap = new HashMap<String, Object>(
(int) ((tokens.size() / 0.75f) + 1), 0.75f);
String pluginName = tokens.get(0);
tokens = tokens.subList(1, tokens.size());
tokens.length, 1.0f);
String pluginName = tokens[0];
dataMap.put(PLUGIN_NAME_KEY, pluginName);
DataURIFieldAccess[] access = getAccess(pluginName);
DataURIFieldAccessCache cache = getAccessCache(pluginName);
DataURIFieldAccess[] access = cache.getDataURIFields();
for (int i = 0; i < access.length; i += 1) {
// Offset tokens by 1 as [0] is plugin name
dataMap.put(access[i].getFieldName(),
access[i].getFieldValue(tokens.get(i)));
access[i].getFieldValue(tokens[i + 1]));
}
return dataMap;
}
@ -215,6 +199,29 @@ public class DataURIUtil {
return createDataURIMap((Object) pdo);
}
/**
* Create a dataURIMap from any object with dataURI annotations.
*
* @param object
* @return
* @throws PluginException
*/
public static Map<String, Object> createDataURIMap(Object object)
throws PluginException {
DataURIFieldAccessCache cache = getAccessCache(object.getClass());
DataURIFieldAccess[] accessArray = cache.getDataURIFields();
Map<String, Object> dataMap = new HashMap<String, Object>(
accessArray.length, 1.0f);
if (object instanceof PluginDataObject) {
dataMap.put(PLUGIN_NAME_KEY,
((PluginDataObject) object).getPluginName());
}
for (DataURIFieldAccess access : accessArray) {
dataMap.put(access.getFieldName(), access.getFieldValue(object));
}
return dataMap;
}
/**
* Create a new PluginDataObject based off the dataURI. THe class of the
* result object is based off the pluginName in the dataURI and all fields
@ -227,8 +234,8 @@ public class DataURIUtil {
public static PluginDataObject createPluginDataObject(String dataURI)
throws PluginException {
PluginDataObject pdo = null;
List<String> tokens = tokenizeURI(dataURI);
Class<PluginDataObject> clazz = getPluginRecordClass(tokens.get(0));
String[] tokens = tokenizeURI(dataURI);
Class<PluginDataObject> clazz = getPluginRecordClass(tokens[0]);
try {
pdo = clazz.newInstance();
} catch (Exception e) {
@ -262,19 +269,6 @@ public class DataURIUtil {
return pdo;
}
/**
* Populate an existing PluginDataObjects with the DataURI fields from the
* dataMap.
*
* @param pdo
* @param dataMap
* @throws PluginException
*/
public static void populatePluginDataObject(PluginDataObject pdo,
Map<String, Object> dataMap) throws PluginException {
populateObject(pdo, dataMap);
}
/**
* Populate an existing PluginDataObject using fields parsed from the
* dataURI.
@ -290,25 +284,29 @@ public class DataURIUtil {
}
/**
* Create a dataURIMap from any object with dataURI annotations.
* Populate an existing PluginDataObjects with the DataURI fields from the
* dataMap.
*
* @param object
* @return
* @param pdo
* @param dataMap
* @throws PluginException
*/
public static Map<String, Object> createDataURIMap(Object object)
throws PluginException {
DataURIFieldAccess[] accessArray = getAccess(object.getClass());
Map<String, Object> dataMap = new HashMap<String, Object>(
(int) ((accessArray.length / 0.75f) + 2), 0.75f);
if (object instanceof PluginDataObject) {
dataMap.put(PLUGIN_NAME_KEY,
((PluginDataObject) object).getPluginName());
public static void populatePluginDataObject(PluginDataObject pdo,
Map<String, Object> dataMap) throws PluginException {
populateObject(pdo, dataMap);
}
/*
* Populate a PDO with the tokens from a parsed DataURI
*/
private static void populatePluginDataObject(PluginDataObject pdo,
String[] uriTokens) throws PluginException {
DataURIFieldAccessCache cache = getAccessCache(pdo.getClass());
DataURIFieldAccess[] access = cache.getDataURIFields();
for (int i = 0; i < access.length; i += 1) {
access[i].setFieldValue(pdo,
access[i].getFieldValue(uriTokens[i + 1]));
}
for (DataURIFieldAccess access : accessArray) {
dataMap.put(access.getFieldName(), access.getFieldValue(object));
}
return dataMap;
}
/**
@ -320,44 +318,22 @@ public class DataURIUtil {
*/
public static void populateObject(Object object, Map<String, Object> dataMap)
throws PluginException {
Map<String, DataURIFieldAccess> accessMap = new HashMap<String, DataURIFieldAccess>();
for (DataURIFieldAccess access : getAccess(object.getClass())) {
accessMap.put(access.getFieldName(), access);
}
DataURIFieldAccessCache cache = getAccessCache(object.getClass());
for (String dataKey : dataMap.keySet()) {
if (!PLUGIN_NAME_KEY.equals(dataKey)) {
Object data = dataMap.get(dataKey);
DataURIFieldAccess access = accessMap.get(dataKey);
if (access == null) {
access = new DataURIFieldAccess(
Arrays.asList(FIELD_SEPARATOR_PATTERN
.split(dataKey)),
object != null ? object.getClass() : null);
DataURIFieldAccess access = cache.getFieldAccess(dataKey, data);
if (access != null) {
access.setFieldValue(object, data);
}
access.setFieldValue(object, data);
}
}
}
/*
* Populate a PDO with the tokens from a parsed DataURI
*/
private static void populatePluginDataObject(PluginDataObject pdo,
List<String> uriTokens) throws PluginException {
uriTokens = uriTokens.subList(1, uriTokens.size());
DataURIFieldAccess[] access = getAccess(pdo.getClass());
for (int i = 0; i < access.length; i += 1) {
access[i].setFieldValue(pdo,
access[i].getFieldValue(uriTokens.get(i)));
}
}
/*
* Split a URI on the seperator and remove empty first element.
*/
private static List<String> tokenizeURI(String dataURI) {
private static String[] tokenizeURI(String dataURI) {
String[] tokens = DATAURI_SEPARATOR_PATTERN.split(dataURI);
for (int i = 0; i < tokens.length; ++i) {
// Replace %2F with '/'
@ -367,54 +343,29 @@ public class DataURIUtil {
tokens[i] = DATAURI_SEPARATOR_CHAR_ENCODED_PATTERN.matcher(
tokens[i]).replaceAll(DATAURI_SEPARATOR_ESCAPE_CHAR);
}
return Arrays.asList(tokens).subList(1, tokens.length);
// Removes empty string in [0] due to starting with '/'
return Arrays.copyOfRange(tokens, 1, tokens.length);
}
private static DataURIFieldAccess[] getAccess(String pluginName)
private static DataURIFieldAccessCache getAccessCache(String pluginName)
throws PluginException {
return getAccess(getPluginRecordClass(pluginName));
return getAccessCache(getPluginRecordClass(pluginName));
}
private static DataURIFieldAccess[] getAccess(Class<?> clazz) {
DataURIFieldAccess[] result = uriFieldMap.get(clazz);
if (result == null) {
result = getAccess(clazz, Collections.<String> emptyList())
.toArray(new DataURIFieldAccess[0]);
uriFieldMap.put(clazz, result);
private static DataURIFieldAccessCache getAccessCache(Class<?> clazz)
throws PluginException {
if (clazz == null) {
throw new PluginException(
"Cannot retrieve field access for null class");
}
return result;
}
private static List<DataURIFieldAccess> getAccess(Class<?> clazz,
List<String> parents) {
List<Field> fields = getOrderedDataURIFields(clazz);
List<DataURIFieldAccess> accessors = new ArrayList<DataURIFieldAccess>();
for (Field field : fields) {
List<String> names = new ArrayList<String>(parents);
names.add(field.getName());
Class<?> type = field.getType();
if (field.getAnnotation(DataURI.class).embedded()) {
accessors.addAll(getAccess(type, names));
} else {
accessors.add(new DataURIFieldAccess(names, type));
synchronized (clazz) {
DataURIFieldAccessCache cache = uriFieldMap.get(clazz);
if (cache == null) {
cache = new DataURIFieldAccessCache(clazz);
uriFieldMap.put(clazz, cache);
}
return cache;
}
return accessors;
}
private static List<Field> getOrderedDataURIFields(Class<?> clazz) {
List<Field> fields = new ArrayList<Field>();
Class<?> currentClass = clazz;
while (currentClass != null) {
for (Field field : currentClass.getDeclaredFields()) {
if (field.getAnnotation(DataURI.class) != null) {
fields.add(field);
}
}
currentClass = currentClass.getSuperclass();
}
Collections.sort(fields, dataURIAnnotationComparator);
return fields;
}
public static Class<PluginDataObject> getPluginRecordClass(String pluginName)
@ -426,6 +377,112 @@ public class DataURIUtil {
return classMapper.getPluginRecordClass(pluginName);
}
private static class DataURIFieldAccessCache {
/*
* Compares two fields with the DataURI annotations based off the
* position.
*/
private static final Comparator<Field> dataURIAnnotationComparator = new Comparator<Field>() {
@Override
public int compare(Field f1, Field f2) {
int i1 = f1.getAnnotation(DataURI.class).position();
int i2 = f2.getAnnotation(DataURI.class).position();
return (i1 < i2 ? -1 : (i1 == i2 ? 0 : 1));
}
};
private final DataURIFieldAccess[] dataURIFields;
private Map<String, DataURIFieldAccess> fieldMap;
public DataURIFieldAccessCache(Class<?> type) throws PluginException {
this.fieldMap = new HashMap<String, DataURIFieldAccess>();
this.dataURIFields = getDataURIAccessFields(type);
for (DataURIFieldAccess access : dataURIFields) {
fieldMap.put(access.getFieldName(), access);
}
}
public DataURIFieldAccess[] getDataURIFields() {
return dataURIFields;
}
public DataURIFieldAccess getFieldAccess(String fieldName, Object object) {
DataURIFieldAccess access = fieldMap.get(fieldName);
if (access == null && object != null) {
synchronized (this) {
Map<String, DataURIFieldAccess> newFieldMap = new HashMap<String, DataURIFieldAccess>(
fieldMap);
access = new DataURIFieldAccess(
Arrays.asList(FIELD_SEPARATOR_PATTERN
.split(fieldName)), object.getClass(), null);
newFieldMap.put(fieldName, access);
fieldMap = newFieldMap;
}
}
return access;
}
/**
* @param clazz
* @return
* @throws PluginException
*/
private static DataURIFieldAccess[] getDataURIAccessFields(
Class<?> clazz) throws PluginException {
return getAccess(clazz, Collections.<String> emptyList()).toArray(
new DataURIFieldAccess[0]);
}
private static List<DataURIFieldAccess> getAccess(Class<?> clazz,
List<String> parents) throws PluginException {
List<Field> fields = getOrderedDataURIFields(clazz);
List<DataURIFieldAccess> accessors = new ArrayList<DataURIFieldAccess>();
for (Field field : fields) {
List<String> names = new ArrayList<String>(parents);
names.add(field.getName());
Class<?> type = field.getType();
DataURI dataURI = field.getAnnotation(DataURI.class);
if (dataURI.embedded()) {
accessors.addAll(getAccess(type, names));
} else {
DataURIFieldConverter converter = null;
if (dataURI.converter() != DataURI.NO_CONVERTER) {
try {
converter = dataURI.converter().newInstance();
} catch (Exception e) {
throw new PluginException(
"Error creating field convert: "
+ dataURI.converter(), e);
}
}
accessors
.add(new DataURIFieldAccess(names, type, converter));
}
}
return accessors;
}
private static List<Field> getOrderedDataURIFields(Class<?> clazz) {
List<Field> fields = new ArrayList<Field>();
Class<?> currentClass = clazz;
while (currentClass != null) {
for (Field field : currentClass.getDeclaredFields()) {
if (field.getAnnotation(DataURI.class) != null) {
fields.add(field);
}
}
currentClass = currentClass.getSuperclass();
}
Collections.sort(fields, dataURIAnnotationComparator);
return fields;
}
}
/*
* Class which remembers the fieldNames and class of a dataURI field to make
* parsing faster.
@ -444,12 +501,14 @@ public class DataURIUtil {
*/
private final String fieldName;
/**
* Class of the oibject that is in the dataURI.
*/
/** Class of the oibject that is in the dataURI. */
private final Class<?> fieldClass;
public DataURIFieldAccess(List<String> fieldNames, Class<?> fieldClass) {
/** URI field converter */
private DataURIFieldConverter fieldConverter;
public DataURIFieldAccess(List<String> fieldNames, Class<?> fieldClass,
DataURIFieldConverter fieldConverter) {
this.fieldNames = fieldNames.toArray(new String[0]);
StringBuilder fieldName = new StringBuilder(this.fieldNames[0]);
for (int i = 1; i < this.fieldNames.length; i += 1) {
@ -457,22 +516,62 @@ public class DataURIUtil {
}
this.fieldName = fieldName.toString();
this.fieldClass = fieldClass;
this.fieldConverter = fieldConverter;
}
/**
* Returns the fully qualified name of the field
*
* @return
*/
public String getFieldName() {
return fieldName;
}
/**
* Extract the field value from a PDO.
* Extract the field value designated by this field access object from
* the field container Object and converts it to a URI string
*
* @param pdo
* @param fieldContainer
* @return
* @throws PluginException
*/
public Object getFieldValue(Object pdo) throws PluginException {
public String getFieldString(Object fieldContainer)
throws PluginException {
return toFieldString(getFieldValue(fieldContainer));
}
/**
* Converts the field value represented by this field access to a uri
* string
*
* @param fieldValue
* @return
*/
public String toFieldString(Object fieldValue) {
String string;
if (fieldConverter != null) {
string = fieldConverter.toString(fieldValue);
} else if (fieldValue instanceof Calendar) {
string = TimeUtil.formatCalendar((Calendar) fieldValue);
} else {
string = String.valueOf(fieldValue);
}
return string;
}
/**
* Extract the field value designated by this field access object from
* the field container Object
*
* @param fieldContainer
* @return
* @throws PluginException
*/
public Object getFieldValue(Object fieldContainer)
throws PluginException {
try {
Object object = pdo;
Object object = fieldContainer;
for (String fieldName : fieldNames) {
object = PropertyUtils.getProperty(object, fieldName);
if (object == null) {
@ -493,19 +592,22 @@ public class DataURIUtil {
* @throws PluginException
*/
public Object getFieldValue(String stringValue) throws PluginException {
if (fieldConverter != null) {
return fieldConverter.fromString(stringValue);
}
return ConvertUtil.convertObject(stringValue, fieldClass);
}
/**
* Set the fieldValue into the PDO.
* Set the fieldValue Object into the fieldContainer Object.
*
* @param pdo
* @param fieldContainer
* @param fieldValue
* @throws PluginException
*/
public void setFieldValue(Object pdo, Object fieldValue)
public void setFieldValue(Object fieldContainer, Object fieldValue)
throws PluginException {
Object source = pdo;
Object source = fieldContainer;
try {
for (int i = 0; i < (fieldNames.length - 1); i += 1) {
Object obj = PropertyUtils.getProperty(source,

View file

@ -33,7 +33,6 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.beanutils.PropertyUtils;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.dataplugin.annotations.DataURIConfig;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.common.localization.LocalizationContext;
import com.raytheon.uf.common.localization.PathManagerFactory;
@ -57,6 +56,7 @@ import com.raytheon.uf.common.time.util.TimeUtil;
* 1/08/09 1674 bphillip Initial creation
* 04/08/13 1293 bkowal Removed references to hdffileid.
* 04/30/13 1861 bkowal Added constant for hdf5 file suffix.
* 10/04/13 2081 mschenke Removed unused annotation logic
* </pre>
*
* @author bphillip
@ -65,7 +65,7 @@ import com.raytheon.uf.common.time.util.TimeUtil;
public class DefaultPathProvider implements IHDFFilePathProvider {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(DefaultPathProvider.class);
public static final String HDF5_SUFFIX = ".h5";
public static final ThreadLocal<SimpleDateFormat> fileNameFormat = new ThreadLocal<SimpleDateFormat>() {
@ -241,32 +241,16 @@ public class DefaultPathProvider implements IHDFFilePathProvider {
+ persistable.toString());
}
StringBuffer sb = new StringBuffer();
sb.append(pluginName);
if (persistable instanceof PluginDataObject) {
PluginDataObject pdo = (PluginDataObject) persistable;
DataURIConfig config = pdo.getClass().getAnnotation(
DataURIConfig.class);
int idx = 0;
if (config != null) {
idx = config.persistentIndex();
}
String[] dataURIParts = pdo.getDataURI().split("/");
StringBuffer sb = new StringBuffer();
sb.append(pluginName);
for (int i = 0; i < idx; i++) {
sb.append("-");
sb.append(dataURIParts[i]);
}
Date refTime = ((PluginDataObject) persistable).getDataTime()
.getRefTime();
sb.append(fileNameFormat.get().format(refTime));
sb.append(".h5");
return sb.toString();
}
return pluginName + ".h5";
sb.append(".h5");
return sb.toString();
}
}

View file

@ -125,7 +125,7 @@ public class DataTime implements Comparable<DataTime>, Serializable,
private static final Comparator<DataTime> DEFAULT_COMPARATOR = new DataTimeComparator(
SortKey.VALID_TIME, SortKey.FORECAST_TIME, false);
/** The reference time */
@Column(name = "refTime")
@DynamicSerializeElement
@ -438,7 +438,7 @@ public class DataTime implements Comparable<DataTime>, Serializable,
} else {
return (rt1.equals(rt2) && fcstTime == rhs.fcstTime
&& validPeriod.equals(rhs.validPeriod) && levelValue
.equals(rhs.levelValue));
.equals(rhs.levelValue));
}
}
@ -611,6 +611,88 @@ public class DataTime implements Comparable<DataTime>, Serializable,
this.visible = visible;
}
private String getReftimeString() {
if (refTime != null) {
Calendar cal = Calendar.getInstance(TimeUtil.GMT_TIME_ZONE);
cal.setTime(this.refTime);
return TimeUtil.formatCalendar(cal);
}
return null;
}
private String getForecastString() {
if (utilityFlags.contains(FLAG.FCST_USED)) {
int hrs = fcstTime / 3600;
int mins = (fcstTime - hrs * 3600) / 60;
if (fcstTime % 3600 == 0) {
return "(" + hrs + ")";
} else {
return "(" + hrs + ":" + mins + ")";
}
}
return null;
}
private String getValidPeriodString() {
if (utilityFlags.contains(FLAG.PERIOD_USED)) {
return "[" + TimeUtil.formatDate(validPeriod.getStart()) + "--"
+ TimeUtil.formatDate(validPeriod.getEnd()) + "]";
}
return null;
}
/**
* Returns the DataTime in a URI formatted way
*
* @return
*/
public String getURIString() {
StringBuilder builder = new StringBuilder();
String refTimeStr = getReftimeString();
if (refTimeStr != null) {
builder.append(refTimeStr);
}
String forecastString = getForecastString();
if (forecastString != null) {
builder.append("_").append(forecastString);
}
String validPeriodString = getValidPeriodString();
if (validPeriodString != null) {
builder.append(validPeriodString);
}
return builder.toString();
}
/**
* Returns the DataTime in a display friendly format
*
* @return
*/
public String getDisplayString() {
StringBuilder builder = new StringBuilder();
String refTimeStr = getReftimeString();
if (refTimeStr != null) {
builder.append(refTimeStr.replaceAll("_", " "));
}
String forecastString = getForecastString();
if (forecastString != null) {
builder.append(" ").append(forecastString);
}
String validPeriodString = getValidPeriodString();
if (validPeriodString != null) {
builder.append(validPeriodString.replaceAll("_", " "));
}
return builder.toString();
}
/*
* (non-Javadoc)
*
@ -618,34 +700,7 @@ public class DataTime implements Comparable<DataTime>, Serializable,
*/
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
if (refTime != null) {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.setTime(this.refTime);
buffer.append(TimeUtil.formatCalendar(cal).replaceAll("_", " "));
}
if (utilityFlags.contains(FLAG.FCST_USED)) {
int hrs = fcstTime / 3600;
int mins = (fcstTime - hrs * 3600) / 60;
if (fcstTime % 3600 == 0) {
buffer.append(" (").append(hrs).append(")");
} else {
buffer.append(" (").append(hrs).append(":").append(mins)
.append(")");
}
}
if (utilityFlags.contains(FLAG.PERIOD_USED)) {
buffer.append("[");
buffer.append(TimeUtil.formatDate(validPeriod.getStart())
.replaceAll("_", " "));
buffer.append("--");
buffer.append(TimeUtil.formatDate(validPeriod.getEnd()).replaceAll(
"_", " "));
buffer.append("]");
}
return buffer.toString();
return getDisplayString();
}
/*