001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/io/datastore/sql/idgenerator/DBMaxIdGenerator.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2006 by: M.O.S.S. Computer Grafik Systeme GmbH
006 Hohenbrunner Weg 13
007 D-82024 Taufkirchen
008 http://www.moss.de/
009
010 This library is free software; you can redistribute it and/or
011 modify it under the terms of the GNU Lesser General Public
012 License as published by the Free Software Foundation; either
013 version 2.1 of the License, or (at your option) any later version.
014
015 This library is distributed in the hope that it will be useful,
016 but WITHOUT ANY WARRANTY; without even the implied warranty of
017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
018 Lesser General Public License for more details.
019
020 You should have received a copy of the GNU Lesser General Public
021 License along with this library; if not, write to the Free Software
022 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
023
024 ---------------------------------------------------------------------------*/
025 package org.deegree.io.datastore.sql.idgenerator;
026
027 import java.sql.Connection;
028 import java.util.Properties;
029
030 import org.deegree.io.datastore.DatastoreException;
031 import org.deegree.io.datastore.DatastoreTransaction;
032 import org.deegree.io.datastore.FeatureId;
033 import org.deegree.io.datastore.idgenerator.IdGenerationException;
034 import org.deegree.io.datastore.idgenerator.IdGenerator;
035 import org.deegree.io.datastore.schema.MappedFeatureType;
036 import org.deegree.io.datastore.schema.MappedGMLId;
037 import org.deegree.io.datastore.sql.AbstractSQLDatastore;
038 import org.deegree.io.datastore.sql.transaction.SQLTransaction;
039
040 /**
041 * Feature id generator that produces successive (+1) values and retrieves its start value from the
042 * specified table value (the maximum stored in the field).
043 * <p>
044 * Please note that aborted transactions will also increase ids, so feature ids may be skipped.
045 *
046 * @author <a href="mailto:cpollmann@moss.de">Christoph Pollmann</a>
047 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
048 * @author last edited by: $Author: mschneider $
049 *
050 * @version $Revision: 6588 $, $Date: 2007-04-11 17:31:29 +0200 (Mi, 11. Apr 2007) $
051 */
052 public class DBMaxIdGenerator extends IdGenerator {
053
054 private String tableName;
055
056 private String columnName;
057
058 // initialized when #getNewId() is called the first time
059 private int lastId = -1;
060
061 /**
062 * Creates a new <code>DBMaxIdGenerator</code> instance.
063 * <p>
064 * Supported configuration parameters: <table>
065 * <tr>
066 * <th>Name</th>
067 * <th>optional?</th>
068 * <th>Usage</th>
069 * </tr>
070 * <tr>
071 * <td>table</td>
072 * <td>no</td>
073 * <td>name of the table where the id field is stored</td>
074 * </tr>
075 * <tr>
076 * <td>column</td>
077 * <td>no</td>
078 * <td>name of the id field</td>
079 * </tr>
080 * </table>
081 *
082 * @param params
083 * configuration parameters
084 * @throws IdGenerationException
085 */
086 public DBMaxIdGenerator( Properties params ) throws IdGenerationException {
087 super( params );
088 this.tableName = params.getProperty( "table" );
089 this.columnName = params.getProperty( "column" );
090 if ( this.tableName == null || this.columnName == null ) {
091 String msg = "DBMaxIdGenerator requires 'table' and 'column' parameters.";
092 throw new IdGenerationException( msg );
093 }
094 }
095
096 /**
097 * Returns a new primary key.
098 *
099 * @param ta
100 * datastore transaction (context)
101 * @return a new primary key.
102 * @throws IdGenerationException
103 * if the generation of the id could not be performed
104 */
105 @Override
106 public Object getNewId( DatastoreTransaction ta )
107 throws IdGenerationException {
108
109 if ( this.lastId == -1 ) {
110 initLastId( ta );
111 }
112
113 return ++this.lastId;
114 }
115
116 /**
117 * Initialized the lastId field with the maximum value stored in the specified table field.
118 *
119 * @param ta
120 * datastore transaction (context)
121 * @throws IdGenerationException
122 */
123 private void initLastId( DatastoreTransaction ta )
124 throws IdGenerationException {
125
126 if ( !( ta instanceof SQLTransaction ) ) {
127 String msg = "DBMaxIdGenerator can only be used with SQL based datastores.";
128 throw new IllegalArgumentException( msg );
129 }
130
131 try {
132 AbstractSQLDatastore ds = (AbstractSQLDatastore) ta.getDatastore();
133 Connection conn = ( (SQLTransaction) ta ).getConnection();
134 this.lastId = ds.getMaxValue( conn, this.tableName, this.columnName );
135 } catch ( DatastoreException e ) {
136 throw new IdGenerationException( e.getMessage(), e );
137 }
138 }
139
140 /**
141 * Returns a new id for a feature of the given type.
142 *
143 * @param ft
144 * (mapped) feature type
145 * @return a new feature id.
146 * @throws IdGenerationException
147 * if the generation of the id could not be performed
148 */
149 @Override
150 public FeatureId getNewId( MappedFeatureType ft, DatastoreTransaction ta )
151 throws IdGenerationException {
152
153 MappedGMLId fidDefinition = ft.getGMLId();
154 if ( fidDefinition.getKeySize() != 1 ) {
155 String msg = "Cannot generate feature ids that are mapped to more than one column.";
156 throw new IdGenerationException( msg );
157 }
158
159 if ( this.lastId == -1 ) {
160 initLastId( ta );
161 }
162
163 FeatureId fid = new FeatureId( ft, new Object[] { ++this.lastId } );
164 return fid;
165 }
166 }