Issue #1869 Rewrite dataURI property mappings.
Change-Id: I1aa45aa5214c3d080766129a470903f2fc2e49b9 Former-commit-id:931e76ae59
[formerlyc11631c7da
[formerly1a31aa2211
] [formerly931e76ae59
[formerly 9c3af2ce1f086bb15fa1f4e261a4d7a1a65bd956]]] Former-commit-id:c11631c7da
[formerly1a31aa2211
] Former-commit-id:c11631c7da
Former-commit-id:5219bd8426
This commit is contained in:
parent
2d9c73be47
commit
bcfdd143ec
10 changed files with 575 additions and 551 deletions
|
@ -55,4 +55,17 @@
|
|||
<constructor-arg ref="requestServiceRouter" />
|
||||
</bean>
|
||||
|
||||
<bean id="recordFactory" class="com.raytheon.uf.viz.core.RecordFactory" factory-method="getInstance"/>
|
||||
|
||||
<bean id="recordFactoryRegisteredToDataURIUtil"
|
||||
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
<property name="targetClass">
|
||||
<value>com.raytheon.uf.common.dataplugin.annotations.DataURIUtil</value>
|
||||
</property>
|
||||
<property name="targetMethod">
|
||||
<value>setClassMapper</value>
|
||||
</property>
|
||||
<property name="arguments" ref="recordFactory" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -24,9 +24,9 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.IPluginClassMapper;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURIUtil;
|
||||
import com.raytheon.uf.common.dataplugin.request.GetPluginRecordMapRequest;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
|
@ -50,11 +50,12 @@ import com.raytheon.uf.viz.core.requests.ThriftClient;
|
|||
* Mar 05, 2013 1753 njensen Improved debug message
|
||||
* Mar 29, 2013 1638 mschenke Added dataURI mapping methods
|
||||
* May 15, 2013 1869 bsteffen Move uri map creation to DataURIUtil.
|
||||
* May 16, 2013 1869 bsteffen Rewrite dataURI property mappings.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
public class RecordFactory {
|
||||
public class RecordFactory implements IPluginClassMapper {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(RecordFactory.class);
|
||||
|
||||
|
@ -62,7 +63,7 @@ public class RecordFactory {
|
|||
private static RecordFactory instance = new RecordFactory();
|
||||
|
||||
/** Map containing the pluginName/Record class pairs */
|
||||
private Map<String, Class<PluginDataObject>> defMap = new HashMap<String, Class<PluginDataObject>>();
|
||||
private volatile Map<String, Class<PluginDataObject>> defMap = null;
|
||||
|
||||
public static final String WILDCARD = "%";
|
||||
|
||||
|
@ -79,20 +80,21 @@ public class RecordFactory {
|
|||
* Creates the singleton instance of the RecordFactory
|
||||
*/
|
||||
private RecordFactory() {
|
||||
try {
|
||||
loadDefMap();
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.WARN,
|
||||
"Failed to load plugin record definitions", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void loadDefMap() throws VizException {
|
||||
private Map<String, Class<PluginDataObject>> getDefMap() {
|
||||
if (defMap == null) {
|
||||
synchronized (this) {
|
||||
if (defMap == null) {
|
||||
Map<String, Class<PluginDataObject>> defMap = new HashMap<String, Class<PluginDataObject>>();
|
||||
GetPluginRecordMapRequest req = new GetPluginRecordMapRequest();
|
||||
try {
|
||||
Map<String, String> pluginRecordMap = (Map<String, String>) ThriftClient
|
||||
.sendRequest(req);
|
||||
for (Map.Entry<String, String> entry : pluginRecordMap.entrySet()) {
|
||||
for (Map.Entry<String, String> entry : pluginRecordMap
|
||||
.entrySet()) {
|
||||
String pluginName = entry.getKey();
|
||||
String record = entry.getValue();
|
||||
if (record != null) {
|
||||
|
@ -101,13 +103,24 @@ public class RecordFactory {
|
|||
.forName(record);
|
||||
defMap.put(pluginName, clazz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
String msg = "Can't find record class for " + pluginName
|
||||
+ " plugin - alerts on " + pluginName
|
||||
String msg = "Can't find record class for "
|
||||
+ pluginName
|
||||
+ " plugin - alerts on "
|
||||
+ pluginName
|
||||
+ " data will be ignored";
|
||||
statusHandler.handle(Priority.DEBUG, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.WARN,
|
||||
"Failed to load plugin record definitions", e);
|
||||
}
|
||||
this.defMap = defMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
return defMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +129,7 @@ public class RecordFactory {
|
|||
* @return
|
||||
*/
|
||||
public Collection<String> getSupportedPlugins() {
|
||||
return new TreeSet<String>(defMap.keySet());
|
||||
return new TreeSet<String>(getDefMap().keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,16 +148,10 @@ public class RecordFactory {
|
|||
return null;
|
||||
}
|
||||
|
||||
String[] tokens = dataURI.split(DataURI.SEPARATOR, 3);
|
||||
String pluginName = tokens[1];
|
||||
|
||||
try {
|
||||
Map<String, Object> map = DataURIUtil.createDataURIMap(dataURI,
|
||||
getPluginClass(pluginName));
|
||||
Map<String, Object> map = DataURIUtil.createDataURIMap(dataURI);
|
||||
map.put("dataURI", dataURI);
|
||||
return map;
|
||||
} catch (NoPluginException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new VizException("Unable to create property map for "
|
||||
+ dataURI, e);
|
||||
|
@ -162,8 +169,9 @@ public class RecordFactory {
|
|||
* If errors occur creating the field/value map
|
||||
*/
|
||||
public Class<PluginDataObject> getPluginClass(String pluginName)
|
||||
throws VizException {
|
||||
throws NoPluginException {
|
||||
Class<PluginDataObject> retVal = null;
|
||||
Map<String, Class<PluginDataObject>> defMap = getDefMap();
|
||||
if (defMap != null) {
|
||||
retVal = defMap.get(pluginName);
|
||||
}
|
||||
|
@ -229,10 +237,21 @@ public class RecordFactory {
|
|||
+ type, e);
|
||||
}
|
||||
try {
|
||||
PluginDataObject.populateFromMap(record, map);
|
||||
DataURIUtil
|
||||
.populatePluginDataObject((PluginDataObject) record, map);
|
||||
} catch (PluginException e) {
|
||||
throw new VizException(e);
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<PluginDataObject> getPluginRecordClass(String pluginName)
|
||||
throws PluginException {
|
||||
try {
|
||||
return getPluginClass(pluginName);
|
||||
} catch (NoPluginException e) {
|
||||
throw new PluginException(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.common.dataplugin;
|
||||
|
||||
|
||||
/**
|
||||
* Interface for any class that is capable of mapping a pluginName to a class
|
||||
* which extends PluginDataObject. This interface exists in common so that
|
||||
* different mechanisms can easily be used in different parts of the system.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* May 16, 2013 1869 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface IPluginClassMapper {
|
||||
|
||||
public Class<PluginDataObject> getPluginRecordClass(String pluginName)
|
||||
throws PluginException;
|
||||
}
|
|
@ -20,10 +20,7 @@
|
|||
|
||||
package com.raytheon.uf.common.dataplugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Embedded;
|
||||
|
@ -40,7 +37,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
|||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
import org.hibernate.annotations.Index;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
|
||||
|
@ -52,9 +48,10 @@ import com.raytheon.uf.common.serialization.ISerializableObject;
|
|||
import com.raytheon.uf.common.serialization.SerializationUtil;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.ConvertUtil;
|
||||
|
||||
/**
|
||||
* Abstract class from which all plugin specific data types inherit. A plugin
|
||||
|
@ -88,21 +85,24 @@ import com.raytheon.uf.common.util.ConvertUtil;
|
|||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 7/24/07 353 bphillip Initial creation
|
||||
* 20071129 472 jkorman Added getDecoderGettable().
|
||||
* 2/6/09 1990 bphillip Added database index on dataURI
|
||||
* 3/18/09 2105 jsanchez Added getter for id.
|
||||
* Removed unused getIdentfier().
|
||||
* Mar 29, 2013 1638 mschenke Added methods for loading from data map and creating data map from
|
||||
* dataURI fields
|
||||
* Apr 12, 2013 1857 bgonzale Changed to MappedSuperclass, named generator,
|
||||
* GenerationType SEQUENCE, moved Indexes to getter
|
||||
* methods.
|
||||
* Jul 24, 2007 353 bphillip Initial creation
|
||||
* Nov 29, 2007 472 jkorman Added getDecoderGettable().
|
||||
* Feb 06, 2009 1990 bphillip Added database index on dataURI
|
||||
* Mar 18, 2009 2105 jsanchez Added getter for id. Removed unused
|
||||
* getIdentfier().
|
||||
* Mar 29, 2013 1638 mschenke Added methods for loading from data map
|
||||
* and creating data map from dataURI
|
||||
* fields
|
||||
* Apr 12, 2013 1857 bgonzale Changed to MappedSuperclass, named
|
||||
* generator, GenerationType SEQUENCE,
|
||||
* moved Indexes to getter methods.
|
||||
* Apr 15, 2013 1868 bsteffen Improved performance of createDataURIMap
|
||||
* May 02, 2013 1970 bgonzale Moved Index annotation from getters to attributes.
|
||||
* </pre>
|
||||
* May 02, 2013 1970 bgonzale Moved Index annotation from getters to
|
||||
* attributes.
|
||||
* May 07, 2013 1869 bsteffen Remove dataURI column from
|
||||
* PluginDataObject.
|
||||
* May 16, 2013 1869 bsteffen Rewrite dataURI property mappings.
|
||||
* </pre>
|
||||
*
|
||||
*/
|
||||
@MappedSuperclass
|
||||
|
@ -112,6 +112,9 @@ import com.raytheon.uf.common.util.ConvertUtil;
|
|||
public abstract class PluginDataObject extends PersistableDataObject implements
|
||||
ISerializableObject {
|
||||
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(PluginDataObject.class);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final String ID_GEN = "idgen";
|
||||
|
@ -159,12 +162,16 @@ public abstract class PluginDataObject extends PersistableDataObject implements
|
|||
* Default Constructor
|
||||
*/
|
||||
public PluginDataObject() {
|
||||
|
||||
}
|
||||
|
||||
public PluginDataObject(String uri) {
|
||||
String[] uriTokens = uri.split(DataURI.SEPARATOR);
|
||||
pluginName = uriTokens[1];
|
||||
populateObject(this, uriTokens);
|
||||
try {
|
||||
DataURIUtil.populatePluginDataObject(this, uri);
|
||||
} catch (PluginException e) {
|
||||
// this should never happen operationally
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
}
|
||||
this.dataURI = uri;
|
||||
}
|
||||
|
||||
|
@ -178,344 +185,19 @@ public abstract class PluginDataObject extends PersistableDataObject implements
|
|||
getDataURI();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive method for generating a dataURI
|
||||
*
|
||||
* @param obj
|
||||
* An object containing fields annotated with the DataURI
|
||||
* annotation
|
||||
* @param uriBuffer
|
||||
* The dataURI StringBuffer
|
||||
* @return The updated dataURI
|
||||
*/
|
||||
private void generateURI(Object obj, StringBuilder uriBuffer) {
|
||||
|
||||
// Get the fields with @DataURI annotation
|
||||
Field[] dataURIFields = DataURIUtil.getInstance().getDataURIFields(
|
||||
obj.getClass());
|
||||
|
||||
/*
|
||||
* Iterate through each field and assemble the dataURI
|
||||
*/
|
||||
for (Field field : dataURIFields) {
|
||||
Object property = null;
|
||||
try {
|
||||
property = PropertyUtils.getProperty(obj, field.getName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (field.getAnnotation(DataURI.class).embedded()) {
|
||||
if (property == null) {
|
||||
// Populate datauri with all "null" for null embedded
|
||||
// objects.
|
||||
int numFields = DataURIUtil.getInstance().getDataURIFields(
|
||||
field.getClass()).length;
|
||||
for (int f = 0; f < numFields; f += 1) {
|
||||
uriBuffer.append(DataURI.SEPARATOR).append(
|
||||
String.valueOf(null));
|
||||
}
|
||||
} else {
|
||||
// Recursive call to get dataURI elements from embedded
|
||||
// object
|
||||
generateURI(property, uriBuffer);
|
||||
}
|
||||
} else {
|
||||
// Append to the dataURI buffer
|
||||
uriBuffer.append(DataURI.SEPARATOR);
|
||||
if (property == null) {
|
||||
uriBuffer.append("null");
|
||||
} else if (property instanceof Calendar) {
|
||||
uriBuffer.append(TimeUtil
|
||||
.formatCalendar((Calendar) property));
|
||||
} else {
|
||||
uriBuffer.append(String.valueOf(property).replaceAll(
|
||||
DataURI.SEPARATOR, "_"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the record object from a data map
|
||||
*
|
||||
* @param dataMap
|
||||
* @throws PluginException
|
||||
*/
|
||||
public void populateFromMap(Map<String, Object> dataMap)
|
||||
throws PluginException {
|
||||
populateFromMap(this, dataMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mapping of dataURI fields to objects set in the record
|
||||
*
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public Map<String, Object> createDataURIMap() throws PluginException {
|
||||
try {
|
||||
Class<? extends PluginDataObject> thisClass = this.getClass();
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("pluginName", getPluginName());
|
||||
int index = 0;
|
||||
String fieldName = PluginDataObject.getDataURIFieldName(thisClass,
|
||||
index++);
|
||||
while (fieldName != null) {
|
||||
Object source = this;
|
||||
int start = 0;
|
||||
int end = fieldName.indexOf('.', start);
|
||||
while (end >= 0) {
|
||||
source = PropertyUtils.getProperty(source,
|
||||
fieldName.substring(start, end));
|
||||
start = end + 1;
|
||||
end = fieldName.indexOf('.', start);
|
||||
}
|
||||
source = PropertyUtils.getProperty(source,
|
||||
fieldName.substring(start));
|
||||
map.put(fieldName, source);
|
||||
fieldName = PluginDataObject.getDataURIFieldName(thisClass,
|
||||
index++);
|
||||
}
|
||||
return map;
|
||||
} catch (Exception e) {
|
||||
throw new PluginException("Error constructing dataURI mapping", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates object from data mapping
|
||||
*
|
||||
* @param object
|
||||
* @param dataMap
|
||||
*/
|
||||
public static void populateFromMap(Object object,
|
||||
Map<String, Object> dataMap) throws PluginException {
|
||||
try {
|
||||
for (String property : dataMap.keySet()) {
|
||||
String[] nested = property.split("[.]");
|
||||
if (nested.length > 0) {
|
||||
Object source = object;
|
||||
for (int i = 0; i < nested.length - 1; ++i) {
|
||||
String field = nested[i];
|
||||
Object obj = PropertyUtils.getProperty(source, field);
|
||||
if (obj == null) {
|
||||
obj = PropertyUtils.getPropertyType(source, field)
|
||||
.newInstance();
|
||||
PropertyUtils.setProperty(source, field, obj);
|
||||
}
|
||||
source = obj;
|
||||
}
|
||||
String sourceProperty = nested[nested.length - 1];
|
||||
Object value = dataMap.get(property);
|
||||
if (value != null) {
|
||||
PropertyUtils
|
||||
.setProperty(source, sourceProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new PluginException("Error populating record type: "
|
||||
+ (object != null ? object.getClass() : null)
|
||||
+ " from map: " + dataMap, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive method to populate an object from the elements in a dataURI
|
||||
* string
|
||||
*
|
||||
* @param obj
|
||||
* The object for which to populate fields from the dataURI
|
||||
* string
|
||||
* @param uriTokens
|
||||
* The elements of the dataURI string
|
||||
* @return An object populated from the elements of the dataURI string
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object populateObject(Object obj, String[] uriTokens) {
|
||||
|
||||
// Get the fields annotated with the @DataURI annotation
|
||||
Field[] dataURIFields = DataURIUtil.getInstance().getDataURIFields(
|
||||
obj.getClass());
|
||||
|
||||
Field currentField = null;
|
||||
String currentUriToken = null;
|
||||
for (Field dataURIField : dataURIFields) {
|
||||
currentUriToken = uriTokens[uriIndex];
|
||||
currentField = dataURIField;
|
||||
|
||||
if (currentField.getAnnotation(DataURI.class).embedded()) {
|
||||
// The current dataURI token refers to a field in an embedded
|
||||
// object. Execute recursive call to populate embedded object
|
||||
try {
|
||||
if (obj instanceof Map) {
|
||||
populateObject(obj, uriTokens);
|
||||
} else {
|
||||
PropertyUtils.setProperty(
|
||||
obj,
|
||||
currentField.getName(),
|
||||
populateObject(currentField.getType()
|
||||
.newInstance(), uriTokens));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
// The current dataURI token refers to field in the obj class.
|
||||
// Assign the field and increment the uri index variable
|
||||
uriIndex++;
|
||||
try {
|
||||
Object property = ConvertUtil.convertObject(
|
||||
currentUriToken, currentField.getType());
|
||||
if (obj instanceof Map) {
|
||||
((Map<String, Object>) obj).put(currentField.getName(),
|
||||
property);
|
||||
} else {
|
||||
try {
|
||||
PropertyUtils.setProperty(obj,
|
||||
currentField.getName(), property);
|
||||
} catch (Throwable e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the name of the field represented by the specified index in the
|
||||
* dataURI. The index starts at the dataTime in the dataURI and does not
|
||||
* include the plugin name.
|
||||
*
|
||||
* @param clazz
|
||||
* The class of the object to examine
|
||||
* @param targetIndex
|
||||
* The index in the dataURI
|
||||
* @return The name of the field at the specified dataURI index
|
||||
*/
|
||||
public static String getDataURIFieldName(Class<?> clazz, int targetIndex) {
|
||||
return getDataURIFieldName(targetIndex, new int[] { 0 }, clazz, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive method to get the dataURI field name
|
||||
*
|
||||
* @param targetIndex
|
||||
* The index in the DataURI to get the field name for
|
||||
* @param index
|
||||
* The current index being examined. This field is necessary for
|
||||
* recursive calls
|
||||
* @param clazz
|
||||
* The class being examined
|
||||
* @param fieldName
|
||||
* The current field name. This field is necessary for recursive
|
||||
* calls. If the dataURI is specified in an embedded object, this
|
||||
* field will take the form class1.class2.field i.e. for a grib
|
||||
* record this could be modelInfo.modelName
|
||||
* @return The fieldName
|
||||
*/
|
||||
private static String getDataURIFieldName(int targetIndex, int[] index,
|
||||
Class<?> clazz, String fieldName) {
|
||||
// Get the fields annotated with the @DataURI annotation
|
||||
Field[] dataURIFields = DataURIUtil.getInstance().getDataURIFields(
|
||||
clazz);
|
||||
|
||||
for (Field field : dataURIFields) {
|
||||
|
||||
DataURI uriAnnotation = field.getAnnotation(DataURI.class);
|
||||
if (uriAnnotation != null) {
|
||||
if (uriAnnotation.embedded()) {
|
||||
String tmp = getDataURIFieldName(targetIndex, index,
|
||||
field.getType(), fieldName + field.getName() + ".");
|
||||
if (tmp != null) {
|
||||
return tmp;
|
||||
}
|
||||
} else {
|
||||
if (index[0] == targetIndex) {
|
||||
fieldName += field.getName();
|
||||
return fieldName;
|
||||
} else {
|
||||
index[0]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value in the dataURI at the specified index
|
||||
*
|
||||
* @param index
|
||||
* The index in the dataURI for which to get the value
|
||||
* @param fieldName
|
||||
* The name of the field
|
||||
* @return The value in the dataURI at the specified index
|
||||
* @throws Exception
|
||||
*/
|
||||
public Object getDataURIFieldValue(int index, String fieldName)
|
||||
throws Exception {
|
||||
return getDataURIFieldValue(index, new int[] { 0 }, this.getClass(),
|
||||
fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper method to get a dataURI field value
|
||||
*
|
||||
* @param targetIndex
|
||||
* The index in the dataURI for which to get the value
|
||||
* @param index
|
||||
* The current index in the dataURI being examined
|
||||
* @param clazz
|
||||
* The class to be examined
|
||||
* @param fieldName
|
||||
* The name of the field
|
||||
* @return The value in the dataURI at the specified index
|
||||
* @throws Exception
|
||||
*/
|
||||
private Object getDataURIFieldValue(int targetIndex, int[] index,
|
||||
Class<?> clazz, String fieldName) throws Exception {
|
||||
// Get the fields annotated with the @DataURI annotation
|
||||
Field[] dataURIFields = DataURIUtil.getInstance().getDataURIFields(
|
||||
clazz);
|
||||
|
||||
for (Field field : dataURIFields) {
|
||||
DataURI uriAnnotation = field.getAnnotation(DataURI.class);
|
||||
if (uriAnnotation != null) {
|
||||
if (uriAnnotation.embedded()) {
|
||||
Object tmp = getDataURIFieldValue(targetIndex, index,
|
||||
field.getType(), fieldName);
|
||||
if (tmp != null) {
|
||||
return tmp;
|
||||
}
|
||||
} else {
|
||||
if (index[0] == targetIndex) {
|
||||
return ConvertUtil.convertObject(fieldName,
|
||||
field.getType());
|
||||
} else {
|
||||
index[0]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public DataTime getDataTime() {
|
||||
return dataTime;
|
||||
}
|
||||
|
||||
public String getDataURI() {
|
||||
if (dataURI == null && pluginName != null) {
|
||||
StringBuilder uriBuffer = new StringBuilder(160);
|
||||
uriBuffer.append(DataURI.SEPARATOR).append(pluginName);
|
||||
generateURI(this, uriBuffer);
|
||||
this.dataURI = uriBuffer.toString().replaceAll(" ", "_");
|
||||
try {
|
||||
this.dataURI = DataURIUtil.createDataURI(this);
|
||||
} catch (PluginException e) {
|
||||
// this should never happen operationally
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
return this.dataURI;
|
||||
}
|
||||
|
|
|
@ -23,14 +23,22 @@ package com.raytheon.uf.common.dataplugin.annotations;
|
|||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.beanutils.PropertyUtils;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.IPluginClassMapper;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.ConvertUtil;
|
||||
|
||||
/**
|
||||
* Utility class for working with dataURIs
|
||||
|
@ -45,6 +53,7 @@ import com.raytheon.uf.common.dataplugin.PluginException;
|
|||
* Apr 18, 2013 1638 mschenke Moved dataURI map generation into here
|
||||
* from PluginDataObject
|
||||
* May 15, 2013 1869 bsteffen Move uri map creation from RecordFactory.
|
||||
* May 16, 2013 1869 bsteffen Rewrite dataURI property mappings.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -53,34 +62,208 @@ import com.raytheon.uf.common.dataplugin.PluginException;
|
|||
*/
|
||||
public class DataURIUtil {
|
||||
|
||||
/** The singleton instance */
|
||||
private static DataURIUtil instance;
|
||||
private static final String PLUGIN_NAME_KEY = "pluginName";
|
||||
|
||||
/** Map of classes and the DataURI annotated fields */
|
||||
private Map<Class<?>, Field[]> uriFieldMap;
|
||||
private static final Pattern SEPARATOR_PATTERN = Pattern
|
||||
.compile(DataURI.SEPARATOR);
|
||||
|
||||
/**
|
||||
* Constructs the singleton instance
|
||||
private static final Pattern UNDERSCORE_PATTERN = Pattern.compile("_");
|
||||
|
||||
private static final Pattern SPACE_PATTERN = Pattern.compile(" ");
|
||||
|
||||
/*
|
||||
* Compares two fields with the DataURI annotations based off the position.
|
||||
*/
|
||||
private DataURIUtil() {
|
||||
uriFieldMap = new HashMap<Class<?>, Field[]>();
|
||||
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[]>();
|
||||
|
||||
/**
|
||||
* Gets the singleton instance
|
||||
* The classMapper needs to be injected to allow this class to create new
|
||||
* PDOs based off the pluginName in a dataURI or map.
|
||||
*
|
||||
* @return The singleton instance
|
||||
* @param classMapper
|
||||
*/
|
||||
public synchronized static DataURIUtil getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new DataURIUtil();
|
||||
}
|
||||
return instance;
|
||||
public static void setClassMapper(IPluginClassMapper classMapper) {
|
||||
DataURIUtil.classMapper = classMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DataURI map for the specified object based on {@link DataURI}
|
||||
* annotations
|
||||
* Build a new dataURI based off the dataURI fields in the PluginDataObject.
|
||||
*
|
||||
* @param pdo
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static String createDataURI(PluginDataObject pdo)
|
||||
throws PluginException {
|
||||
StringBuilder uri = new StringBuilder(160);
|
||||
addToDataURI(uri, pdo.getPluginName());
|
||||
for (DataURIFieldAccess access : getAccess(pdo.getClass())) {
|
||||
addToDataURI(uri, access.getFieldValue(pdo));
|
||||
}
|
||||
return SPACE_PATTERN.matcher(uri).replaceAll("_");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dataURI based off the dataURI fields in the dataMap.
|
||||
*
|
||||
* @param dataMap
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static String createDataURI(Map<String, Object> dataMap)
|
||||
throws PluginException {
|
||||
String pluginName = dataMap.get(PLUGIN_NAME_KEY).toString();
|
||||
StringBuilder uri = new StringBuilder(160);
|
||||
addToDataURI(uri, pluginName);
|
||||
for (DataURIFieldAccess access : getAccess(pluginName)) {
|
||||
addToDataURI(uri, dataMap.get(access.getFieldName()));
|
||||
}
|
||||
return SPACE_PATTERN.matcher(uri).replaceAll("_");
|
||||
}
|
||||
|
||||
/*
|
||||
* Properly formats an arbitrary object into a dataURI.
|
||||
*/
|
||||
private static void addToDataURI(StringBuilder uri, Object property) {
|
||||
uri.append("/");
|
||||
if (property == null) {
|
||||
uri.append("null");
|
||||
} else if (property instanceof Calendar) {
|
||||
uri.append(TimeUtil.formatCalendar((Calendar) property));
|
||||
} else {
|
||||
uri.append(SEPARATOR_PATTERN.matcher(String.valueOf(property))
|
||||
.replaceAll("_"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a dataURI and set the dataURIFields into a dataMap
|
||||
*
|
||||
* @param dataURI
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static Map<String, Object> createDataURIMap(String dataURI)
|
||||
throws PluginException {
|
||||
List<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());
|
||||
dataMap.put(PLUGIN_NAME_KEY, pluginName);
|
||||
DataURIFieldAccess[] access = getAccess(pluginName);
|
||||
for (int i = 0; i < access.length; i += 1) {
|
||||
dataMap.put(access[i].getFieldName(),
|
||||
access[i].getFieldValue(tokens.get(i)));
|
||||
}
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate a dataMap based off the dataURI fields in the PluginDataObject.
|
||||
*
|
||||
* @param pdo
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static Map<String, Object> createDataURIMap(PluginDataObject pdo)
|
||||
throws PluginException {
|
||||
return createDataURIMap((Object) pdo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* present in the DataURI are set into the PDO.
|
||||
*
|
||||
* @param dataURI
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static PluginDataObject createPluginDataObject(String dataURI)
|
||||
throws PluginException {
|
||||
PluginDataObject pdo = null;
|
||||
List<String> tokens = tokenizeURI(dataURI);
|
||||
Class<PluginDataObject> clazz = getPluginRecordClass(tokens.get(0));
|
||||
try {
|
||||
pdo = clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new PluginException(e);
|
||||
}
|
||||
populatePluginDataObject(pdo, tokens);
|
||||
pdo.setDataURI(dataURI);
|
||||
return pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new PluginDataObject based off the dataMap. The class of the
|
||||
* result object is based off the pluginName mapping and all dataURI fields
|
||||
* present in the map are set into the PDO.
|
||||
*
|
||||
* @param dataMap
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static PluginDataObject createPluginDataObject(
|
||||
Map<String, Object> dataMap) throws PluginException {
|
||||
PluginDataObject pdo = null;
|
||||
Class<PluginDataObject> clazz = getPluginRecordClass(dataMap.get(
|
||||
PLUGIN_NAME_KEY).toString());
|
||||
try {
|
||||
pdo = clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new PluginException(e);
|
||||
}
|
||||
populatePluginDataObject(pdo, dataMap);
|
||||
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 {
|
||||
pdo.setPluginName(dataMap.get(PLUGIN_NAME_KEY).toString());
|
||||
populateObject(pdo, dataMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate an existing PluginDataObject using fields parsed from the
|
||||
* dataURI.
|
||||
*
|
||||
* @param pdo
|
||||
* @param dataURI
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static void populatePluginDataObject(PluginDataObject pdo,
|
||||
String dataURI) throws PluginException {
|
||||
populatePluginDataObject(pdo, tokenizeURI(dataURI));
|
||||
pdo.setDataURI(dataURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dataURIMap from any object with dataURI annotations.
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
|
@ -88,110 +271,208 @@ public class DataURIUtil {
|
|||
*/
|
||||
public static Map<String, Object> createDataURIMap(Object object)
|
||||
throws PluginException {
|
||||
try {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
Field[] fields = DataURIUtil.getInstance().getAllDataURIFields(
|
||||
object.getClass());
|
||||
for (int i = 0; i < fields.length; ++i) {
|
||||
String fieldName = PluginDataObject.getDataURIFieldName(
|
||||
object.getClass(), i);
|
||||
String[] nested = fieldName.split("[.]");
|
||||
Object source = object;
|
||||
if (nested.length > 0) {
|
||||
for (int j = 0; j < nested.length && source != null; ++j) {
|
||||
source = PropertyUtils.getProperty(source, nested[j]);
|
||||
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());
|
||||
}
|
||||
map.put(fieldName, source);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
} catch (Exception e) {
|
||||
throw new PluginException("Error constructing dataURI mapping", e);
|
||||
for (DataURIFieldAccess access : accessArray) {
|
||||
dataMap.put(access.getFieldName(), access.getFieldValue(object));
|
||||
}
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
public static Map<String, Object> createDataURIMap(String dataURI, Class<PluginDataObject> clazz)
|
||||
/**
|
||||
* Populate an existing object from the dataURI fields in dataMap.
|
||||
*
|
||||
* @param object
|
||||
* @param dataMap
|
||||
* @throws PluginException
|
||||
*/
|
||||
public static void populateObject(Object object, Map<String, Object> dataMap)
|
||||
throws PluginException {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
String[] tokens = dataURI.replaceAll("_", " ").split(DataURI.SEPARATOR);
|
||||
|
||||
map.put("pluginName", tokens[1]);
|
||||
PluginDataObject obj = null;
|
||||
try {
|
||||
obj = clazz.newInstance();
|
||||
|
||||
for (int i = 2; i < tokens.length; i++) {
|
||||
String fieldName = PluginDataObject.getDataURIFieldName(
|
||||
obj.getClass(), i - 2);
|
||||
if (fieldName == null) {
|
||||
continue;
|
||||
for (DataURIFieldAccess access : getAccess(object.getClass())) {
|
||||
access.setFieldValue(object, dataMap.get(access.getFieldName()));
|
||||
}
|
||||
Object value = obj.getDataURIFieldValue(i - 2, tokens[i]);
|
||||
map.put(fieldName, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new PluginException("Error constructing dataURI mapping", e);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public Field[] getAllDataURIFields(Class<?> obj) {
|
||||
List<Field> fields = new ArrayList<Field>();
|
||||
getAllDataURIFields(obj, fields);
|
||||
return fields.toArray(new Field[0]);
|
||||
/*
|
||||
* Populate a PDO with the tokens from a parsed DataURI
|
||||
*/
|
||||
private static void populatePluginDataObject(PluginDataObject pdo,
|
||||
List<String> uriTokens) throws PluginException {
|
||||
pdo.setPluginName(uriTokens.get(0));
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
private void getAllDataURIFields(Class<?> obj, List<Field> fields) {
|
||||
for (Field field : getDataURIFields(obj)) {
|
||||
/*
|
||||
* Split a URI on the seperator and remove empty first element.
|
||||
*/
|
||||
private static List<String> tokenizeURI(String dataURI) {
|
||||
dataURI = UNDERSCORE_PATTERN.matcher(dataURI).replaceAll(" ");
|
||||
String[] tokens = SEPARATOR_PATTERN.split(dataURI);
|
||||
return Arrays.asList(tokens).subList(1, tokens.length);
|
||||
}
|
||||
|
||||
private static DataURIFieldAccess[] getAccess(String pluginName)
|
||||
throws PluginException {
|
||||
return getAccess(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);
|
||||
}
|
||||
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()) {
|
||||
getAllDataURIFields(field.getType(), fields);
|
||||
accessors.addAll(getAccess(type, names));
|
||||
} else {
|
||||
accessors.add(new DataURIFieldAccess(names, type));
|
||||
}
|
||||
}
|
||||
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)
|
||||
throws PluginException {
|
||||
if (classMapper == null) {
|
||||
throw new PluginException(
|
||||
"No PluginClassMapper is registered with DataURIUtil.");
|
||||
}
|
||||
return classMapper.getPluginRecordClass(pluginName);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class which remembers the fieldNames and class of a dataURI field to make
|
||||
* parsing faster.
|
||||
*/
|
||||
private static class DataURIFieldAccess {
|
||||
|
||||
/**
|
||||
* List of fieldNames, used for finding objects in a PDO, for example
|
||||
* {"location", "longitude"}
|
||||
*/
|
||||
private final String[] fieldNames;
|
||||
|
||||
/**
|
||||
* Compiled field names, used as map keys, for example
|
||||
* "location.longitude"
|
||||
*/
|
||||
private final String fieldName;
|
||||
|
||||
/**
|
||||
* Class of the oibject that is in the dataURI.
|
||||
*/
|
||||
private final Class<?> fieldClass;
|
||||
|
||||
public DataURIFieldAccess(List<String> fieldNames, Class<?> fieldClass) {
|
||||
this.fieldNames = fieldNames.toArray(new String[0]);
|
||||
StringBuilder fieldName = new StringBuilder(this.fieldNames[0]);
|
||||
for (int i = 1; i < this.fieldNames.length; i += 1) {
|
||||
fieldName.append(".").append(this.fieldNames[i]);
|
||||
}
|
||||
this.fieldName = fieldName.toString();
|
||||
this.fieldClass = fieldClass;
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the field value from a PDO.
|
||||
*
|
||||
* @param pdo
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public Object getFieldValue(Object pdo) throws PluginException {
|
||||
try {
|
||||
Object object = pdo;
|
||||
for (String fieldName : fieldNames) {
|
||||
object = PropertyUtils.getProperty(object, fieldName);
|
||||
if (object == null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return object;
|
||||
} catch (Exception e) {
|
||||
throw new PluginException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an ordered listing of all fields annotated as DataURI fields.
|
||||
* Convert the provided string into the correct type for the field.
|
||||
*
|
||||
* @param obj
|
||||
* The object to examine
|
||||
* @return The ordered array of all fields annotated as DataURI fields
|
||||
* @param stringValue
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
public Field[] getDataURIFields(Class<?> obj) {
|
||||
|
||||
// Check map first
|
||||
if (uriFieldMap.containsKey(obj)) {
|
||||
return uriFieldMap.get(obj);
|
||||
public Object getFieldValue(String stringValue) throws PluginException {
|
||||
return ConvertUtil.convertObject(stringValue, fieldClass);
|
||||
}
|
||||
|
||||
// Iterate through the class hierarchy
|
||||
List<Field> fields = new ArrayList<Field>();
|
||||
Class<?> currentClass = obj;
|
||||
while (currentClass != null) {
|
||||
fields.addAll(Arrays.asList(currentClass.getDeclaredFields()));
|
||||
currentClass = currentClass.getSuperclass();
|
||||
/**
|
||||
* Set the fieldValue into the PDO.
|
||||
*
|
||||
* @param pdo
|
||||
* @param fieldValue
|
||||
* @throws PluginException
|
||||
*/
|
||||
public void setFieldValue(Object pdo, Object fieldValue)
|
||||
throws PluginException {
|
||||
Object source = pdo;
|
||||
try {
|
||||
for (int i = 0; i < fieldNames.length - 1; i += 1) {
|
||||
Object obj = PropertyUtils.getProperty(source,
|
||||
fieldNames[i]);
|
||||
if (obj == null) {
|
||||
obj = PropertyUtils.getPropertyType(source,
|
||||
fieldNames[i]).newInstance();
|
||||
PropertyUtils.setProperty(source, fieldNames[i], obj);
|
||||
}
|
||||
|
||||
// Count the fields annotated with the DataURI annotation
|
||||
int fieldCount = 0;
|
||||
for (Field field : fields) {
|
||||
if (field.getAnnotation(DataURI.class) != null) {
|
||||
fieldCount++;
|
||||
source = obj;
|
||||
}
|
||||
PropertyUtils.setProperty(source,
|
||||
fieldNames[fieldNames.length - 1], fieldValue);
|
||||
} catch (Exception e) {
|
||||
throw new PluginException(e);
|
||||
}
|
||||
}
|
||||
// Sort the annotations into an array
|
||||
Field[] annotatedFields = new Field[fieldCount];
|
||||
for (Field field : fields) {
|
||||
DataURI annotation = field.getAnnotation(DataURI.class);
|
||||
if (annotation != null) {
|
||||
annotatedFields[annotation.position()] = field;
|
||||
}
|
||||
}
|
||||
|
||||
// Put fields in map and return
|
||||
uriFieldMap.put(obj, annotatedFields);
|
||||
return annotatedFields;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,4 +46,17 @@
|
|||
<constructor-arg ref="timeQueryHandlerSet"/>
|
||||
</bean>
|
||||
|
||||
<bean id="pluginFactory" class="com.raytheon.uf.edex.database.plugin.PluginFactory" factory-method="getInstance"/>
|
||||
|
||||
<bean id="pluginFactoryRegisteredToDataURIUtil"
|
||||
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
|
||||
<property name="targetClass">
|
||||
<value>com.raytheon.uf.common.dataplugin.annotations.DataURIUtil</value>
|
||||
</property>
|
||||
<property name="targetMethod">
|
||||
<value>setClassMapper</value>
|
||||
</property>
|
||||
<property name="arguments" ref="pluginFactory" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -50,6 +50,7 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
|||
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURIUtil;
|
||||
import com.raytheon.uf.common.dataplugin.persist.DefaultPathProvider;
|
||||
import com.raytheon.uf.common.dataplugin.persist.IHDFFilePathProvider;
|
||||
import com.raytheon.uf.common.dataplugin.persist.IPersistable;
|
||||
|
@ -93,20 +94,23 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
|||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 2/6/09 1990 bphillip Initial creation
|
||||
* 6/29/12 #828 dgilling Force getPurgeRulesForPlugin()
|
||||
* to search only COMMON_STATIC.
|
||||
* Feb 06, 2009 1990 bphillip Initial creation
|
||||
* Jun 29, 2012 828 dgilling Force getPurgeRulesForPlugin() to search
|
||||
* only COMMON_STATIC.
|
||||
* Oct 10, 2012 1261 djohnson Add some generics wildcarding.
|
||||
* Jan 14, 2013 1469 bkowal No longer retrieves the hdf5 data directory
|
||||
* from the environment.
|
||||
* Feb 12, 2013 #1608 randerso Changed to call deleteDatasets
|
||||
* Feb 26, 2013 1638 mschenke Moved OGC specific functions to OGC project
|
||||
* Jan 14, 2013 1469 bkowal No longer retrieves the hdf5 data
|
||||
* directory from the environment.
|
||||
* Feb 12, 2013 1608 randerso Changed to call deleteDatasets
|
||||
* Feb 26, 2013 1638 mschenke Moved OGC specific functions to OGC
|
||||
* project
|
||||
* Mar 27, 2013 1821 bsteffen Remove extra store in persistToHDF5 for
|
||||
* replace only operations.
|
||||
* Apr 04, 2013 djohnson Remove formerly removed methods that won't compile.
|
||||
* Apr 04, 2013 djohnson Remove formerly removed methods that
|
||||
* won't compile.
|
||||
* Apr 15, 2013 1868 bsteffen Rewrite mergeAll in PluginDao.
|
||||
* May 07, 2013 1869 bsteffen Remove dataURI column from
|
||||
* PluginDataObject.
|
||||
* May 16, 2013 1869 bsteffen Rewrite dataURI property mappings.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -365,7 +369,8 @@ public abstract class PluginDao extends CoreDao {
|
|||
}
|
||||
}
|
||||
// This means dataURI is not a column.
|
||||
for (Entry<String, Object> uriEntry : pdo.createDataURIMap().entrySet()) {
|
||||
for (Entry<String, Object> uriEntry : DataURIUtil.createDataURIMap(pdo)
|
||||
.entrySet()) {
|
||||
String key = uriEntry.getKey();
|
||||
Object value = uriEntry.getValue();
|
||||
if (key.equals("pluginName")) {
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.persistence.Table;
|
|||
|
||||
import org.apache.commons.beanutils.ConstructorUtils;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.IPluginClassMapper;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginProperties;
|
||||
|
@ -44,17 +45,18 @@ import com.raytheon.uf.edex.core.dataplugin.PluginRegistry;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 06/14/06 garmendariz Initial check-in
|
||||
* 05/29/07 312 bphillip Removed unused methods
|
||||
* 02/06/09 1990 bphillip Refactored to use spring container
|
||||
* 03/20/09 njensen Refactored to use PluginProperties
|
||||
* Jun 14, 2006 garmendariz Initial check-in
|
||||
* May 29, 2007 312 bphillip Removed unused methods
|
||||
* Feb 06, 2009 1990 bphillip Refactored to use spring container
|
||||
* Mar 20, 2009 njensen Refactored to use PluginProperties
|
||||
* May 16, 2013 1869 bsteffen Rewrite dataURI property mappings.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author garmendariz
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PluginFactory {
|
||||
public class PluginFactory implements IPluginClassMapper {
|
||||
|
||||
/** The instance of the PluginFactory class */
|
||||
private static final PluginFactory instance = new PluginFactory();
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.util.Map.Entry;
|
|||
import java.util.Scanner;
|
||||
|
||||
import com.raytheon.edex.site.SiteUtil;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURIUtil;
|
||||
import com.raytheon.uf.common.dataplugin.fssobs.FSSObsRecord;
|
||||
|
@ -40,7 +39,6 @@ import com.raytheon.uf.common.pointdata.PointDataContainer;
|
|||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.edex.database.plugin.PluginFactory;
|
||||
import com.raytheon.uf.edex.pointdata.PointDataQuery;
|
||||
|
||||
/**
|
||||
|
@ -55,6 +53,7 @@ import com.raytheon.uf.edex.pointdata.PointDataQuery;
|
|||
* Nov 12, 2010 skorolev Initial creation
|
||||
* Nov 26, 2012 1297 skorolev Changed ArrayList to List.Clean code
|
||||
* May 15, 2013 1869 bsteffen Remove DataURI column from ldadmesonet.
|
||||
* May 16, 2013 1869 bsteffen Rewrite dataURI property mappings.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -198,11 +197,8 @@ public class FSSObsUtils {
|
|||
PointDataQuery request = null;
|
||||
PointDataContainer result = null;
|
||||
try {
|
||||
Class<PluginDataObject> clazz = PluginFactory.getInstance()
|
||||
.getPluginRecordClass(plgn.ldadmesonet.toString());
|
||||
Map<String, RequestConstraint> rcMap = RequestConstraint
|
||||
.toConstraintMapping(DataURIUtil.createDataURIMap(uri,
|
||||
clazz));
|
||||
.toConstraintMapping(DataURIUtil.createDataURIMap(uri));
|
||||
// Not actually in db
|
||||
rcMap.remove("pluginName");
|
||||
request = new PointDataQuery(plgn.ldadmesonet.toString());
|
||||
|
|
|
@ -20,19 +20,13 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.raytheon.edex.uengine.tasks.query.MetadataCatalogQuery;
|
||||
import com.raytheon.edex.uengine.tasks.query.TableQuery;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.PluginProperties;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURIUtil;
|
||||
import com.raytheon.uf.common.dataplugin.message.DataURINotificationMessage;
|
||||
import com.raytheon.uf.common.dataplugin.radar.RadarRecord;
|
||||
import com.raytheon.uf.edex.core.dataplugin.PluginRegistry;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
import com.raytheon.uf.edex.database.status.StatusConstants;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -42,6 +36,7 @@ import com.raytheon.uf.edex.database.status.StatusConstants;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 02/20/12 #606 Greg Hull Created
|
||||
* May 16, 2013 1869 bsteffen Rewrite dataURI property mappings.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -84,34 +79,7 @@ public class NcInventoryUpdater {
|
|||
PluginDataObject pdo = null;
|
||||
|
||||
try {
|
||||
PluginRegistry reg = PluginRegistry.getInstance();
|
||||
PluginProperties props = reg.getRegisteredObject(pluginName);
|
||||
|
||||
if( props != null && props.getRecord() != null) {
|
||||
pdo = props.getRecord().newInstance();
|
||||
}
|
||||
|
||||
if( pdo == null ) {
|
||||
throw new Exception( "Can't find PDO for plugin.");
|
||||
}
|
||||
|
||||
for( int i=2 ; i < tokens.length ; i++ ) {
|
||||
if( !tokens[i].equals("%") && !tokens[i].trim().isEmpty() ) {
|
||||
String fld = PluginDataObject.getDataURIFieldName( pdo.getClass(), i-2 );
|
||||
|
||||
if( fld == null ) {
|
||||
throw new Exception("Unable to get field name");
|
||||
}
|
||||
|
||||
Object value = pdo.getDataURIFieldValue( i-2, tokens[i] );
|
||||
|
||||
attrsMap.put( fld, value );
|
||||
}
|
||||
else if( tokens[i].equals("%") ) {
|
||||
String fld = PluginDataObject.getDataURIFieldName( pdo.getClass(), i-2 );
|
||||
attrsMap.put( fld, "%");
|
||||
}
|
||||
}
|
||||
attrsMap.putAll(DataURIUtil.createDataURIMap(dataURI));
|
||||
|
||||
attrsMap.put( "dataURI", dataURI );
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue