/jdbo/src/main/java/org/openlogics/jdbo/Features.java
Java | 209 lines | 137 code | 30 blank | 42 comment | 28 complexity | edf4cadea35f9978708c8d0cd4d50b7d MD5 | raw file
- package org.openlogics.jdbo;
- import org.geotools.data.FeatureSource;
- import org.geotools.data.simple.SimpleFeatureStore;
- import org.geotools.factory.Hints;
- import org.geotools.feature.NameImpl;
- import org.geotools.feature.simple.SimpleFeatureBuilder;
- import org.geotools.jdbc.PrimaryKey;
- import org.geotools.jdbc.PrimaryKeyColumn;
- import org.geotools.util.Converters;
- import org.opengis.feature.simple.SimpleFeature;
- import org.opengis.feature.simple.SimpleFeatureType;
- import org.opengis.feature.type.Name;
- import org.openlogics.utils.reflect.Reflections;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.persistence.Column;
- import javax.persistence.GeneratedValue;
- import javax.persistence.GenerationType;
- import javax.persistence.Id;
- import java.beans.IntrospectionException;
- import java.io.UnsupportedEncodingException;
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.net.URLDecoder;
- import java.util.ArrayList;
- import java.util.List;
- import static com.google.common.base.Strings.isNullOrEmpty;
- import static org.openlogics.utils.reflect.Reflections.getGetterMethod;
- /**
- * @author Miguel Vega
- * @version $Id: Features.java 0, 2013-07-05 10:16 AM mvega $
- */
- public class Features {
- final static Logger logger = LoggerFactory.getLogger(Features.class);
- /**
- * Converts an object well formed with javax persistence API into a Simple feature
- *
- * @param featureType
- * @param context
- * @return
- */
- public static <U> SimpleFeature objectToSimpleFeature(SimpleFeatureType featureType, U context) {
- SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
- Iterable<Field> fields = Reflections.getDeclaredFields(context.getClass());
- String fidValue = null;
- for (Field field : fields) {
- Column column;
- //todo, need to cache the following operations, to avoid inspect the class every time
- Name attrName;
- if ((column = field.getAnnotation(Column.class)) == null) {
- continue;
- }
- if (!isNullOrEmpty(column.name())) {
- attrName = new NameImpl(column.name());
- } else {
- attrName = new NameImpl(field.getName());
- }
- Method method = null;
- try {
- method = getGetterMethod(field.getName(), context.getClass());
- Object value = method.invoke(context);
- if (field.getAnnotation(Id.class) != null) {
- GeneratedValue genVal;
- if ((genVal = field.getAnnotation(GeneratedValue.class)) != null) {
- GenerationType strategy = genVal.strategy();
- switch (strategy) {
- case SEQUENCE:
- //todo, need to do something??
- break;
- case AUTO:
- //todo, need to do something??
- break;
- case TABLE:
- //todo, need to do something??
- break;
- case IDENTITY:
- //todo, need to do something??
- break;
- default:
- fidValue = String.valueOf(value);
- }
- } else {
- //if attribute is not annotated with GeneratedValue strategy, then simply use the value in attribute
- fidValue = String.valueOf(value);
- }
- } else {
- featureBuilder.set(attrName, value);
- }
- } catch (IntrospectionException e) {
- logger.debug("Unable to invoke method " + method.getName(), e);
- } catch (InvocationTargetException e) {
- logger.debug("Unable to invoke method " + method.getName(), e);
- } catch (IllegalAccessException e) {
- logger.debug("Unable to invoke method " + method.getName(), e);
- }
- }
- if (!isNullOrEmpty(fidValue)) {
- //to enable the insertion of custom values in PK columns (FID)
- featureBuilder.featureUserData(Hints.USE_PROVIDED_FID, Boolean.TRUE);
- }
- return featureBuilder.buildFeature(fidValue);
- }
- /**
- * Check if a FeatureSource object is write enabled
- *
- * @param source
- * @return
- */
- public static boolean isWriteEnabled(FeatureSource<SimpleFeatureType, SimpleFeature> source) {
- if (source instanceof SimpleFeatureStore) {
- // you have write access
- //SimpleFeatureStore store = (SimpleFeatureStore) source;
- return true;
- } else {
- // read-only
- return false;
- }
- }
- /**
- * <code>Copied from {@link org.geotools.jdbc.JDBCDataStore}</code>
- * Decodes a fid into its components based on a primary key.
- *
- * @param strict If set to true the value of the fid will be validated against
- * the type of the key columns. If a conversion can not be made, an exception will be thrown.
- */
- public static List<Object> decodeFID(PrimaryKey key, String FID, boolean strict, FIDDecoderVisitor decoderVisitor) {
- //strip off the feature type name
- if (FID.startsWith(key.getTableName() + ".")) {
- FID = FID.substring(key.getTableName().length() + 1);
- }
- try {
- FID = URLDecoder.decode(FID, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
- //check for case of multi column primary key and try to backwards map using
- // "." as a seperator of values
- List values;
- if (key.getColumns().size() > 1) {
- String[] split = FID.split("\\.");
- //copy over to avoid array store exception
- values = new ArrayList(split.length);
- for (int i = 0; i < split.length; i++) {
- values.add(split[i]);
- }
- } else {
- //single value case
- values = new ArrayList();
- values.add(FID);
- }
- if (values.size() != key.getColumns().size()) {
- throw new IllegalArgumentException("Illegal fid: " + FID + ". Expected "
- + key.getColumns().size() + " values but got " + values.size());
- }
- //convert to the type of the key
- //JD: usually this would be done by the dialect directly when the value
- // actually gets set but the FIDMapper interface does not report types
- for (int i = 0; i < values.size(); i++) {
- PrimaryKeyColumn pkCol = key.getColumns().get(i);
- Object value = values.get(i);
- if (value != null) {
- Class type = key.getColumns().get(i).getType();
- Object converted = Converters.convert(value, type);
- if (converted != null) {
- values.set(i, converted);
- }
- if (strict && !type.isInstance(values.get(i))) {
- throw new IllegalArgumentException("Value " + values.get(i) + " illegal for type " + type.getName());
- }
- decoderVisitor.visit(pkCol, converted);
- }
- }
- return values;
- }
- public static interface FIDDecoderVisitor {
- void visit(PrimaryKeyColumn pkColumn, Object decoded);
- }
- }