001/* 002 * Copyright (c) 2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.ecoinformatics.seek.dataquery; 031 032import java.sql.SQLException; 033 034import org.apache.commons.logging.Log; 035import org.apache.commons.logging.LogFactory; 036import org.kepler.objectmanager.data.db.Entity; 037 038/** 039 * This class will try to generate a unique table name base on a given 040 * TableEntity object. 041 * 042 * @author Jing Tao 043 * 044 */ 045public class DBTableNameResolver { 046 private static final String PREFIX = "T"; 047 048 private static Log log; 049 private static boolean isDebugging; 050 051 static { 052 log = LogFactory.getLog("org.ecoinformatics.seek.dataquery"); 053 isDebugging = log.isDebugEnabled(); 054 } 055 056 /** 057 * If the url in this TableEntity is null, we will use the TableEntity name 058 * as url. First we will check if the url is already in the system table 059 * which store the url and table mapping. If the url already existed, the 060 * table name will be set as the table name stored in system table. If the 061 * url doesn't exited, the hashcode of this url (add profix "T") as table 062 * name. 063 * 064 * @param table 065 * TableEntity 066 * @throws SQLException 067 * @throws ClassNotFoundException 068 * @return TableEntity 069 */ 070 public Entity resolveTableName(Entity table) throws SQLException, 071 ClassNotFoundException { 072 String newTableName = null; 073 String url = table.getURL(); 074 if (url == null) { 075 url = table.getName(); 076 } 077 // check if the url already existed in system table 078 DBTableExistenceChecker checker = new DBTableExistenceChecker(); 079 // if the table already existed, we don't need 080 // generate table name again(url is the key) 081 if (checker.isURLExisted(url)) { 082 // to do get the table name and set to table entity 083 newTableName = checker.getTableName(url); 084 if (isDebugging) { 085 log 086 .debug("Get the table name for system table " 087 + newTableName); 088 } 089 table.setDBTableName(newTableName); 090 return table; 091 } 092 // if this is a record we need to generate the tablename 093 newTableName = generateTableName(table); 094 table.setDBTableName(newTableName); 095 return table; 096 } 097 098 /* 099 * Method to generate a talbe name base a given TableEnity object. Now it 100 * use url to generate hash and add a given letter in first position. If the 101 * generate table name already in persistant table, it will append random 102 * strings 103 */ 104 private String generateTableName(Entity table) throws SQLException, 105 ClassNotFoundException { 106 int maxTime = 5; 107 108 String tableName = null; 109 String url = table.getURL(); 110 // if url is null, set url as same as entity name 111 if (url == null) { 112 url = table.getName(); 113 } 114 int hashNumber = url.hashCode(); 115 // remove "-" because hsql doesn't allow it in table name 116 hashNumber = removeNegativeSymbolFromHashNumber(hashNumber); 117 if (isDebugging) { 118 log.debug("The hash number is " + hashNumber); 119 } 120 tableName = PREFIX + hashNumber; 121 // check if the generate table already existed, if exited, append some 122 // random character. If the while loop runs > maxTime times, throw a 123 // exception 124 DBTableExistenceChecker checker = new DBTableExistenceChecker(); 125 int times = 0; 126 while (checker.isTableNameExisted(tableName)) { 127 String random = generateRandomString(); 128 tableName = tableName + random; 129 times++; 130 if (times > maxTime) { 131 throw new SQLException( 132 "Couldn't generate a non duplicate table name"); 133 } 134 } 135 if (isDebugging) { 136 log.debug("The table name is " + tableName); 137 } 138 return tableName; 139 }// generateTableName 140 141 /* 142 * method to generate a random string which lenght is between 1 to 10. 143 */ 144 private String generateRandomString() { 145 String randomString = ""; 146 char[] letters = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 147 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 148 'w', 'x', 'y', 'z' }; 149 int length = (new Double(Math.random() * 10)).intValue() + 1; 150 if (isDebugging) { 151 log.debug("The appendix string lenghth is " + length); 152 } 153 for (int i = 0; i < length; i++) { 154 int random = (new Double(Math.random() * 26)).intValue(); 155 if (random >= 25) { 156 random = 25; 157 } 158 char selectChar = letters[random]; 159 randomString = randomString + selectChar; 160 } 161 if (isDebugging) { 162 log.debug("the random string is " + randomString); 163 } 164 return randomString; 165 }// generateRandomString 166 167 /* 168 * Method to remove negative symbol for hash number. Table name doesn't 169 * allow "-" in hsql 170 */ 171 private int removeNegativeSymbolFromHashNumber(int hashNumber) { 172 int newHashNumber = hashNumber; 173 String hashNumberString = (new Integer(hashNumber)).toString(); 174 if (isDebugging) { 175 log.debug("transform hashnumber from int " + hashNumber 176 + " to string " + hashNumberString); 177 } 178 if (hashNumberString != null && hashNumberString.startsWith("-")) { 179 hashNumberString = hashNumberString.substring(1); 180 if (isDebugging) { 181 log.debug("The new string after removing negative symbol is " 182 + hashNumberString); 183 } 184 newHashNumber = (new Integer(hashNumberString)).intValue(); 185 186 } 187 if (isDebugging) { 188 log.debug("The new hash number after removing netative symbol is " 189 + newHashNumber); 190 } 191 return newHashNumber; 192 }// removeNegativeSymbolFromHashNumber 193 194}