View Javadoc

1   /*
2    * Copyright 2004-2006 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.tuigwaa.database;
17  
18  import java.sql.Connection;
19  import java.sql.DatabaseMetaData;
20  import java.sql.ResultSet;
21  import java.sql.SQLException;
22  import java.util.ArrayList;
23  import java.util.HashMap;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.hibernate.util.StringHelper;
31  import org.seasar.framework.exception.SQLRuntimeException;
32  import org.seasar.tuigwaa.system.Constants;
33  import org.seasar.tuigwaa.util.ajax.AjaxEvent;
34  import org.seasar.tuigwaa.util.ajax.Ajaxlizable;
35  import org.seasar.tuigwaa.util.ajax.SharedObjects;
36  
37  
38  /***
39   * @author someda
40   */
41  public class DatabaseInfo implements Ajaxlizable {
42  
43  	private static final String[] COLUMN_TYPES = { "TABLE" };
44  
45  	private static final String COLUMN_TABLENAME = "TABLE_NAME";
46  
47  	private static final String COLUMN_TABLESCHEMA = "TABLE_SCHEM";
48  
49  	private static final String COLUMN_PKTABLE = "PKTABLE_NAME";
50  
51  	private static final String COLUMN_NAME = "COLUMN_NAME";
52  
53  	private String name;
54  
55  	private String databasename;
56  
57  	private String version;
58  
59  	private String url;
60  
61  	private String username;
62  
63  	private String drivername;
64  
65  	private DatabaseMetaData metadata;
66  
67  	private Log log_ = LogFactory.getLog(getClass());
68  
69  	public DatabaseInfo(Connection con) throws SQLException {
70  		try {
71  			this.metadata = con.getMetaData();
72  			init();
73  		} catch (SQLException se) {
74  			throw se;
75  		}
76  	}
77  
78  	public DatabaseInfo(DatabaseMetaData metadata) {
79  		this.metadata = metadata;
80  		init();
81  	}
82  
83  	public boolean isSharable() {
84  		return false;
85  	}
86  	
87  	public void addEvent(AjaxEvent event) {
88  	}
89  	
90  	public String getSharedKey() {
91  		return null;
92  	}
93  	
94  	public void setSharedObject(SharedObjects objs) {
95  	}
96  	
97  	private void init() {
98  		if (metadata != null) {
99  			try {
100 				databasename = metadata.getDatabaseProductName();
101 				version = metadata.getDatabaseProductVersion();
102 				url = metadata.getURL();
103 				username = metadata.getUserName();
104 				drivername = metadata.getDriverName();
105 			} catch (SQLException se) {
106 				log_.error(se.getMessage());
107 			}
108 		}
109 	}
110 
111 	// ----- [Start] setters and getters -----
112 
113 	public void setName(String name) {
114 		this.name = name;
115 	}
116 
117 	public String getName() {
118 		return name;
119 	}
120 
121 	public String getDatabasename() {
122 		return databasename;
123 	}
124 
125 	public void setDatabasename(String databasename) {
126 		this.databasename = databasename;
127 	}
128 
129 	public String getVersion() {
130 		return version;
131 	}
132 
133 	public void setVersion(String version) {
134 		this.version = version;
135 	}
136 
137 	public String getUrl() {
138 		return url;
139 	}
140 
141 	public void setUrl(String url) {
142 		this.url = url;
143 	}
144 
145 	public String getUsername() {
146 		return username;
147 	}
148 
149 	public void setUsername(String username) {
150 		this.username = username;
151 	}
152 
153 	public String getDrivername() {
154 		return drivername;
155 	}
156 
157 	public void setDrivername(String drivername) {
158 		this.drivername = drivername;
159 	}
160 
161 	// ----- [End] setters and getters -----
162 
163 	public List getTablenameNames(String schema) {
164 		List list = new ArrayList();
165 
166 		try {
167 			ResultSet rs = null;
168 			try {
169 				if (metadata.storesUpperCaseIdentifiers()) {
170 					rs = metadata.getTables(null, StringHelper
171 							.toUpperCase(schema), null, COLUMN_TYPES);
172 				} else if (metadata.storesLowerCaseIdentifiers()) {
173 					rs = metadata.getTables(null, StringHelper
174 							.toLowerCase(schema), null, COLUMN_TYPES);
175 				} else {
176 					rs = metadata.getTables(null, schema, null, COLUMN_TYPES);
177 				}
178 				while (rs.next()) {
179 					String tableName = rs.getString(COLUMN_TABLENAME);
180 					list.add(tableName);
181 				}
182 			} finally {
183 				if (rs != null)
184 					rs.close();
185 			}
186 		} catch (SQLException e) {
187 			log_.error(e.getMessage());
188 			throw new RuntimeException(e);
189 		}
190 		return list;
191 	}
192 
193 	public List getSchemaNames() {
194 		List list = new ArrayList();
195 
196 		try {
197 			ResultSet rs = null;
198 			try {
199 				rs = metadata.getSchemas();
200 				while (rs.next()) {
201 					String schemaName = rs.getString(COLUMN_TABLESCHEMA);
202 					list.add(schemaName);
203 				}
204 			} finally {
205 				if (rs != null)
206 					rs.close();
207 			}
208 		} catch (SQLException e) {
209 			log_.error(e.getMessage());
210 			throw new RuntimeException(e);
211 		}
212 		return list;
213 	}
214 
215 	public String getTableNamesByAjax(String schema) {
216 
217 		StringBuffer buf = new StringBuffer();
218 		List list = getTablenameNames(schema);
219 		if (list != null) {
220 			buf.append("<ul>");
221 			for (Iterator i = list.iterator(); i.hasNext();) {
222 				String table = (String) i.next();
223 				if (schema.equalsIgnoreCase("public")) {
224 					buf.append("<li>" + table + "</li>");
225 				} else {
226 					if (table.endsWith("_"))
227 						table = table.substring(0, table.length() - 1);
228 					String path = "../" + schema.toLowerCase()
229 							+ "/listRecord.do?" + Constants.PARAM_ENTITY_NAME
230 							+ "=" + table.toLowerCase();
231 					buf.append("<li><a href=\"" + path + "\">" + table
232 							+ "</a></li>");
233 				}
234 			}
235 			buf.append("</ul>");
236 		}
237 		return buf.toString();
238 	}
239 
240 	public void sortByReference(String catalog, String schema, List tableList,
241 			List processList) {
242 
243 		if (processList == null)
244 			throw new IllegalArgumentException("processList must not be null.");
245 
246 		if (tableList.size() == 0)
247 			return;
248 
249 		try {
250 			for (int i = 0; i < tableList.size(); i++) {
251 				String table = (String) tableList.get(i);
252 				ResultSet rs = null;
253 
254 				try {
255 
256 					List fks = getForeignKeys(catalog, schema, table);
257 
258 					if (fks.size() == 0) {
259 						processList.add(table);
260 						tableList.remove(table);
261 						i--;
262 					} else {
263 						boolean allcontained = true;
264 						for (Iterator j = fks.iterator(); j.hasNext();) {
265 							String fkname = (String) j.next();
266 							if (!processList.contains(fkname)) {
267 								allcontained = false;
268 								break;
269 							}
270 						}
271 						if (allcontained) {
272 							processList.add(table);
273 							tableList.remove(table);
274 							i--;
275 						}
276 					}
277 				} finally {
278 					if (rs != null)
279 						rs.close();
280 				}
281 			}
282 			if (tableList.size() != 0)
283 				sortByReference(catalog, schema, tableList, processList);
284 
285 		} catch (SQLException se) {
286 			se.printStackTrace();
287 		}
288 	}
289 
290 	public List getForeignKeys(String catalog, String schema, String tableName) {
291 		List fks = new ArrayList();
292 		try {
293 			ResultSet rs = null;
294 			if (metadata.storesUpperCaseIdentifiers()) {
295 				rs = metadata.getImportedKeys(
296 						StringHelper.toUpperCase(catalog), StringHelper
297 								.toUpperCase(schema), StringHelper
298 								.toUpperCase(tableName));
299 			} else if (metadata.storesLowerCaseIdentifiers()) {
300 				rs = metadata.getImportedKeys(
301 						StringHelper.toLowerCase(catalog), StringHelper
302 								.toLowerCase(schema), StringHelper
303 								.toLowerCase(tableName));
304 			} else {
305 				rs = metadata.getImportedKeys(catalog, schema, tableName);
306 			}
307 
308 			while (rs.next()) {
309 				String fkname = rs.getString(COLUMN_PKTABLE);
310 				if (log_.isDebugEnabled())
311 					log_.debug(tableName + " references " + fkname);
312 				fks.add(fkname);
313 			}
314 		} catch (SQLException e) {
315 			e.printStackTrace();
316 		}
317 		return fks;
318 	}
319 
320 	public Map getForeignKeyInfoMap(String catalog, String schema, String tableName) {
321 		Map map = new HashMap();
322 		try {
323 			ResultSet rs = null;
324 			if (metadata.storesUpperCaseIdentifiers()) {
325 				rs = metadata.getImportedKeys(
326 						StringHelper.toUpperCase(catalog), StringHelper
327 								.toUpperCase(schema), StringHelper
328 								.toUpperCase(tableName));
329 			} else if (metadata.storesLowerCaseIdentifiers()) {
330 				rs = metadata.getImportedKeys(
331 						StringHelper.toLowerCase(catalog), StringHelper
332 								.toLowerCase(schema), StringHelper
333 								.toLowerCase(tableName));
334 			} else {
335 				rs = metadata.getImportedKeys(catalog, schema, tableName);
336 			}
337 
338 			while (rs.next()) {
339 				ForeignKeyInfo info = new ForeignKeyInfo(rs);
340 				map.put(info.getColumnName(), info);
341 			}
342 		} catch (SQLException e) {
343 			e.printStackTrace();
344 		}
345 		return map;
346 	}
347 
348 	public List getPrimaryKeys(String catalog, String schema, String tableName) {
349 		List pks = new ArrayList();
350 		try {
351 			ResultSet rs = null;
352 			if (metadata.storesUpperCaseIdentifiers()) {
353 				rs = metadata.getPrimaryKeys(StringHelper.toUpperCase(catalog),
354 						StringHelper.toUpperCase(schema), StringHelper
355 								.toUpperCase(tableName));
356 			} else if (metadata.storesLowerCaseIdentifiers()) {
357 				rs = metadata.getPrimaryKeys(StringHelper.toLowerCase(catalog),
358 						StringHelper.toLowerCase(schema), StringHelper
359 								.toLowerCase(tableName));
360 			} else {
361 				rs = metadata.getPrimaryKeys(catalog, schema, tableName);
362 			}
363 
364 			while (rs.next()) {
365 				String pkname = rs.getString(COLUMN_NAME);
366 				if (log_.isDebugEnabled())
367 					log_.debug(tableName + " references " + pkname);
368 				pks.add(pkname);
369 			}
370 		} catch (SQLException e) {
371 			e.printStackTrace();
372 		}
373 		
374 		
375 		return pks;
376 	}
377 	
378 
379 	public static class ForeignKeyInfo{
380 		
381 		private String columnName;
382 		
383 		private String referenceTableName;
384 		
385 		private String referecneColumnName;
386 		
387 		ForeignKeyInfo(ResultSet rs){
388 			try {
389 				this.referenceTableName = rs.getString("PKTABLE_NAME");
390 				this.referecneColumnName = rs.getString("PKCOLUMN_NAME");
391 				this.columnName = rs.getString("FKCOLUMN_NAME");
392 			} catch (SQLException e) {
393 				throw new SQLRuntimeException(e);
394 			}
395 		}
396 		
397 		public String getColumnName() {
398 			return columnName;
399 		}
400 		
401 		public String getReferecneColumnName() {
402 			return referecneColumnName;
403 		}
404 		
405 		public String getReferenceTableName() {
406 			return referenceTableName;
407 		}
408 		
409 	}
410 }