001/* 002 * Copyright 2015 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.core.datasource.dbtype; 017 018import java.io.InputStream; 019import java.io.UnsupportedEncodingException; 020import java.sql.PreparedStatement; 021import java.sql.ResultSet; 022import java.sql.SQLException; 023import java.util.HashMap; 024import java.util.Map; 025import java.util.Set; 026 027import org.ametys.runtime.i18n.I18nizableText; 028import org.ametys.runtime.plugin.component.AbstractThreadSafeComponentExtensionPoint; 029 030/** 031 * This class is in charge to load and initialize the {@link SQLDatabaseType} 032 */ 033public class SQLDatabaseTypeExtensionPoint extends AbstractThreadSafeComponentExtensionPoint<SQLDatabaseType> 034{ 035 /** Avalon Role */ 036 public static final String ROLE = SQLDatabaseTypeExtensionPoint.class.getName(); 037 038 @Override 039 public void initializeExtensions() throws Exception 040 { 041 super.initializeExtensions(); 042 043 for (String databaseTypeId : getExtensionsIds()) 044 { 045 SQLDatabaseType databaseType = getExtension(databaseTypeId); 046 047 try 048 { 049 Class.forName(databaseType.getDriver()); 050 } 051 catch (ClassNotFoundException e) 052 { 053 getLogger().warn("JDBC Driver cannot be found for extension '" + databaseTypeId + "' with classname '" + databaseType.getDriver() + "'"); 054 } 055 } 056 } 057 058 /** 059 * Get the SQL database types with their label 060 * @return the SQL database types with their label 061 */ 062 public Map<String, I18nizableText> getSQLDatabaseTypes() 063 { 064 Map<String, I18nizableText> db = new HashMap<>(); 065 066 Set<String> extensionsIds = getExtensionsIds(); 067 for (String extensionId : extensionsIds) 068 { 069 SQLDatabaseType dbType = getExtension(extensionId); 070 db.put(extensionId, dbType.getLabel()); 071 } 072 073 return db; 074 } 075 076 /** 077 * Some db systems requires the table names to be escaped 078 * @param dbType The identifier of the db type used 079 * @param tableNameToEscape The non-null table name 080 * @return The escaped table name or at least the table name if no escape is required. Or null if the dbtype is unknown. 081 */ 082 public String languageEscapeTableName(String dbType, String tableNameToEscape) 083 { 084 if (hasExtension(dbType)) 085 { 086 return getExtension(dbType).languageEscapeTableName(tableNameToEscape); 087 } 088 else 089 { 090 return null; 091 } 092 } 093 094 /** 095 * Add a limit/offset element to the given query 096 * @param dbType The identifier of the db type used 097 * @param queryToLimit The sql query that will be amended 098 * @param limit The max number of the results to return 099 * @param offset The initial offset of the results to return 100 * @return The initial query amended to handle the limit and offset. Or null if the dbtype is unknown. 101 */ 102 public String languageLimitQuery(String dbType, String queryToLimit, String limit, String offset) 103 { 104 if (hasExtension(dbType)) 105 { 106 return getExtension(dbType).languageLimitQuery(queryToLimit, limit, offset); 107 } 108 else 109 { 110 return null; 111 } 112 } 113 114 /** 115 * Get the InputStream to read a blob 116 * @param dbType The identifier of the db type used 117 * @param resultSet the result set containing the blob. 118 * @param columnName column 119 * @return an InputStream to read the blob 120 * @throws SQLException if the columnLabel is not valid; if a database access error occurs or this method is called on a closed result set 121 */ 122 public InputStream getBlob(String dbType, ResultSet resultSet, String columnName) throws SQLException 123 { 124 if (hasExtension(dbType)) 125 { 126 return getExtension(dbType).getBlob(resultSet, columnName); 127 } 128 else 129 { 130 return null; 131 } 132 } 133 134 /** 135 * Get the InputStream to read a blob 136 * @param dbType The identifier of the db type used 137 * @param resultSet the result set containing the blob. 138 * @param pos column position 139 * @return an InputStream to read the blob 140 * @throws SQLException if the columnLabel is not valid; if a database access error occurs or this method is called on a closed result set 141 */ 142 public InputStream getBlob(String dbType, ResultSet resultSet, int pos) throws SQLException 143 { 144 if (hasExtension(dbType)) 145 { 146 return getExtension(dbType).getBlob(resultSet, pos); 147 } 148 else 149 { 150 return null; 151 } 152 } 153 154 /** 155 * Set an String into a blob 156 * @param dbType The identifier of the db type used 157 * @param statement The satement where the blob will be set 158 * @param pos position in the statement 159 * @param blob String representing the blob 160 * @throws SQLException if the columnLabel is not valid; if a database access error occurs or this method is called on a closed result set 161 * @throws UnsupportedEncodingException if UTF-8 is not supported 162 * @throws IllegalArgumentException if the dbType is not found 163 */ 164 public void setBlob(String dbType, PreparedStatement statement, int pos, String blob) throws SQLException, UnsupportedEncodingException, IllegalArgumentException 165 { 166 if (hasExtension(dbType)) 167 { 168 getExtension(dbType).setBlob(statement, pos, blob); 169 } 170 else 171 { 172 throw new IllegalArgumentException("Database of type '" + dbType + "' is not supported"); 173 } 174 } 175 176 /** 177 * Set an array of bytes (UTF-8 encoded) into a blob, if you want to pass a String, you can use {@link #setBlob(String, PreparedStatement, int, String)} 178 * @param dbType The identifier of the db type used 179 * @param statement The satement where the blob will be set 180 * @param pos position in the statement 181 * @param bytes byte[] representing the blob, in UTF-8 182 * @throws SQLException if the columnLabel is not valid; if a database access error occurs or this method is called on a closed result set 183 * @throws IllegalArgumentException if the dbType is not found 184 */ 185 public void setBlob(String dbType, PreparedStatement statement, int pos, byte[] bytes) throws SQLException, IllegalArgumentException 186 { 187 if (hasExtension(dbType)) 188 { 189 getExtension(dbType).setBlob(statement, pos, bytes); 190 } 191 else 192 { 193 throw new IllegalArgumentException("Database of type '" + dbType + "' is not supported"); 194 } 195 } 196 197 198 199 /** 200 * Set an array of bytes (UTF-8 encoded) into a blob, if you want to pass a String, you can use {@link #setBlob(String, PreparedStatement, int, String)} 201 * @param dbType The identifier of the db type used 202 * @param statement The satement where the blob will be set 203 * @param pos position in the statement 204 * @param is inputStream to put in the blob 205 * @param length length of the stream 206 * @throws SQLException if the columnLabel is not valid; if a database access error occurs or this method is called on a closed result set 207 * @throws IllegalArgumentException if the dbType is not found 208 */ 209 public void setBlob(String dbType, PreparedStatement statement, int pos, InputStream is, long length) throws SQLException, IllegalArgumentException 210 { 211 if (hasExtension(dbType)) 212 { 213 getExtension(dbType).setBlob(statement, pos, is, length); 214 } 215 else 216 { 217 throw new IllegalArgumentException("Database of type '" + dbType + "' is not supported"); 218 } 219 } 220}