Revision 238

View differences:

org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.app.jcrs/org.gvsig.projection.app.jcrs.common/src/main/java/org/gvsig/crs/JCRSPluginLibrary.java
26 26
		initalizeHomeDB(plugin);
27 27
		CrsFactory.setDataBaseFolder(new File (plugin.getPluginHomeFolder(),"db"));		
28 28
		CrsFactory.setProjLibFolder(new File (plugin.getPluginHomeFolder(),"projlib"));
29
		CrsFactory.setEnableMemoryCacheOfCRS(true);
29 30
	}
30 31

  
31 32
	private void initalizeHomeDB(PluginServices plugin) {
org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.jcrs.lib/src/main/java/es/idr/teledeteccion/connection/EpsgConnection.java
20 20
package es.idr.teledeteccion.connection;
21 21

  
22 22
import java.sql.Connection;
23
import java.sql.ResultSet;
24 23
import java.sql.SQLException;
25 24
import java.sql.Statement;
26 25

  
......
135 134
        return connect;
136 135
    }
137 136

  
137
    public void close() throws SQLException {
138

  
139
        try {
140
            connect.close();    // if there are no other open connection
141
            logger.debug("Shutdown connection to '" + connectionType + "' database.");
142
        } catch (Exception ex) {
143
            logger.warn("Can't shutdown the conexion.",ex);
144
        }
145
    }
146

  
138 147
    public void shutdown() throws SQLException {
139 148

  
140
        Statement st = connect.createStatement();
141

  
142
            // db writes out to files and performs clean shuts down
149
        // db writes out to files and performs clean shuts down
143 150
        // otherwise there will be an unclean shutdown
144 151
        // when program ends
145
        st.execute("SHUTDOWN");
146
        connect.close();    // if there are no other open connection
147
        logger.debug("Shutdown connection to '"+connectionType+"' database.");
152
        try {
153
            Statement st = connect.createStatement();
154
            st.execute("SHUTDOWN");
155
            connect.close();    // if there are no other open connection
156
            logger.debug("Shutdown connection to '" + connectionType + "' database.");
157
        } catch (Exception ex) {
158
            logger.warn("Can't shutdown the conexion.",ex);
159
        }
148 160
    }
149 161

  
150 162
    public synchronized void update(String expression) throws SQLException {
org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.jcrs.lib/src/main/java/es/idr/teledeteccion/connection/epsg/HSQLDataSource.java
42 42
import org.slf4j.Logger;
43 43
import org.slf4j.LoggerFactory;
44 44

  
45

  
46 45
/**
47
 * Connection to the EPSG database in HSQL database engine format using JDBC. The EPSG
48
 * database can be downloaded from <A HREF="http://www.epsg.org">http://www.epsg.org</A>.
49
 * The SQL scripts (modified for the HSQL syntax as <A HREF="doc-files/HSQL.html">explained
50
 * here</A>) are bundled into this plugin. The database version is given in the
46
 * Connection to the EPSG database in HSQL database engine format using JDBC.
47
 * The EPSG database can be downloaded from <A
48
 * HREF="http://www.epsg.org">http://www.epsg.org</A>. The SQL scripts (modified
49
 * for the HSQL syntax as <A HREF="doc-files/HSQL.html">explained here</A>) are
50
 * bundled into this plugin. The database version is given in the
51 51
 * {@linkplain org.opengis.metadata.citation.Citation#getEdition edition attribute}
52
 * of the {@linkplain org.opengis.referencing.AuthorityFactory#getAuthority authority}.
52
 * of the
53
 * {@linkplain org.opengis.referencing.AuthorityFactory#getAuthority authority}.
53 54
 * The HSQL database is read only.
54 55
 * <P>
55 56
 * <H3>Implementation note</H3>
56
 * The SQL scripts are executed the first time a connection is required. The database
57
 * is then created as cached tables ({@code HSQL.properties} and {@code HSQL.data} files)
58
 * in a temporary directory. Future connections to the EPSG database while reuse the cached
59
 * tables, if available. Otherwise, the scripts will be executed again in order to recreate
60
 * them.
57
 * The SQL scripts are executed the first time a connection is required. The
58
 * database is then created as cached tables ({@code HSQL.properties} and
59
 * {@code HSQL.data} files) in a temporary directory. Future connections to the
60
 * EPSG database while reuse the cached tables, if available. Otherwise, the
61
 * scripts will be executed again in order to recreate them.
61 62
 *
62 63
 * @version $Id: HSQLDataSource.java 14624 2005-06-29 02:19:08Z desruisseaux $
63 64
 * @author Martin Desruisseaux
......
66 67
 * @since 2.2
67 68
 */
68 69
public class HSQLDataSource extends jdbcDataSource implements DataSource {
69
	// 20090518 cmartinez: Use a different tmp dir for each geotools instance
70
	private static File tmpDir = null;
71
	
72
	private static final Logger logger = LoggerFactory.getLogger(HSQLDataSource.class);
70

  
71
    // 20090518 cmartinez: Use a different tmp dir for each geotools instance
72
    private static File tmpDir = null;
73

  
74
    private static final Logger logger = LoggerFactory.getLogger(HSQLDataSource.class);
75

  
73 76
    /**
74 77
     * Creates a new instance of this data source
75 78
     */
......
85 88
                 */
86 89
                final StringBuffer url = new StringBuffer("jdbc:hsqldb:file:");
87 90
                final String path = directory.getAbsolutePath().replace(File.separatorChar, '/');
88
                if (path.length()==0 || path.charAt(0)!='/') {
91
                if (path.length() == 0 || path.charAt(0) != '/') {
89 92
                    url.append('/');
90 93
                }
91 94
                url.append(path);
92
                if (url.charAt(url.length()-1) != '/') {
95
                if (url.charAt(url.length() - 1) != '/') {
93 96
                    url.append('/');
94 97
                }
95 98
                url.append("EPSG");
......
105 108
        setUser("SA"); // System administrator. No password.
106 109
    }
107 110

  
108
    private static File getGtTmpDir() {
109
    	if (tmpDir == null) {
110
//    		tmpDir = new File(System.getProperty("java.io.tmpdir", "."), "Geotools-"+System.currentTimeMillis());
111
    		tmpDir = new File( CrsFactory.getDataBaseFolder(),"temp-"+ getProcessId());
112
    		Runtime.getRuntime().addShutdownHook( new RemoveFolderOnShutdown(tmpDir) );
113
    	}
114
    	return tmpDir;
111
    private File getGtTmpDir() {
112
        if (tmpDir == null) {
113
            tmpDir = new File(CrsFactory.getDataBaseFolder(), "temp-" + getProcessId());
114
            Runtime.getRuntime().addShutdownHook(new cleanOnShutdown(this));
115
        }
116
        return tmpDir;
115 117
    }
116 118

  
117 119
    private static String getProcessId() {
118
    	String fallback = "time" + System.currentTimeMillis();
119
    	
120
        String fallback = "time" + System.currentTimeMillis();
121

  
120 122
        // something like '<pid>@<hostname>', at least in SUN / Oracle JVMs
121 123
        final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
122 124
        final int index = jvmName.indexOf('@');
......
125 127
            return fallback;
126 128
        }
127 129
        try {
128
            return "pid"+Long.toString(Long.parseLong(jvmName.substring(0, index)));
130
            return "pid" + Long.toString(Long.parseLong(jvmName.substring(0, index)));
129 131
        } catch (NumberFormatException e) {
130 132
            // ignore
131 133
        }
132 134
        return fallback;
133 135
    }
134
    
135
    public static class RemoveFolderOnShutdown extends Thread {
136
    	private File folder;
137
		public RemoveFolderOnShutdown(File folder) {
138
    		this.folder = folder;
139
    	}
140
    	public void run() {
141
    		try {
142
    			logger.info("Deleting CRS temporary database folder ("+folder.getAbsolutePath()+").");
143
				FileUtils.deleteDirectory(this.folder);
144
			} catch (IOException e) {
145
				logger.error("Can't delete CRS temporary database folder ("+this.folder+".",e);
146
			}
147
    	}
136

  
137
    public static class cleanOnShutdown extends Thread {
138

  
139
        private HSQLDataSource ds;
140

  
141
        public cleanOnShutdown(HSQLDataSource ds) {
142
            this.ds = ds;
143
        }
144

  
145
        public void run() {
146
            this.shutdown();
147
            this.delete();
148
        }
149

  
150
        private void delete() {
151
            File folder = HSQLDataSource.tmpDir;
152
            if (folder == null) {
153
                return;
154
            }
155
            try {
156
                logger.info("Deleting CRS temporary database folder (" + folder.getAbsolutePath() + ").");
157
                FileUtils.deleteDirectory(folder);
158
            } catch (IOException e) {
159
                logger.error("Can't delete CRS temporary database folder (" + folder + ".", e);
160
            }
161
        }
162

  
163
        private void shutdown() {
164
            try {
165
                logger.info("Shutdown the data-base.");
166
                Connection connection = this.ds.getConnection(false);
167
                final Statement statement = connection.createStatement();
168
                statement.execute("SHUTDOWN");
169
                statement.close();
170
                connection.close();
171
            } catch (Exception ex) {
172
                logger.error("Can't shutdown the database.", ex);
173
            }
174
        }
148 175
    }
149
    
176

  
150 177
    /**
151
     * Returns the priority for this data source. This priority is set to a lower value than
152
     * the {@linkplain AccessDataSource}'s one in order to give the priority to the Access-backed
153
     * database, if presents. Priorities are set that way because:
178
     * Returns the priority for this data source. This priority is set to a
179
     * lower value than the {@linkplain AccessDataSource}'s one in order to give
180
     * the priority to the Access-backed database, if presents. Priorities are
181
     * set that way because:
154 182
     * <ul>
155
     *   <li>The MS-Access format is the primary EPSG database format.</li>
156
     *   <li>If a user downloads the MS-Access database himself, he probably wants to use it.</li>
183
     * <li>The MS-Access format is the primary EPSG database format.</li>
184
     * <li>If a user downloads the MS-Access database himself, he probably wants
185
     * to use it.</li>
157 186
     * </ul>
158 187
     */
159 188
    public int getPriority() {
......
161 190
    }
162 191

  
163 192
    /**
164
     * Returns {@code true} if the database contains data. This method returns {@code false}
165
     * if an empty EPSG database has been automatically created by HSQL and not yet populated.
193
     * Returns {@code true} if the database contains data. This method returns
194
     * {@code false} if an empty EPSG database has been automatically created by
195
     * HSQL and not yet populated.
166 196
     */
167 197
    private static boolean dataExists(final Connection connection) throws SQLException {
168 198
        final ResultSet tables = connection.getMetaData().getTables(
169
                null, null, "EPSG_%", new String[] {"TABLE"});
199
                null, null, "EPSG_%", new String[]{"TABLE"});
170 200
        final boolean exists = tables.next();
171 201
        tables.close();
172 202
        return exists;
173 203
    }
174 204

  
175 205
    /**
176
     * Opens a connection to the database. If the cached tables are not available,
177
     * they will be created now from the SQL scripts bundled in this plugin.
206
     * Opens a connection to the database. If the cached tables are not
207
     * available, they will be created now from the SQL scripts bundled in this
208
     * plugin.
178 209
     */
179 210
    public Connection getConnection() throws SQLException {
211
        return getConnection(true);
212
    }
213

  
214
    public Connection getConnection(boolean initialize) throws SQLException {
180 215
        final String database = getDatabase();
181
        if (database==null || database.trim().length()==0) {
216
        if (database == null || database.trim().length() == 0) {
182 217
            /*
183 218
             * The 'database' attribute is unset if the constructor has been unable
184 219
             * to locate the temporary directory, or to create the subdirectory.
185 220
             */
186
            // TODO: localize
187 221
            throw new SQLException("Can't write to the temporary directory.");
188 222
        }
189 223
        Connection connection = super.getConnection();
224
        if (!initialize) {
225
            return connection;
226
        }
190 227
        if (!dataExists(connection)) {
191 228
            /*
192 229
             * HSQL has created automatically an empty database. We need to populate it.
......
194 231
             * a full SQL statement. For this plugin however, we have compressed "INSERT
195 232
             * INTO" statements using Compactor class in this package.
196 233
             */
197
            logger.info("Creating temporary cached EPSG database in '"+getGtTmpDir().getAbsolutePath()+"'."); 
234
            logger.info("Creating temporary cached EPSG database in '" + getGtTmpDir().getAbsolutePath() + "'.");
198 235
            final Statement statement = connection.createStatement();
199 236
            try {
200
                FileInputStream sqlInputStream = new FileInputStream(new File(CrsFactory.getDataBaseFolder(),"EPSG.sql"));
237
                FileInputStream sqlInputStream = new FileInputStream(new File(CrsFactory.getDataBaseFolder(), "EPSG.sql"));
201 238
                final BufferedReader in = new BufferedReader(new InputStreamReader(
202
                		sqlInputStream, "ISO-8859-1"));
203
                
204
//                final BufferedReader in = new BufferedReader(new InputStreamReader(
205
//                        HSQLDataSource.class.getResourceAsStream("EPSG.sql"), "ISO-8859-1"));
206

  
207
                
239
                        sqlInputStream, "ISO-8859-1"));
208 240
                StringBuffer insertStatement = null;
209 241
                String line;
210
                while ((line=in.readLine()) != null) {
242
                while ((line = in.readLine()) != null) {
211 243
                    line = line.trim();
212 244
                    final int length = line.length();
213 245
                    if (length != 0) {
......
228 260
                             */
229 261
                            final int values = insertStatement.length();
230 262
                            insertStatement.append(line);
231
                            final boolean hasMore = (line.charAt(length-1) == ',');
263
                            final boolean hasMore = (line.charAt(length - 1) == ',');
232 264
                            if (hasMore) {
233
                                insertStatement.setLength(insertStatement.length()-1);
265
                                insertStatement.setLength(insertStatement.length() - 1);
234 266
                            }
235 267
                            line = insertStatement.toString();
236 268
                            insertStatement.setLength(values);
......
244 276
                in.close();
245 277
            } catch (IOException exception) {
246 278
                statement.close();
247
                SQLException e = new SQLException("Can't read the SQL script."); // TODO: localize
279
                SQLException e = new SQLException("Can't read the SQL script.");
248 280
                e.initCause(exception);
249 281
                throw e;
250 282
            }
......
257 289
    }
258 290

  
259 291
    /**
260
     * Open a connection and creates an {@linkplain FactoryUsingSQL EPSG factory} for it.
292
     * Open a connection and creates an
293
     * {@linkplain FactoryUsingSQL EPSG factory} for it.
261 294
     *
262
     * @param  factories The low-level factories to use for CRS creation.
295
     * @param factories The low-level factories to use for CRS creation.
263 296
     * @return The EPSG factory using HSQLDB SQL syntax.
264 297
     * @throws SQLException if connection to the database failed.
265 298
     */
266 299
    public AbstractAuthorityFactory createFactory(final FactoryGroup factories) throws SQLException {
267 300
        return new FactoryUsingHSQL(factories, getConnection());
268 301
    }
269
    
302

  
270 303
    public java.util.logging.Logger getParentLogger()
271
    		throws SQLFeatureNotSupportedException {
272
    	// TODO Auto-generated method stub
273
    	return null;
304
            throws SQLFeatureNotSupportedException {
305
        // TODO Auto-generated method stub
306
        return null;
274 307
    }
275
    
308

  
276 309
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
277
    	// TODO Auto-generated method stub
278
    	return false;
310
        // TODO Auto-generated method stub
311
        return false;
279 312
    }
280
    
313

  
281 314
    public <T> T unwrap(Class<T> iface) throws SQLException {
282
    	// TODO Auto-generated method stub
283
    	return null;
315
        // TODO Auto-generated method stub
316
        return null;
284 317
    }
285 318
}
org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.jcrs.lib/src/main/java/org/gvsig/crs/CrsFactory.java
73 73

  
74 74
    private static File databaseFolder = null;
75 75
    private static File projLibFolder = null;
76
    private static boolean enableMemoryCache = true;
76 77

  
77 78
    public CrsFactory() {
78 79
    }
......
86 87
     */
87 88
    public ICrs getCRS(String code) throws CrsException {
88 89

  
89
        /*if (data.containsKey(code))
90
         return (ICrs) data.get(code);*/
90
        if (enableMemoryCache && data.containsKey(code)) {
91
            return (ICrs) data.get(code);
92
        }
91 93
        String repoId = "";
92 94
        String crsCode = "";
93 95
        ICrs crs = null;
......
163 165

  
164 166
            }
165 167

  
166
            /*code = crs.getAbrev();
167

  
168
             data.put(code, crs);*/
168
            if( enableMemoryCache ) {
169
                code = crs.getAbrev();
170
                data.put(code, crs);
171
            }
172
            
169 173
            if ( crs == null ) {
170 174
                logger.debug("Can't find CRS '" + code + "' in available repositories.");
171 175
            } else {
......
269 273
    public static void setProjLibFolder(File folder) {
270 274
        projLibFolder = folder;
271 275
    }
276
    
277
    public static void setEnableMemoryCacheOfCRS(boolean enableMemoryCache) {
278
        CrsFactory.enableMemoryCache = enableMemoryCache;
279
    }
280

  
281
    public static boolean isEnableMemoryCacheOfCRS() {
282
        return enableMemoryCache;
283
    }
272 284
}
org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.jcrs.lib/src/main/java/org/gvsig/crs/repository/UsrRepository.java
64 64

  
65 65
        public void dispose() {
66 66
            try {
67
                this.connection.shutdown();
67
                this.connection.close();
68 68
                this.connection = null;
69 69
            } catch (SQLException ex) {
70 70
                LOG.warn("Con't shutdown the connection.",ex);
org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.jcrs.lib/src/main/java/org/gvsig/crs/repository/EpsgRepository.java
152 152

  
153 153
        public void dispose() {
154 154
            try {
155
                this.connection.shutdown();
155
                this.connection.close();
156 156
                this.connection = null;
157 157
            } catch (SQLException ex) {
158 158
                logger.warn("Can't shutdown the connection.",ex);
org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.jcrs.lib/src/main/java/org/gvsig/crs/repository/NoAuthRepository.java
107 107

  
108 108
        public void dispose() {
109 109
            try {
110
                this.connection.shutdown();
110
                this.connection.close();
111 111
                this.connection = null;
112 112
            } catch (SQLException ex) {
113 113
                logger.warn("Con't shutdown the connection.",ex);
org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.jcrs.lib/src/main/java/org/gvsig/crs/repository/Iau2000Repository.java
117 117

  
118 118
        public void dispose() {
119 119
            try {
120
                this.connection.shutdown();
120
                this.connection.close();
121 121
                this.connection = null;
122 122
            } catch (SQLException ex) {
123 123
                LOG.warn("Con't shutdown the connection.",ex);
org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/org.gvsig.projection.jcrs.lib/src/main/java/org/gvsig/crs/repository/EsriRepository.java
116 116

  
117 117
        public void dispose() {
118 118
            try {
119
                this.connection.shutdown();
119
                this.connection.close();
120 120
                this.connection = null;
121 121
            } catch (SQLException ex) {
122 122
                logger.warn("Con't shutdown the connection.",ex);
org.gvsig.projection.jcrs/trunk/org.gvsig.projection.jcrs/pom.xml
9 9
  <parent>
10 10
    <groupId>org.gvsig</groupId>
11 11
    <artifactId>org.gvsig.desktop</artifactId>
12
    <version>2.0.36</version>
12
    <version>2.0.39</version>
13 13
  </parent>
14 14
  
15 15
  <description>

Also available in: Unified diff