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    }