PageRenderTime 232ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/jdbo/src/main/java/org/openlogics/jdbo/Features.java

https://bitbucket.org/miguelvega/openapi
Java | 209 lines | 137 code | 30 blank | 42 comment | 28 complexity | edf4cadea35f9978708c8d0cd4d50b7d MD5 | raw file
  1. package org.openlogics.jdbo;
  2. import org.geotools.data.FeatureSource;
  3. import org.geotools.data.simple.SimpleFeatureStore;
  4. import org.geotools.factory.Hints;
  5. import org.geotools.feature.NameImpl;
  6. import org.geotools.feature.simple.SimpleFeatureBuilder;
  7. import org.geotools.jdbc.PrimaryKey;
  8. import org.geotools.jdbc.PrimaryKeyColumn;
  9. import org.geotools.util.Converters;
  10. import org.opengis.feature.simple.SimpleFeature;
  11. import org.opengis.feature.simple.SimpleFeatureType;
  12. import org.opengis.feature.type.Name;
  13. import org.openlogics.utils.reflect.Reflections;
  14. import org.slf4j.Logger;
  15. import org.slf4j.LoggerFactory;
  16. import javax.persistence.Column;
  17. import javax.persistence.GeneratedValue;
  18. import javax.persistence.GenerationType;
  19. import javax.persistence.Id;
  20. import java.beans.IntrospectionException;
  21. import java.io.UnsupportedEncodingException;
  22. import java.lang.reflect.Field;
  23. import java.lang.reflect.InvocationTargetException;
  24. import java.lang.reflect.Method;
  25. import java.net.URLDecoder;
  26. import java.util.ArrayList;
  27. import java.util.List;
  28. import static com.google.common.base.Strings.isNullOrEmpty;
  29. import static org.openlogics.utils.reflect.Reflections.getGetterMethod;
  30. /**
  31. * @author Miguel Vega
  32. * @version $Id: Features.java 0, 2013-07-05 10:16 AM mvega $
  33. */
  34. public class Features {
  35. final static Logger logger = LoggerFactory.getLogger(Features.class);
  36. /**
  37. * Converts an object well formed with javax persistence API into a Simple feature
  38. *
  39. * @param featureType
  40. * @param context
  41. * @return
  42. */
  43. public static <U> SimpleFeature objectToSimpleFeature(SimpleFeatureType featureType, U context) {
  44. SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
  45. Iterable<Field> fields = Reflections.getDeclaredFields(context.getClass());
  46. String fidValue = null;
  47. for (Field field : fields) {
  48. Column column;
  49. //todo, need to cache the following operations, to avoid inspect the class every time
  50. Name attrName;
  51. if ((column = field.getAnnotation(Column.class)) == null) {
  52. continue;
  53. }
  54. if (!isNullOrEmpty(column.name())) {
  55. attrName = new NameImpl(column.name());
  56. } else {
  57. attrName = new NameImpl(field.getName());
  58. }
  59. Method method = null;
  60. try {
  61. method = getGetterMethod(field.getName(), context.getClass());
  62. Object value = method.invoke(context);
  63. if (field.getAnnotation(Id.class) != null) {
  64. GeneratedValue genVal;
  65. if ((genVal = field.getAnnotation(GeneratedValue.class)) != null) {
  66. GenerationType strategy = genVal.strategy();
  67. switch (strategy) {
  68. case SEQUENCE:
  69. //todo, need to do something??
  70. break;
  71. case AUTO:
  72. //todo, need to do something??
  73. break;
  74. case TABLE:
  75. //todo, need to do something??
  76. break;
  77. case IDENTITY:
  78. //todo, need to do something??
  79. break;
  80. default:
  81. fidValue = String.valueOf(value);
  82. }
  83. } else {
  84. //if attribute is not annotated with GeneratedValue strategy, then simply use the value in attribute
  85. fidValue = String.valueOf(value);
  86. }
  87. } else {
  88. featureBuilder.set(attrName, value);
  89. }
  90. } catch (IntrospectionException e) {
  91. logger.debug("Unable to invoke method " + method.getName(), e);
  92. } catch (InvocationTargetException e) {
  93. logger.debug("Unable to invoke method " + method.getName(), e);
  94. } catch (IllegalAccessException e) {
  95. logger.debug("Unable to invoke method " + method.getName(), e);
  96. }
  97. }
  98. if (!isNullOrEmpty(fidValue)) {
  99. //to enable the insertion of custom values in PK columns (FID)
  100. featureBuilder.featureUserData(Hints.USE_PROVIDED_FID, Boolean.TRUE);
  101. }
  102. return featureBuilder.buildFeature(fidValue);
  103. }
  104. /**
  105. * Check if a FeatureSource object is write enabled
  106. *
  107. * @param source
  108. * @return
  109. */
  110. public static boolean isWriteEnabled(FeatureSource<SimpleFeatureType, SimpleFeature> source) {
  111. if (source instanceof SimpleFeatureStore) {
  112. // you have write access
  113. //SimpleFeatureStore store = (SimpleFeatureStore) source;
  114. return true;
  115. } else {
  116. // read-only
  117. return false;
  118. }
  119. }
  120. /**
  121. * <code>Copied from {@link org.geotools.jdbc.JDBCDataStore}</code>
  122. * Decodes a fid into its components based on a primary key.
  123. *
  124. * @param strict If set to true the value of the fid will be validated against
  125. * the type of the key columns. If a conversion can not be made, an exception will be thrown.
  126. */
  127. public static List<Object> decodeFID(PrimaryKey key, String FID, boolean strict, FIDDecoderVisitor decoderVisitor) {
  128. //strip off the feature type name
  129. if (FID.startsWith(key.getTableName() + ".")) {
  130. FID = FID.substring(key.getTableName().length() + 1);
  131. }
  132. try {
  133. FID = URLDecoder.decode(FID, "UTF-8");
  134. } catch (UnsupportedEncodingException e) {
  135. throw new RuntimeException(e);
  136. }
  137. //check for case of multi column primary key and try to backwards map using
  138. // "." as a seperator of values
  139. List values;
  140. if (key.getColumns().size() > 1) {
  141. String[] split = FID.split("\\.");
  142. //copy over to avoid array store exception
  143. values = new ArrayList(split.length);
  144. for (int i = 0; i < split.length; i++) {
  145. values.add(split[i]);
  146. }
  147. } else {
  148. //single value case
  149. values = new ArrayList();
  150. values.add(FID);
  151. }
  152. if (values.size() != key.getColumns().size()) {
  153. throw new IllegalArgumentException("Illegal fid: " + FID + ". Expected "
  154. + key.getColumns().size() + " values but got " + values.size());
  155. }
  156. //convert to the type of the key
  157. //JD: usually this would be done by the dialect directly when the value
  158. // actually gets set but the FIDMapper interface does not report types
  159. for (int i = 0; i < values.size(); i++) {
  160. PrimaryKeyColumn pkCol = key.getColumns().get(i);
  161. Object value = values.get(i);
  162. if (value != null) {
  163. Class type = key.getColumns().get(i).getType();
  164. Object converted = Converters.convert(value, type);
  165. if (converted != null) {
  166. values.set(i, converted);
  167. }
  168. if (strict && !type.isInstance(values.get(i))) {
  169. throw new IllegalArgumentException("Value " + values.get(i) + " illegal for type " + type.getName());
  170. }
  171. decoderVisitor.visit(pkCol, converted);
  172. }
  173. }
  174. return values;
  175. }
  176. public static interface FIDDecoderVisitor {
  177. void visit(PrimaryKeyColumn pkColumn, Object decoded);
  178. }
  179. }