[Schmitzm-commits] r1125 - in trunk: src/schmitzm/geotools/feature src_junit/schmitzm/geotools/feature

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Thu Oct 14 23:02:50 CEST 2010


Author: mojays
Date: 2010-10-14 23:02:49 +0200 (Thu, 14 Oct 2010)
New Revision: 1125

Modified:
   trunk/src/schmitzm/geotools/feature/AttributeModificationRule.java
   trunk/src/schmitzm/geotools/feature/FeatureUtil.java
   trunk/src_junit/schmitzm/geotools/feature/FeatureUtilTest.java
Log:


Modified: trunk/src/schmitzm/geotools/feature/AttributeModificationRule.java
===================================================================
--- trunk/src/schmitzm/geotools/feature/AttributeModificationRule.java	2010-10-14 20:58:06 UTC (rev 1124)
+++ trunk/src/schmitzm/geotools/feature/AttributeModificationRule.java	2010-10-14 21:02:49 UTC (rev 1125)
@@ -4,8 +4,12 @@
 
 import org.geotools.data.FeatureSource;
 import org.geotools.feature.AttributeTypeFactory;
+import org.geotools.feature.GeometryAttributeType;
+import org.geotools.feature.NameImpl;
+import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.type.AttributeDescriptor;
 import org.opengis.feature.type.GeometryDescriptor;
+import org.opengis.feature.type.Name;
 import org.opengis.filter.Filter;
 
 import schmitzm.geotools.FilterUtil;
@@ -24,9 +28,13 @@
   protected String newAttrName;
   /** Holds the new attribute type for the attribute. */
   protected Class<?> newAttrClass;
+  /** Holds the nillable property for the new attribute. */
+  protected Boolean newAttrNillable;
   /** Holds attribute values, which are transformed to NULL in the
    *  modification process. */
   protected Set<Object> nullValues;
+  /** Holds the value used as NULL alias in the modification process. */
+  protected Object nullValueAlias;
   
   /**
    * Creates a new modification definition
@@ -36,14 +44,20 @@
    *                    (if {@code null} the origin attribute name is used)
    * @param newAttrClass new attribute type for the attribute in the destination
    *                    (if {@code null} the origin attribute type is used)
+   * @param newAttrNillable nillable property for the attribute in the destination
+   *                    (if {@code null} the origin nillable property is used)
    * @param nullValues values which are transformed to NULL during the modification
    *                   process (if {@code null} the values are copied unchanged)
+   * @param nullValueAlias value which is used as NULL during the modification
+   *                       process
    */
-  public AttributeModificationRule(int attrIdx, String newAttrName, Class<?> newAttrClass, Set<Object> nullValues) {
+  public AttributeModificationRule(int attrIdx, String newAttrName, Class<?> newAttrClass, Boolean newAttrNillable, Set<Object> nullValues, Object nullValueAlias) {
     this.attrIdx = attrIdx;
     this.newAttrName = newAttrName;
     this.newAttrClass = newAttrClass;
+    this.newAttrNillable = newAttrNillable;
     this.nullValues = nullValues;
+    this.nullValueAlias = nullValueAlias;
   }
   
   /**
@@ -52,7 +66,7 @@
    *                should be transfered to the destination     
    */
   public AttributeModificationRule(int attrIdx) {
-    this(attrIdx,null,null,null);
+    this(attrIdx,null,null,null,null,null);
   }
 
   /**
@@ -96,6 +110,24 @@
   }
   
   /**
+   * Returns whether the attribute in the destination {@link FeatureSource} will
+   * be nillable.
+   * @return {@code null} if the origin nillable property is used
+   */
+  public Boolean getNewAttrNillable() {
+    return newAttrNillable;
+  }
+  
+  /**
+   * Sets whether the attribute in the destination {@link FeatureSource} will
+   * be nillable.
+   * If set to {@code null}, the origin nillable property is used
+   */
+  public void setNewAttrNillable(Boolean newAttrNillable) {
+    this.newAttrNillable = newAttrNillable;
+  }
+
+  /**
    * Returns the attribute values which are transformed to NULL during the
    * modification process.
    * @return {@code null} if the origin attribute values are copied unchanged
@@ -122,6 +154,21 @@
   }
   
   /**
+   * Returns the values which is used as NULL during the
+   * modification process.
+   */
+  public Object getNullValueAlias() {
+    return nullValueAlias;
+  }
+  /**
+   * Sets the values which is used as NULL during the
+   * modification process.
+   */
+  public void setNullValueAlias(Object nullValueAlias) {
+    this.nullValueAlias = nullValueAlias;
+  }
+
+  /**
    * Applies the modifications defined by this {@link AttributeModificationRule} and
    * creates a new {@link AttributeDescriptor}.
    */
@@ -139,6 +186,11 @@
     if ( newClass == null )
       newClass = sourceAttrDescr.getType().getBinding();
   
+    // Change the nillable propery
+    Boolean newNillable = getNewAttrNillable();
+    if ( newNillable == null )
+      newNillable = sourceAttrDescr.isNillable();
+
     // Transform the default value to the new type
     Object newDefaultValue = FeatureUtil.transformAttributeValue(sourceAttrDescr.getDefaultValue(),newClass);
     
@@ -157,13 +209,34 @@
     return AttributeTypeFactory.newAttributeType(
         newName,
         newClass,
-        sourceAttrDescr.isNillable(),
+        newNillable,
         newRestrictions,
         newDefaultValue,
         newMetaData
     );
   }
 
+  /**
+   * Applies the modifications defined by this {@link AttributeModificationRule} to a
+   * destination feature.
+   */
+  public void applyToFeature(SimpleFeature sourceFeature, SimpleFeature destFeature) {
+    if ( destFeature == null )
+      throw new UnsupportedOperationException("Can not apply rules to NULL feature.");
+    if ( sourceFeature == null )
+      throw new UnsupportedOperationException("Can not apply rules from NULL feature.");
+
+    // determine source value
+    Object sValue = sourceFeature.getAttribute( getAttrIdx() );
+    // determine destination value according to NULL values and
+    // NULL alias
+    Object dValue = getNullValueAlias();
+    if ( !isNullValue(sValue))
+      dValue = FeatureUtil.transformAttributeValue(sValue, getNewAttrClass());
+    destFeature.setAttribute(getNewAttrName(), dValue);
+  }
+
+
 	/**
 	 * Testet ob ein Array mit {@link AttributeModificationRule}s bereits einen
 	 * Eintrag für einen zu prüfenden Namen enthaelt.

Modified: trunk/src/schmitzm/geotools/feature/FeatureUtil.java
===================================================================
--- trunk/src/schmitzm/geotools/feature/FeatureUtil.java	2010-10-14 20:58:06 UTC (rev 1124)
+++ trunk/src/schmitzm/geotools/feature/FeatureUtil.java	2010-10-14 21:02:49 UTC (rev 1125)
@@ -51,7 +51,6 @@
 import java.util.SortedMap;
 import java.util.TreeMap;
 import java.util.Vector;
-import java.util.regex.Pattern;
 
 import javax.measure.converter.ConversionException;
 import javax.measure.quantity.Length;
@@ -105,7 +104,6 @@
 
 import schmitzm.geotools.FilterUtil;
 import schmitzm.geotools.GTUtil;
-import schmitzm.io.IOUtil;
 import schmitzm.lang.LangUtil;
 import schmitzm.lang.ResourceProvider;
 import schmitzm.temp.BaseTypeUtil;
@@ -142,13 +140,13 @@
 	private static final NameImpl GC_NAME = new NameImpl(
 			"http://www.opengis.net/gml", "GridCoverage");
 
-	/**
-	 * Prueft, ob ein Attribut ein Geometrie-Attribut ist.
-	 */
-	public static boolean isGeometryAttribute(Object attrType) {
-		return attrType instanceof GeometryAttributeType
-				|| attrType instanceof GeometryDescriptor;
-	}
+    /**
+     * Prueft, ob ein Attribut ein Geometrie-Attribut ist.
+     */
+    public static boolean isGeometryAttribute(Object attrType) {
+      return attrType instanceof GeometryAttributeType ||
+             attrType instanceof GeometryDescriptor;
+    }
 
 	/**
 	 * This is a cheap and not good hack to extract the names of attributes used
@@ -313,7 +311,7 @@
 		else if (Polygon.class.isAssignableFrom(geometryType)
 				|| MultiPolygon.class.isAssignableFrom(geometryType))
 			return GeometryForm.POLYGON;
-
+		
 		// Aus anderem, doppelem alten code
 		// if (geometryAttrib != null
 		// && (com.vividsolutions.jts.geom.Polygon.class
@@ -379,7 +377,7 @@
 
 		for (int j = 0; j < f.getFeatureType().getAttributeCount(); j++)
 			// if ( f.getFeatureType().getAttributeType(j).isGeometry() )
-			if (isGeometryAttribute(f.getFeatureType()))
+			if ( isGeometryAttribute(f.getFeatureType() ))
 				geomVec.add(f.getAttribute(j));
 
 		Geometry[] geomArr = new Geometry[geomVec.size()];
@@ -412,7 +410,7 @@
 		}
 		return result;
 	}
-
+	
 	/**
 	 * Erzeugt einen Standard-Style fuer eine {@link FeatureCollection} Und
 	 * setzt eine default namen
@@ -441,8 +439,8 @@
 	}
 
 	/**
-	 * Erzeugt einen Standard-Style fuer einen {@link GeometryForm} Und setzt
-	 * eine default Namen.
+	 * Erzeugt einen Standard-Style fuer einen {@link GeometryForm} Und
+	 * setzt eine default Namen.
 	 * 
 	 * @param geometryAttrib
 	 *            GeometryAttributeType
@@ -702,8 +700,7 @@
 		// if it is a GeometryAttributeType, the CRS must be stored
 		// in the meta data
 		if (aType instanceof GeometryDescriptor)
-			metaData = ((GeometryDescriptor) aType)
-					.getCoordinateReferenceSystem();
+			metaData = ((GeometryDescriptor)aType).getCoordinateReferenceSystem();
 
 		// combine the restrictions of the attribute type for the
 		// AttributeTypeFactory
@@ -849,8 +846,8 @@
 
 			try {
 				builder.add(aType);
-				if (isGeometryAttribute(aType)
-						&& builder.getDefaultGeometry() == null)
+				if ( isGeometryAttribute(aType) &&
+				     builder.getDefaultGeometry() == null)
 					builder.setDefaultGeometry(aType.getLocalName());
 			} catch (IllegalArgumentException err) {
 				builder.add(AttributeTypeFactory.newAttributeType(
@@ -2453,160 +2450,97 @@
 
 		return null;
 	}
+	
 
 	/**
 	 * "Modifies" a {@link FeatureSource} according to the given
-	 * {@link AttributeModificationRule AttributeModificationDefinitions} and
-	 * stores the resulting {@link FeatureSource} in a data store.<br>
-	 * <b>Note</b>: Only the attibutes for which a
-	 * {@link AttributeModificationRule} is specified, are copied to the
-	 * destination {@link FeatureSource}. So even if an attribute should be
-	 * transfered unchanged, there must be an {@link AttributeModificationRule}
-	 * for it!! This <b>also</b> applies to the geometry attribute!!
-	 * 
-	 * @param sourceFs
-	 *            source {@link FeatureSource}
-	 * @param destDataStore
-	 *            destination for the new {@link FeatureSource}
-	 * @param destAttrRule
-	 *            defines which attributes of the source {@link FeatureSource}
-	 *            are copied in the destination, and (optionally) how the
-	 *            attributes are modified during this procedure
+	 * {@link AttributeModificationRule AttributeModificationDefinitions}
+	 * and stores the resulting {@link FeatureSource} in a data store.<br>
+	 * <b>Note</b>:
+	 * Only the attibutes for which a {@link AttributeModificationRule} is
+	 * specified, are copied to the destination {@link FeatureSource}. So even
+	 * if an attribute should be transfered unchanged, there must be an
+	 * {@link AttributeModificationRule} for it!!
+	 * This <b>also</b> applies to the geometry attribute!! 
+	 * @param sourceFs source {@link FeatureSource}
+	 * @param destDataStore destination for the new {@link FeatureSource}
+	 * @param destAttrRule defines which attributes of the source {@link FeatureSource}
+	 *                 are copied in the destination, and (optionally) how the
+	 *                 attributes are modified during this procedure 
 	 */
-	public static void modifyFeatureSource(
-			FeatureSource<SimpleFeatureType, SimpleFeature> sourceFs,
-			AbstractDataStore destDataStore,
-			AttributeModificationRule... destAttrRule) throws IOException {
-		SimpleFeatureType sType = sourceFs.getSchema();
-		SimpleFeatureTypeBuilder typebuilder = new SimpleFeatureTypeBuilder();
-		typebuilder.setName(sType.getTypeName());
+	public static void modifyFeatureSource(FeatureSource<SimpleFeatureType,SimpleFeature> sourceFs, AbstractDataStore destDataStore, AttributeModificationRule... destAttrRule) throws IOException {
+	  SimpleFeatureType sType = sourceFs.getSchema();
+      SimpleFeatureTypeBuilder typebuilder = new SimpleFeatureTypeBuilder();
+      typebuilder.setName(sType.getTypeName());
+      
+      //***** Create the new attribute type for the destination FeatureSource *****
+      // Loop the attributes, which should be transfered to the
+      // destination FeatureSource
+      for (AttributeModificationRule rule : destAttrRule) {
+        AttributeDescriptor sDescr = sType.getDescriptor(rule.getAttrIdx());
+        AttributeDescriptor dDescr = rule.applyToAttributeType(sDescr);
+        typebuilder.add(dDescr);
+      }
+      // create the FeatureType for the destination FeatureSource
+      SimpleFeatureType dType = typebuilder.buildFeatureType();
 
-		// ***** Create the new attribute type for the destination FeatureSource
-		// *****
-		// Loop the attributes, which should be transfered to the
-		// destination FeatureSource
-		for (AttributeModificationRule rule : destAttrRule) {
-			AttributeDescriptor sDescr = sType.getDescriptor(rule.getAttrIdx());
-			AttributeDescriptor dDescr = rule.applyToAttributeType(sDescr);
-			typebuilder.add(dDescr);
-		}
-		// create the FeatureType for the destination FeatureSource
-		SimpleFeatureType dType = typebuilder.buildFeatureType();
-
-		// ***** Create the new FeatureSource *****
-		destDataStore.createSchema(dType);
-		FeatureWriter<SimpleFeatureType, SimpleFeature> fWriter = destDataStore
-				.getFeatureWriter(dType.getTypeName(), Transaction.AUTO_COMMIT);
-		FeatureCollection<SimpleFeatureType, SimpleFeature> sourceFc = sourceFs
-				.getFeatures();
-		FeatureIterator<SimpleFeature> fIter = sourceFc.features();
-		try {
-			for (SimpleFeature sFeature = null; fIter.hasNext();) {
-				// Determine source feature
-				sFeature = fIter.next();
-				// Create destination feature
-				SimpleFeature dFeature = fWriter.next();
-				// Set the values in the destination feature
-				for (int destAttrIdx = 0; destAttrIdx < destAttrRule.length; destAttrIdx++) {
-					AttributeModificationRule rule = destAttrRule[destAttrIdx];
-					Object sValue = sFeature.getAttribute(rule.getAttrIdx());
-					Object dValue = null;
-					if (!rule.isNullValue(sValue))
-						dValue = transformAttributeValue(sValue,
-								rule.getNewAttrClass());
-					dFeature.setAttribute(destAttrIdx, dValue);
-				}
-				// write the destination feature
-				fWriter.write();
-			}
-		} finally {
-			sourceFc.close(fIter);
-			fWriter.close();
-		}
-
-		LOGGER.error("FeatureUtil.modifyFeatureSource(..) not yet implemented!");
-
+      //***** Create the new FeatureSource *****
+      destDataStore.createSchema(dType);
+      FeatureWriter<SimpleFeatureType, SimpleFeature> fWriter = destDataStore.getFeatureWriter(dType.getTypeName(), Transaction.AUTO_COMMIT);
+      FeatureCollection<SimpleFeatureType, SimpleFeature> sourceFc = sourceFs.getFeatures();
+      FeatureIterator<SimpleFeature> fIter = sourceFc.features();
+      try {
+        for (SimpleFeature sFeature = null; fIter.hasNext(); ) {
+          // Determine source feature
+          sFeature = fIter.next();
+          // Create destination feature
+          SimpleFeature dFeature = fWriter.next();
+          // Set the values in the destination feature
+          for (AttributeModificationRule modRule : destAttrRule) 
+            modRule.applyToFeature(sFeature, dFeature);
+          // write the destination feature
+          fWriter.write();
+        }
+      } finally {
+        sourceFc.close(fIter);
+        fWriter.close();
+      }
 	}
-
+	
 	/**
 	 * Transforms a value to another type.
-	 * 
-	 * @param value
-	 *            a value
-	 * @param destType
-	 *            destination type
-	 * @return {@code null} if {@code value} is {@code null} or if the
-	 *         transformation can not be applied; the {@code value} itself if no
-	 *         destination type is given or {@code value} is already in instance
-	 *         of the destination type
+	 * @param value a value
+	 * @param destType destination type
+	 * @return {@code null} if {@code value} is {@code null} or if the transformation can
+	 *         not be applied; the {@code value} itself if no destination type is given or
+	 *         {@code value} is already in instance of the destination type 
 	 */
 	public static Object transformAttributeValue(Object value, Class<?> destType) {
-		if (value == null)
-			return null;
-		if (destType == null)
-			return value;
-		if (destType.isInstance(value))
-			return value;
-
-		// convert to string --> easy!
-		if (String.class.equals(destType))
-			return value.toString();
-		// convert to number
-		if (Number.class.isAssignableFrom(destType)) {
-			if (value instanceof Number)
-				return BaseTypeUtil.convertNumber((Number) value,
-						(Class<Number>) destType);
-			if (value instanceof String)
-				return BaseTypeUtil.convertFromString((String) value,
-						(Class<Number>) destType);
-		}
-
-		// TODO: implement more transformation rules
-
-		LOGGER.warn("Can not apply attribute value transformation: "
-				+ LangUtil.getSimpleClassName(value) + " --> "
-				+ LangUtil.getSimpleClassName(destType) + " (for '" + value
-				+ "')");
-
-		return null;
+	  if ( value == null )
+	    return null;
+	  if ( destType == null )
+	    return value;
+	  if ( destType.isInstance(value) )
+	    return value;
+	  
+	  // convert to string --> easy!
+	  if ( String.class.equals(destType) )
+	    return value.toString();
+	  // convert to number
+	  if ( Number.class.isAssignableFrom(destType) ) {
+	    if ( value instanceof Number )
+	      return BaseTypeUtil.convertNumber((Number)value,(Class<Number>)destType);
+        if ( value instanceof String )
+          return BaseTypeUtil.convertFromString((String)value,(Class<Number>)destType);
+	  }
+	  
+	  // TODO: implement more transformation rules
+	  
+	  LOGGER.warn("Can not apply attribute value transformation: "+LangUtil.getSimpleClassName(value)+" --> "+LangUtil.getSimpleClassName(destType)+" (for '"+value+"')");
+	    
+	  return null;
 	}
 
-	/**
-	 * @returns a "cleaned" (DBF compatible) proposal for a attribute name based
-	 *          on the existing name.
-	 */
-	public static String cleanAttname(String name) {
-		return cleanAttname(name, null);
-	}
-
-	static public final Pattern StringStartsWithNumber = Pattern
-			.compile("^\\d.*$");
-
-	/**
-	 * @returns a "cleaned" (DBF compatible) proposal for a attribute name based
-	 *          on the existing name.
-	 */
-	public static String cleanAttname(String name, Integer counter) {
-
-		String clean = IOUtil.cleanFilename(name);
-		clean = clean.toUpperCase();
-
-		if (StringStartsWithNumber.matcher(clean).find()) {
-			clean = "_" + clean;
-		}
-
-		clean = clean.substring(0, Math.min(11, clean.length() - 1));
-
-		if (!FeatureUtil.checkAttributeNameRestrictions(clean)) {
-			if (counter != null)
-				return "COLUMN" + counter;
-			else
-				return "COLUMN" + new Random().nextInt(9999);
-		}
-
-		return clean;
-	}
-
 	// /**
 	// * Extrahiert alle Geometrien aus einer FeatureCollection. Fuer jedes
 	// * Geometry-Attribut der FeatureCollection wird eine GeometrieCollection

Modified: trunk/src_junit/schmitzm/geotools/feature/FeatureUtilTest.java
===================================================================
--- trunk/src_junit/schmitzm/geotools/feature/FeatureUtilTest.java	2010-10-14 20:58:06 UTC (rev 1124)
+++ trunk/src_junit/schmitzm/geotools/feature/FeatureUtilTest.java	2010-10-14 21:02:49 UTC (rev 1125)
@@ -108,7 +108,7 @@
 
 		AttributeModificationRule[] destAttrs = new AttributeModificationRule[3];
 		destAttrs[0] = new AttributeModificationRule(0);
-		destAttrs[1] = new AttributeModificationRule(3, "arab", null, null);
+		destAttrs[1] = new AttributeModificationRule(3, "arab", null, null, null, null);
 		destAttrs[2] = new AttributeModificationRule(2);
 		Set<Object> nullValues = new HashSet<Object>();
 		nullValues.add(39207);



More information about the Schmitzm-commits mailing list