]> source.dussan.org Git - jackcess.git/commitdiff
add ability to set properties in the various Bulders
authorJames Ahlborn <jtahlborn@yahoo.com>
Tue, 9 Sep 2014 01:03:04 +0000 (01:03 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Tue, 9 Sep 2014 01:03:04 +0000 (01:03 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@870 f203690c-595d-4dc9-a70b-905162fa7fd2

src/changes/changes.xml
src/main/java/com/healthmarketscience/jackcess/ColumnBuilder.java
src/main/java/com/healthmarketscience/jackcess/DatabaseBuilder.java
src/main/java/com/healthmarketscience/jackcess/PropertyMap.java
src/main/java/com/healthmarketscience/jackcess/TableBuilder.java
src/main/java/com/healthmarketscience/jackcess/impl/PropertyMapImpl.java

index ccc033ac52902be481a6afb2f96a1f293c7f72fc..8ef8f7e0160ac0fa02bb94afe786fc0789d7ce92 100644 (file)
         Jackcess will not evaluate the actual expressions, but the column
         values can be written directly.
       </action>
+      <action dev="jahlborn" type="add">
+        Add the ability to set properties in DatabaseBuilder, TableBuilder,
+        and ColumnBuilder.
+      </action>
     </release>
     <release version="2.0.4" date="2014-04-05">
       <action dev="jahlborn" type="add">
index dc0b5662346874b9fe32761dad85fbc9a5029cc5..57c5bb5eafe1cd0f3bc5d6afb3f8f9ffdaad1d25 100644 (file)
@@ -28,12 +28,15 @@ King of Prussia, PA 19406
 package com.healthmarketscience.jackcess;
 
 import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import com.healthmarketscience.jackcess.impl.ColumnImpl;
-import com.healthmarketscience.jackcess.impl.JetFormat;
 import com.healthmarketscience.jackcess.impl.DatabaseImpl;
+import com.healthmarketscience.jackcess.impl.JetFormat;
+import com.healthmarketscience.jackcess.impl.PropertyMapImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * Builder style class for constructing a {@link Column}.  See {@link
@@ -66,6 +69,8 @@ public class ColumnBuilder {
   private short _columnNumber;
   /** the collating sort order for a text field */
   private ColumnImpl.SortOrder _sortOrder;
+  /** table properties (if any) */
+  private Map<String,PropertyMap.Property> _props;
 
 
   public ColumnBuilder(String name) {
@@ -198,6 +203,31 @@ public class ColumnBuilder {
     return _hyperlink;
   }
 
+  /**
+   * Sets the column property with the given name to the given value.  Attempts
+   * to determine the type of the property (see
+   * {@link PropertyMap#put(String,Object)} for details on determining the
+   * property type).
+   */
+  public ColumnBuilder putProperty(String name, Object value) {
+    return putProperty(name, null, value);
+  }
+
+  /**
+   * Sets the column property with the given name and type to the given value.
+   */
+  public ColumnBuilder putProperty(String name, DataType type, Object value) {
+    if(_props == null) {
+      _props = new HashMap<String,PropertyMap.Property>();
+    }
+    _props.put(name, PropertyMapImpl.createProperty(name, type, value));
+    return this;
+  }
+
+  public Map<String,PropertyMap.Property> getProperties() {
+    return _props;
+  }
+  
   /**
    * Sets all attributes except name from the given Column template.
    */
index 7e40c10920c4464a3bc142ac37f9cbe21b5f1b11..c1dc889421d9ea5f76764afb587ad8ba6f1121a2 100644 (file)
@@ -23,10 +23,13 @@ import java.io.File;
 import java.io.IOException;
 import java.nio.channels.FileChannel;
 import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.TimeZone;
 
-import com.healthmarketscience.jackcess.impl.DatabaseImpl;
 import com.healthmarketscience.jackcess.impl.CodecProvider;
+import com.healthmarketscience.jackcess.impl.DatabaseImpl;
+import com.healthmarketscience.jackcess.impl.PropertyMapImpl;
 import com.healthmarketscience.jackcess.util.MemFileChannel;
 
 /**
@@ -66,7 +69,14 @@ public class DatabaseBuilder
   /** optional pre-opened FileChannel, will _not_ be closed by Database
       close */
   private FileChannel _channel;
+  /** database properties (if any) */
+  private Map<String,PropertyMap.Property> _dbProps;
+  /** database summary properties (if any) */
+  private Map<String,PropertyMap.Property> _summaryProps;
+  /** database user-defined (if any) */
+  private Map<String,PropertyMap.Property> _userProps;
 
+  
   public DatabaseBuilder() {
     this(null);
   }
@@ -163,6 +173,77 @@ public class DatabaseBuilder
     return this;
   }
 
+  /**
+   * Sets the database property with the given name to the given value.
+   * Attempts to determine the type of the property (see
+   * {@link PropertyMap#put(String,Object)} for details on determining the
+   * property type).
+   */
+  public DatabaseBuilder putDatabaseProperty(String name, Object value) {
+    return putDatabaseProperty(name, null, value);
+  }
+  
+  /**
+   * Sets the database property with the given name and type to the given
+   * value.
+   */
+  public DatabaseBuilder putDatabaseProperty(String name, DataType type,
+                                             Object value) {
+    _dbProps = putProperty(_dbProps, name, type, value);
+    return this;
+  }
+  
+  /**
+   * Sets the summary database property with the given name to the given
+   * value.  Attempts to determine the type of the property (see
+   * {@link PropertyMap#put(String,Object)} for details on determining the
+   * property type).
+   */
+  public DatabaseBuilder putSummaryProperty(String name, Object value) {
+    return putSummaryProperty(name, null, value);
+  }
+  
+  /**
+   * Sets the summary database property with the given name and type to
+   * the given value.
+   */
+  public DatabaseBuilder putSummaryProperty(String name, DataType type,
+                                            Object value) {
+    _summaryProps = putProperty(_summaryProps, name, type, value);
+    return this;
+  }
+
+  /**
+   * Sets the user-defined database property with the given name to the given
+   * value.  Attempts to determine the type of the property (see
+   * {@link PropertyMap#put(String,Object)} for details on determining the
+   * property type).
+   */
+  public DatabaseBuilder putUserDefinedProperty(String name, Object value) {
+    return putUserDefinedProperty(name, null, value);
+  }
+  
+  /**
+   * Sets the user-defined database property with the given name and type to
+   * the given value.
+   */
+  public DatabaseBuilder putUserDefinedProperty(String name, DataType type,
+                                                Object value) {
+    _userProps = putProperty(_userProps, name, type, value);
+    return this;
+  }
+
+  private static Map<String,PropertyMap.Property> putProperty(
+      Map<String,PropertyMap.Property> props, String name, DataType type,
+      Object value)
+  {
+    if(props == null) {
+      props = new HashMap<String,PropertyMap.Property>();
+    }
+    props.put(name, PropertyMapImpl.createProperty(name, type, value));
+    return props;
+  }
+
   /**
    * Opens an existingnew Database using the configured information.
    */
@@ -175,8 +256,24 @@ public class DatabaseBuilder
    * Creates a new Database using the configured information.
    */
   public Database create() throws IOException {
-    return DatabaseImpl.create(_fileFormat, _mdbFile, _channel, _autoSync, 
-                               _charset, _timeZone);
+    Database db = DatabaseImpl.create(_fileFormat, _mdbFile, _channel, _autoSync, 
+                                      _charset, _timeZone);
+    if(_dbProps != null) {
+      PropertyMap props = db.getDatabaseProperties();
+      props.putAll(_dbProps.values());
+      props.save();
+    }
+    if(_summaryProps != null) {
+      PropertyMap props = db.getSummaryProperties();
+      props.putAll(_summaryProps.values());
+      props.save();
+    }
+    if(_userProps != null) {
+      PropertyMap props = db.getUserDefinedProperties();
+      props.putAll(_userProps.values());
+      props.save();
+    }
+    return db;
   }
 
   /**
@@ -208,6 +305,4 @@ public class DatabaseBuilder
   {
     return new DatabaseBuilder(mdbFile).setFileFormat(fileFormat).create();
   }
-  
-
 }
index 779d92b9cfc5690adca0e8f40f04417d45c0cc63..f411bfd92a0064df337e17bcd5cf527ec88aaabc 100644 (file)
@@ -71,6 +71,21 @@ public interface PropertyMap extends Iterable<PropertyMap.Property>
    */
   public Object getValue(String name, Object defaultValue);
 
+  /**
+   * Creates a new (or updates an existing) property in the map.  Attempts to
+   * determine the type of the property based on the name and value (the
+   * property names listed above have their types builtin, otherwise the type
+   * of the value is used).
+   * <p/>
+   * Note, this change will not be persisted until the {@link #save} method
+   * has been called.
+   *
+   * @return the newly created (or updated) property
+   * @throws IllegalArgumentException if the type of the property could not be
+   *                                  determined automatically
+   */
+  public Property put(String name, Object value);
+
   /**
    * Creates a new (or updates an existing) property in the map.
    * <p/>
@@ -81,6 +96,14 @@ public interface PropertyMap extends Iterable<PropertyMap.Property>
    */
   public Property put(String name, DataType type, Object value);
 
+  /**
+   * Puts all the given properties into this map.
+   *
+   * @props the properties to put into this map ({@code null} is tolerated and
+   *        ignored).
+   */
+  public void putAll(Iterable<? extends Property> props);
+  
   /**
    * Removes the property with the given name
    *
index 9f63796431cbcac80157d3720bcecec0fcb035cf..b28d35b87dccdbfa0dd89d7a9b9f68119e5b5e8e 100644 (file)
@@ -31,11 +31,14 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import com.healthmarketscience.jackcess.impl.DatabaseImpl;
+import com.healthmarketscience.jackcess.impl.PropertyMapImpl;
 
 /**
  * Builder style class for constructing a {@link Table}.
@@ -108,8 +111,10 @@ public class TableBuilder {
   private List<IndexBuilder> _indexes = new ArrayList<IndexBuilder>();
   /** whether or not table/column/index names are automatically escaped */
   private boolean _escapeIdentifiers;
-  
+  /** table properties (if any) */
+  private Map<String,PropertyMap.Property> _props;
 
+  
   public TableBuilder(String name) {
     this(name, false);
   }
@@ -187,6 +192,27 @@ public class TableBuilder {
     return this;
   }
 
+  /**
+   * Sets the table property with the given name to the given value.  Attempts
+   * to determine the type of the property (see
+   * {@link PropertyMap#put(String,Object)} for details on determining the
+   * property type).
+   */
+  public TableBuilder putProperty(String name, Object value) {
+    return putProperty(name, null, value);
+  }
+  
+  /**
+   * Sets the table property with the given name and type to the given value.
+   */
+  public TableBuilder putProperty(String name, DataType type, Object value) {
+    if(_props == null) {
+      _props = new HashMap<String,PropertyMap.Property>();
+    }
+    _props.put(name, PropertyMapImpl.createProperty(name, type, value));
+    return this;
+  }
+  
   /**
    * Creates a new Table in the given Database with the currently configured
    * attributes.
@@ -195,7 +221,27 @@ public class TableBuilder {
     throws IOException
   {
     ((DatabaseImpl)db).createTable(_name, _columns, _indexes);
-    return db.getTable(_name);
+    Table table = db.getTable(_name);
+
+    boolean addedProps = false;
+    if(_props != null) {
+      table.getProperties().putAll(_props.values());
+      addedProps = true;
+    }
+    for(ColumnBuilder cb : _columns) {
+      Map<String,PropertyMap.Property> colProps = cb.getProperties();
+      if(colProps != null) {
+        table.getColumn(cb.getName()).getProperties().putAll(colProps.values());
+        addedProps = true;
+      }
+    }
+
+    // all table and column props are saved together
+    if(addedProps) {
+      table.getProperties().save();
+    }
+    
+    return table;
   }
 
   /**
@@ -218,5 +264,4 @@ public class TableBuilder {
     return ReservedWords.VALUES.contains(s.toLowerCase());
   }
 
-  
 }
index 11bdf21a1daae4a9bbd613793d07cc5d06669cc1..3c14be2d16bc1f605d5f6b85660b4fe4cd84f91b 100644 (file)
@@ -20,6 +20,8 @@ USA
 package com.healthmarketscience.jackcess.impl;
 
 import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -34,6 +36,30 @@ import com.healthmarketscience.jackcess.PropertyMap;
  */
 public class PropertyMapImpl implements PropertyMap
 {
+  private static final Map<String,DataType> DEFAULT_TYPES =
+    new HashMap<String,DataType>();
+
+  static {
+    DEFAULT_TYPES.put(ACCESS_VERSION_PROP, DataType.TEXT);
+    DEFAULT_TYPES.put(TITLE_PROP, DataType.TEXT);
+    DEFAULT_TYPES.put(AUTHOR_PROP, DataType.TEXT);
+    DEFAULT_TYPES.put(COMPANY_PROP, DataType.TEXT);
+
+    DEFAULT_TYPES.put(DEFAULT_VALUE_PROP, DataType.MEMO);
+    DEFAULT_TYPES.put(REQUIRED_PROP, DataType.BOOLEAN);
+    DEFAULT_TYPES.put(ALLOW_ZERO_LEN_PROP, DataType.MEMO);
+    DEFAULT_TYPES.put(DECIMAL_PLACES_PROP, DataType.BYTE);
+    DEFAULT_TYPES.put(FORMAT_PROP, DataType.TEXT);
+    DEFAULT_TYPES.put(INPUT_MASK_PROP, DataType.TEXT);
+    DEFAULT_TYPES.put(CAPTION_PROP, DataType.MEMO);
+    DEFAULT_TYPES.put(VALIDATION_RULE_PROP, DataType.TEXT);
+    DEFAULT_TYPES.put(VALIDATION_TEXT_PROP, DataType.TEXT);
+    DEFAULT_TYPES.put(GUID_PROP, DataType.BINARY);
+    DEFAULT_TYPES.put(DESCRIPTION_PROP, DataType.MEMO);
+    DEFAULT_TYPES.put(RESULT_TYPE_PROP, DataType.BYTE);
+    DEFAULT_TYPES.put(EXPRESSION_PROP, DataType.MEMO);
+  }
+
   private final String _mapName;
   private final short _mapType;
   private final Map<String,Property> _props = 
@@ -83,15 +109,33 @@ public class PropertyMapImpl implements PropertyMap
     return value;
   }
 
+  public PropertyImpl put(String name, Object value) {
+    return put(name, null, (byte)0, value);
+  }
+
   public PropertyImpl put(String name, DataType type, Object value) {
     return put(name, type, (byte)0, value);
   }
 
+  public void putAll(Iterable<? extends Property> props) {
+    if(props == null) {
+      return;
+    }
+
+    for(Property prop : props) {
+      byte flag = 0;
+      if(prop instanceof PropertyImpl) {
+        flag = ((PropertyImpl)prop).getFlag();
+      }
+      put(prop.getName(), prop.getType(), flag, prop.getValue());
+    }
+  }  
+  
   /**
    * Puts a property into this map with the given information.
    */
   public PropertyImpl put(String name, DataType type, byte flag, Object value) {
-    PropertyImpl prop = new PropertyImpl(name, type, flag, value);
+    PropertyImpl prop = (PropertyImpl)createProperty(name, type, flag, value);
     _props.put(DatabaseImpl.toLookupName(name), prop);
     return prop;
   }
@@ -124,6 +168,47 @@ public class PropertyMapImpl implements PropertyMap
     return sb.toString();
   }      
 
+  public static Property createProperty(String name, DataType type, Object value) {
+    return createProperty(name, type, (byte)0, value);
+  }
+  
+  public static Property createProperty(String name, DataType type, byte flag,
+                                        Object value) {
+    if(type == null) {
+      
+      // attempt to figure out the type
+      type = DEFAULT_TYPES.get(type);
+
+      if(type == null) {
+        if(value instanceof String) {
+          type = DataType.TEXT;
+        } else if(value instanceof Boolean) {
+          type = DataType.BOOLEAN;
+        } else if(value instanceof Byte) {
+          type = DataType.BYTE;
+        } else if(value instanceof Short) {
+          type = DataType.INT;
+        } else if(value instanceof Integer) {
+          type = DataType.LONG;
+        } else if(value instanceof Float) {
+          type = DataType.FLOAT;
+        } else if(value instanceof Double) {
+          type = DataType.DOUBLE;
+        } else if(value instanceof Date) {
+          type = DataType.SHORT_DATE_TIME;
+        } else if(value instanceof byte[]) {
+          type = DataType.OLE;
+        } else {
+          throw new IllegalArgumentException(
+              "Could not determine type for property " + name +
+              " with value " + value);
+        }
+      }
+    }
+    
+    return new PropertyImpl(name, type, flag, value);
+  }
+  
   /**
    * Info about a property defined in a PropertyMap.
    */