/* =============================================================================== * * Part of the InfoGlue Content Management Platform (www.infoglue.org) * * =============================================================================== * * Copyright (C) * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2, as published by the * Free Software Foundation. See the file LICENSE.html for more information. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple * Place, Suite 330 / Boston, MA 02111-1307 / USA. * * =============================================================================== */ package org.infoglue.cms.util.workflow; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.sql.Blob; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.sql.Types; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.commons.dbcp.ConnectionFactory; import org.apache.commons.dbcp.DriverManagerConnectionFactory; import org.apache.commons.dbcp.PoolableConnectionFactory; import org.apache.commons.dbcp.PoolingDriver; import org.apache.commons.pool.ObjectPool; import org.apache.commons.pool.impl.GenericObjectPool; import org.apache.log4j.Logger; import org.dom4j.Document; import org.dom4j.Element; import org.infoglue.cms.controllers.kernel.impl.simple.CastorDatabaseService; import org.infoglue.cms.controllers.kernel.impl.simple.InstallationController; import org.infoglue.cms.io.FileHelper; import org.infoglue.cms.util.CmsPropertyHandler; import org.infoglue.cms.util.dom.DOMBuilder; import org.infoglue.deliver.util.NullObject; import org.infoglue.deliver.util.Timer; import com.opensymphony.module.propertyset.InvalidPropertyTypeException; import com.opensymphony.module.propertyset.PropertyException; import com.opensymphony.module.propertyset.PropertySet; import com.opensymphony.module.propertyset.database.JDBCPropertySet; import com.opensymphony.util.Data; /** * This is an implementation of a property set manager for JDBC. * * @author Mattias Bogeblad */ public class InfoGlueJDBCPropertySet extends JDBCPropertySet { private final static Logger logger = Logger.getLogger(InfoGlueJDBCPropertySet.class.getName()); private static GenericObjectPool connectionPool = null; private static ConnectionFactory connectionFactory = null; private static PoolableConnectionFactory poolableConnectionFactory = null; private static PoolingDriver driver = null; String colData; String colDate; String colFloat; String colGlobalKey; String colItemKey; String colItemType; String colNumber; String colString; private String userName; private String password; private String driverClassName; private String url; private String dbcpWhenExhaustedAction = null; private String dbcpMaxActive = null; private String dbcpMaxWait = null; private String dbcpMaxIdle = null; private String dbcpValidationQuery = null; // args String globalKey; String tableName; private boolean enableCache = true; private boolean allKeysCachedType5 = false; private boolean allKeysCachedType10 = false; private static boolean isRecacheCall = false; private static boolean reloadConfiguration = false; private static Map type5Map = null; private static Map type10Map = null; private static Map valueMapType5 = null; private static Map valueMapType10 = null; private static InfoGlueJDBCPropertySet instance = null; private static Map typeMap5Fallback = null; private static Map valueMap5Fallback = null; private static Map typeMap10Fallback = null; private static Map valueMap10Fallback = null; //~ Methods //////////////////////////////////////////////////////////////// public Collection getKeys(String prefix, int type) throws PropertyException { if(wasDatabaseFaulty) return new ArrayList(); Timer t = new Timer(); //System.out.println("isRecacheCall:" + isRecacheCall); //valueMapType5 == null && !allKeysCachedType5 Map currentType5Map = type5Map; Map currentValue5Map = valueMapType5; Map currentType10Map = type10Map; Map currentValue10Map = valueMapType10; if (prefix == null) { prefix = ""; } Connection conn = null; try { //System.out.println("Getting keys with prefix:" + prefix + " and type: " + type + " and globalKey:" + globalKey); logger.info("Getting keys with prefix:" + prefix + " and type: " + type + " and globalKey:" + globalKey); conn = getConnection(); //t.printElapsedTime("Connection took.."); if(conn == null) { System.out.println("braking as connection was not yet ready"); throw new PropertyException("Problem getting connection"); } PreparedStatement ps = null; //String sql = "SELECT " + colItemKey + "," + colItemType + ", " + colString + ", " + colDate + ", " + colData + ", " + colFloat + ", " + colNumber + " FROM " + tableName + " WHERE " + colItemKey + " LIKE ? AND " + colGlobalKey + " = ?"; String sql = "SELECT " + colItemKey + "," + colItemType + ", " + colString + ", " + colDate + ", " + colData + ", " + colFloat + ", " + colNumber + " FROM " + tableName; if(type != 10) { sql = "SELECT " + colItemKey + "," + colItemType + ", " + colString + ", " + colDate + ", '' AS " + colData + ", " + colFloat + ", " + colNumber + " FROM " + tableName; } sql += " WHERE "; sql += "((" + colItemKey + " NOT LIKE 'content_%' AND "; sql += "" + colItemKey + " NOT LIKE 'principal_%' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_WYSIWYGConfig' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_StylesXML' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_defaultFolderContentTypeName' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_defaultTemplateRepository' AND "; sql += "" + colItemKey + " NOT LIKE 'siteNode_%_enabledLanguages' AND "; sql += "" + colItemKey + " NOT LIKE 'siteNode_%_disabledLanguages') OR "; sql += "(" + colItemKey + " LIKE 'siteNode_%_enabledLanguages' AND string_val <> '') OR "; sql += "(" + colItemKey + " LIKE 'siteNode_%_disabledLanguages' AND string_val <> '')) AND "; sql += "" + colGlobalKey + " = ? "; //System.out.println("sql:" + sql); if(logger.isInfoEnabled()) { logger.info("app:" + CmsPropertyHandler.getApplicationName()); logger.info("operating mode:" + CmsPropertyHandler.getOperatingMode()); } /* if(CmsPropertyHandler.getApplicationName().equalsIgnoreCase("deliver") && CmsPropertyHandler.getOperatingMode().equalsIgnoreCase("3")) { sql = "SELECT " + colItemKey + "," + colItemType + ", " + colString + ", " + colDate + ", " + colData + ", " + colFloat + ", " + colNumber + " FROM " + tableName; sql += " WHERE "; sql += "" + colItemKey + " LIKE ? AND "; sql += "" + colItemKey + " NOT LIKE 'principal_%_languageCode' AND "; sql += "" + colItemKey + " NOT LIKE 'principal_%_defaultToolId' AND "; sql += "" + colItemKey + " NOT LIKE 'content_%_allowedContentTypeNames' AND "; sql += "" + colItemKey + " NOT LIKE 'content_%_defaultContentTypeName' AND "; sql += "" + colItemKey + " NOT LIKE 'content_%_initialLanguageId' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_defaultFolderContentTypeName' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_defaultTemplateRepository' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_parentRepository' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_WYSIWYGConfig' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_StylesXML' AND "; sql += "" + colItemKey + " NOT LIKE 'repository_%_extraProperties' AND "; sql += "" + colGlobalKey + " = ? "; } */ if(logger.isInfoEnabled()) logger.info("sql:" + sql); //System.out.println("sql:" + sql); if (type == 0) { //System.out.println("conn:" + conn); //System.out.println("sql:" + sql); ps = conn.prepareStatement(sql); //ps.setString(1, prefix + "%"); //ps.setString(2, globalKey); ps.setString(1, globalKey); //System.out.println("arg1:" + prefix + "%"); //System.out.println("arg2:" + globalKey); } else { sql = sql + " AND " + colItemType + " = ?"; ps = conn.prepareStatement(sql); ps.setString(1, prefix + "%"); ps.setString(2, globalKey); ps.setInt(3, type); //System.out.println("arg1:" + prefix + "%"); //System.out.println("arg2:" + globalKey); //System.out.println("arg3:" + type); } ArrayList list = new ArrayList(); ResultSet rs = ps.executeQuery(); logger.info("All rows " + sql); int rows = 0; while (rs.next()) { rows++; String key = rs.getString(colItemKey); int typeId = rs.getInt(colItemType); //System.out.println("key[" + typeId + "]:" + key); if(logger.isInfoEnabled()) logger.info("key[" + typeId + "]:" + key); list.add(key); if(type == 5 && type5Map == null) type5Map = new HashMap(); if(type == 5 && typeMap5Fallback == null) typeMap5Fallback = new HashMap(); if(type == 10 && type10Map == null) type10Map = new HashMap(); if(type == 10 && typeMap10Fallback == null) typeMap10Fallback = new HashMap(); currentType5Map = type5Map; currentType10Map = type10Map; if(isRecacheCall) { currentType5Map = typeMap5Fallback; currentType10Map = typeMap10Fallback; } if(type == 5) { synchronized (currentType5Map) { currentType5Map.put(key, new Integer(typeId)); } } if(type == 10) { synchronized (currentType10Map) { currentType10Map.put(key, new Integer(typeId)); } } Object o = null; switch (typeId) { case PropertySet.BOOLEAN: int boolVal = rs.getInt(colNumber); o = new Boolean(boolVal == 1); break; case PropertySet.DATA: { //Ugly fix for old type of column in oracle which we used to run LONG RAW. We converted to blob and the code is different String columnTypeName = rs.getMetaData().getColumnTypeName(5); logger.info("columnTypeName: " + columnTypeName); if(this.driverClassName.indexOf("oracle") > -1 && columnTypeName != null && columnTypeName.indexOf("RAW") == -1) { //System.out.println("Getting as blob"); Blob blob = rs.getBlob(colData); //System.out.println("blob:" + blob); if(blob != null) { try { InputStream in = blob.getBinaryStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[(int)blob.length()]; InputStream is = in; while (is.read(buffer) > 0) { baos.write(buffer); } baos.flush(); String s = baos.toString(); //System.out.println("S: " + s + "..."); o = s.getBytes(); } catch (Exception e) { e.printStackTrace(); } } else { o = null; } } else { //System.out.println("Getting as raw bytes:" + key); o = rs.getBytes(colData); } break; } case PropertySet.DATE: o = rs.getTimestamp(colDate); break; case PropertySet.DOUBLE: o = new Double(rs.getDouble(colFloat)); break; case PropertySet.INT: o = new Integer(rs.getInt(colNumber)); break; case PropertySet.LONG: o = new Long(rs.getLong(colNumber)); break; case PropertySet.STRING: o = rs.getString(colString); break; default: logger.info("JDBCPropertySet doesn't support this type yet:" + key + ":" + typeId); } if(type != 10 && valueMapType5 == null) valueMapType5 = new HashMap(); if(type != 10 && valueMap5Fallback == null) valueMap5Fallback = new HashMap(); if(type == 10 && valueMapType10 == null) valueMapType10 = new HashMap(); if(type == 10 && valueMap10Fallback == null) valueMap10Fallback = new HashMap(); currentValue5Map = valueMapType5; currentValue10Map = valueMapType10; if(isRecacheCall) { currentValue5Map = valueMap5Fallback; currentValue10Map = valueMap10Fallback; } //System.out.println("Caching:" + key + "=" + o + "(type " + type + ")"); if(type != 10) { synchronized (currentValue5Map) { currentValue5Map.put(key, o); } } if(type == 10) { synchronized (currentValue10Map) { currentValue10Map.put(key, o); } } } logger.warn("All rows in InfoGlueJDBCPropertySet [" + rows + "] took: " + t.getElapsedTime()); allKeysCachedType5 = true; if(type == 10) allKeysCachedType10 = true; if(isRecacheCall) { //System.out.println("Switching valueMap from:" + valueMap.hashCode() + " --> " + currentValueMap.hashCode()); type5Map = currentType5Map; valueMapType5 = currentValue5Map; typeMap5Fallback = new HashMap(); valueMap5Fallback = new HashMap(); type10Map = currentType10Map; valueMapType10 = currentValue10Map; typeMap10Fallback = new HashMap(); valueMap10Fallback = new HashMap(); } rs.close(); ps.close(); return list; } catch (SQLException e) { logger.error("Problem getting keys due to an SQL exception:" + e.getCause().getMessage(), e); throw new PropertyException(e.getMessage()); } catch (PropertyException pe) { //logger.error("Problem getting keys due to unavailable connection:" + e.getCause().getMessage()); throw new PropertyException(pe.getMessage()); } catch (Throwable tr) { logger.error("Problem getting keys:" + tr.getMessage(), tr); throw new PropertyException(tr.getMessage()); } /* catch (UnsupportedEncodingException ue) { throw new PropertyException(ue.getMessage()); } */ finally { closeConnection(conn); isRecacheCall = false; } } public int getType(String key) throws PropertyException { Connection conn = null; if(enableCache && type5Map != null) { synchronized (type5Map) { Integer typeInteger = (Integer)type5Map.get(key); if(typeInteger != null) { return typeInteger.intValue(); } } } if(enableCache && type10Map != null) { synchronized (type10Map) { Integer typeInteger = (Integer)type10Map.get(key); if(typeInteger != null) { return typeInteger.intValue(); } } } try { conn = getConnection(); //System.out.println("globalKey:" + globalKey); //System.out.println("key:" + key); String sql = "SELECT " + colItemType + " FROM " + tableName + " WHERE " + colGlobalKey + " = ? AND " + colItemKey + " = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, globalKey); ps.setString(2, key); ResultSet rs = ps.executeQuery(); int type = 0; if (rs.next()) { type = rs.getInt(colItemType); } rs.close(); ps.close(); return type; } catch (SQLException e) { throw new PropertyException(e.getMessage()); } finally { closeConnection(conn); } } public boolean exists(String key) throws PropertyException { return getType(key) != 0; } public void init(Map config, Map args) { reloadConfiguration = false; // args globalKey = (String) args.get("globalKey"); tableName = (String) config.get("table.name"); colGlobalKey = (String) config.get("col.globalKey"); colItemKey = (String) config.get("col.itemKey"); colItemType = (String) config.get("col.itemType"); colString = (String) config.get("col.string"); colDate = (String) config.get("col.date"); colData = (String) config.get("col.data"); colFloat = (String) config.get("col.float"); colNumber = (String) config.get("col.number"); this.userName = (String) config.get("username"); this.password = (String) config.get("password"); this.driverClassName = (String) config.get("driverClassName"); this.url = (String) config.get("url"); if(this.url.equalsIgnoreCase("@database.url@")) reloadConfiguration = true; this.dbcpWhenExhaustedAction = (String) config.get("dbcp.whenExhaustedAction"); this.dbcpMaxActive = (String) config.get("dbcp.maxActive"); this.dbcpMaxWait = (String) config.get("dbcp.maxWait"); this.dbcpMaxIdle = (String) config.get("dbcp.maxIdle"); this.dbcpValidationQuery = (String) config.get("dbcp.validationQuery"); if(this.dbcpWhenExhaustedAction != null && (this.dbcpWhenExhaustedAction.length() == 0 || this.dbcpWhenExhaustedAction.indexOf("@") > -1)) this.dbcpWhenExhaustedAction = null; if(this.dbcpMaxActive != null && (this.dbcpMaxActive.length() == 0 || this.dbcpMaxActive.indexOf("@") > -1)) this.dbcpMaxActive = null; if(this.dbcpMaxWait != null && (this.dbcpMaxWait.length() == 0 || this.dbcpMaxWait.indexOf("@") > -1)) this.dbcpMaxWait = null; if(this.dbcpMaxIdle != null && (this.dbcpMaxIdle.length() == 0 || this.dbcpMaxIdle.indexOf("@") > -1)) this.dbcpMaxIdle = null; if(this.dbcpValidationQuery != null && (this.dbcpValidationQuery.length() == 0 || this.dbcpValidationQuery.indexOf("@") > -1)) this.dbcpValidationQuery = null; instance = this; } public void remove(String key) throws PropertyException { Connection conn = null; try { conn = getConnection(); String sql = "DELETE FROM " + tableName + " WHERE " + colGlobalKey + " = ? AND " + colItemKey + " = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, globalKey); ps.setString(2, key); ps.executeUpdate(); ps.close(); if(valueMapType5 != null) valueMapType5.remove(key); if(type5Map != null) type5Map.remove(key); if(valueMapType10 != null) valueMapType10.remove(key); if(type10Map != null) type10Map.remove(key); } catch (SQLException e) { throw new PropertyException(e.getMessage()); } finally { closeConnection(conn); } } protected void setImpl(int type, String key, Object value) throws PropertyException { if (value == null) { throw new PropertyException("JDBCPropertySet does not allow for null values to be stored"); } Connection conn = null; try { if(this.colItemKey == null || this.globalKey == null) { try { reloadConfiguration(); } catch (Exception e1) { e1.printStackTrace(); } } conn = getConnection(); String sql = "UPDATE " + tableName + " SET " + colString + " = ?, " + colDate + " = ?, " + colData + " = ?, " + colFloat + " = ?, " + colNumber + " = ?, " + colItemType + " = ? " + " WHERE " + colGlobalKey + " = ? AND " + colItemKey + " = ?"; PreparedStatement ps = conn.prepareStatement(sql); setValues(ps, type, key, value); int rows = ps.executeUpdate(); ps.close(); if (rows != 1) { // ok, this is a new value, insert it sql = "INSERT INTO " + tableName + " (" + colString + ", " + colDate + ", " + colData + ", " + colFloat + ", " + colNumber + ", " + colItemType + ", " + colGlobalKey + ", " + colItemKey + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; ps = conn.prepareStatement(sql); setValues(ps, type, key, value); ps.executeUpdate(); ps.close(); } } catch (SQLException e) { try { reloadConfiguration(); } catch (Exception e1) { e1.printStackTrace(); } throw new PropertyException(e.getMessage()); } finally { closeConnection(conn); } } protected Object get(int type, String key) throws PropertyException { if(key.indexOf("allowedAdminIP") == -1 && key.indexOf("_") == -1 && globalKey.equals("infoglue")) { logger.info("Returning null for key:" + key); return null; } if(type != 10 && enableCache && valueMapType5 == null && !allKeysCachedType5) { logger.info("Caching as:" + valueMapType5 + ":" + allKeysCachedType5); this.getKeys(); } if(type == 10 && enableCache && valueMapType10 == null && !allKeysCachedType10) { //System.out.println("Caching..."); this.getKeys(); } if(type != 10 && enableCache && valueMapType5 != null) { synchronized (valueMapType5) { Object value = valueMapType5.get(key); //System.out.println("value:" + value + ":" + allKeysCachedType5); if(value == null && !allKeysCachedType5) { } else { if(value != null && !(value instanceof NullObject)) return value; else if(value instanceof NullObject) return null; else { if(key.indexOf("usePasswordEncryption") > -1 || key.indexOf("ipAddressesToFallbackToBasicAuth") > -1 || key.indexOf("inputCharacterEncoding") > -1 || key.indexOf("anonymous.username") > -1 || key.indexOf("niceURIEncoding") > -1 || key.indexOf("defaultNumberOfYearsBeforeExpire") > -1 || key.indexOf("setDerivedLastModifiedInLive") > -1 || key.indexOf("digitalAssetPath.0") > -1 || key.indexOf("enableNiceURIInWorking") > -1 || key.indexOf("useImprovedContentCategorySearch") > -1 || key.indexOf("useAccessBasedProtocolRedirects") > -1 || key.indexOf("useHashCodeInCaches") > -1 || key.indexOf("useSynchronizationOnCaches") > -1 || key.indexOf("cacheSettings") > -1 || key.indexOf("digitalAssetPath") > -1 || key.indexOf("digitalAssetBaseUrl") > -1 || key.indexOf("anonymous.password") > -1 || key.indexOf("extranetCookieTimeout") > -1 || key.indexOf("pageKey") > -1 || key.indexOf("editOnSite") > -1 || key.indexOf("decoratedPageInvoker") > -1 || key.indexOf("internalDeliveryUrls") > -1 || key.indexOf("mail.smtp.user") > -1 || key.indexOf("mail.smtp.password") > -1 || key.indexOf("mail.contentType") > -1 || key.indexOf("propertiesParser") > -1 || key.indexOf("componentEditorUrl") > -1 || key.indexOf("unprotectedProtocolName") > -1 || key.indexOf("unprotectedProtocolPort") > -1 || key.indexOf("protectedProtocolName") > -1 || key.indexOf("protectedProtocolPort") > -1 || key.indexOf("componentRendererAction") > -1 || key.indexOf("componentRendererUrl") > -1 || key.indexOf("encodeValidateUrl") > -1 || key.indexOf("encodeCasServiceUrl") > -1 || key.indexOf("helpUrl") > -1 || key.indexOf("headerHTML") > -1 || key.indexOf("tree") > -1 || key.indexOf("authorizerClass") > -1 || key.indexOf("invalidLoginUrl") > -1 || key.indexOf("successLoginBaseUrl") > -1 || key.indexOf("serverName") > -1 || key.indexOf("casRenew") > -1 || key.indexOf("casProxyValidateUrl") > -1 || key.indexOf("authConstraint") > -1 || key.indexOf("session.timeout") > -1 ) { logger.info("Returning null!!!!!!!!!:" + key); return null; } } } } } if(type == 10 && enableCache && valueMapType10 != null) { synchronized (valueMapType10) { Object value = valueMapType10.get(key); if(value == null && !allKeysCachedType10) { } else { if(value != null && !(value instanceof NullObject)) return value; else if(value instanceof NullObject) return null; } } } //System.out.println("Getting value for key:" + key + ":" + type); /* if(key.equalsIgnoreCase("serverNode_-1_logPath")) { String sql = "SELECT accessRightId, interceptionPointId from cmAccessRight where interceptionPointId = 6"; Object o = null; Connection conn = null; Timer t = new Timer(); try { conn = getConnection(); PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(); while(rs.next()) { System.out.print("."); rs.getInt("accessRightId"); //rs.getString("parameters"); rs.getInt("interceptionPointId"); } t.printElapsedTime("Done..............."); } catch (Exception e) { e.printStackTrace(); } finally { closeConnection(conn); } } */ Timer t = new Timer(); if(logger.isInfoEnabled()) logger.info("Getting value for key:" + key + ":" + type); String sql = "SELECT " + colItemType + ", " + colString + ", " + colDate + ", " + colData + ", " + colFloat + ", " + colNumber + " FROM " + tableName + " WHERE " + colItemKey + " = ? AND " + colGlobalKey + " = ?"; if(type == 0 || type == 5) sql = "SELECT " + colItemType + ", " + colString + ", " + colDate + ", '' AS " + colData + ", " + colFloat + ", " + colNumber + " FROM " + tableName + " WHERE " + colItemKey + " = ? AND " + colGlobalKey + " = ?"; //System.out.println("sql:" + sql); //System.out.println("key:" + key); //System.out.println("globalKey:" + globalKey); //Thread.dumpStack(); Object o = null; Connection conn = null; try { //t.printElapsedTime("SQL creation took.."); conn = getConnection(); PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, key); ps.setString(2, globalKey); int propertyType; ResultSet rs = ps.executeQuery(); if (rs.next()) { propertyType = rs.getInt(colItemType); if (propertyType != type) { throw new InvalidPropertyTypeException(); } switch (type) { case PropertySet.BOOLEAN: int boolVal = rs.getInt(colNumber); o = new Boolean(boolVal == 1); break; case PropertySet.DATA: { //Ugly fix for old type of column in oracle which we used to run LONG RAW. We converted to blob and the code is different String columnTypeName = rs.getMetaData().getColumnTypeName(4); logger.info("columnTypeName: " + columnTypeName); if(this.driverClassName.indexOf("oracle") > -1 && columnTypeName != null && columnTypeName.indexOf("RAW") == -1) { //System.out.println("Getting as blob"); Blob blob = rs.getBlob(colData); //System.out.println("blob:" + blob); if(blob != null) { try { InputStream in = blob.getBinaryStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[(int)blob.length()]; InputStream is = in; while (is.read(buffer) > 0) { baos.write(buffer); } baos.flush(); String s = baos.toString(); //System.out.println("S: " + s + "..."); o = s.getBytes(); } catch (Exception e) { e.printStackTrace(); } } else { o = null; } } else { o = rs.getBytes(colData); } break; } case PropertySet.DATE: o = rs.getTimestamp(colDate); break; case PropertySet.DOUBLE: o = new Double(rs.getDouble(colFloat)); break; case PropertySet.INT: o = new Integer(rs.getInt(colNumber)); break; case PropertySet.LONG: o = new Long(rs.getLong(colNumber)); break; case PropertySet.STRING: o = rs.getString(colString); break; default: throw new InvalidPropertyTypeException("JDBCPropertySet doesn't support this type yet."); } } rs.close(); ps.close(); //if(key.indexOf("error") > -1) // System.out.println("o1:" + o); //t.printElapsedTime("Read took + " + type + "=" + o); } catch (SQLException e) { logger.error("Problem getting property from database:" + e.getMessage()); throw new PropertyException(e.getMessage()); } catch (NumberFormatException e) { logger.error("Problem getting property from database:" + e.getMessage()); throw new PropertyException(e.getMessage()); } /* catch (UnsupportedEncodingException ue) { throw new PropertyException(ue.getMessage()); } */ finally { closeConnection(conn); } if(type != 10 && valueMapType5 == null) valueMapType5 = new HashMap(); if(type == 10 && valueMapType10 == null) valueMapType10 = new HashMap(); if(type != 10) { synchronized (valueMapType5) { if(o != null) valueMapType5.put(key, o); else valueMapType5.put(key, new NullObject()); } } if(type == 10) { synchronized (valueMapType10) { if(o != null) valueMapType10.put(key, o); else valueMapType10.put(key, new NullObject()); } } //if(key.indexOf("error") > -1) // System.out.println("o:" + o); return o; } private void setValues(PreparedStatement ps, int type, String key, Object value) throws SQLException, PropertyException { //System.out.println("key:" + key); //if(!key.equalsIgnoreCase("serverNode_-1_shortcuts")) // return; // Patched by Edson Richter for MS SQL Server JDBC Support! String driverName; try { driverName = ps.getConnection().getMetaData().getDriverName().toUpperCase(); } catch (Exception e) { driverName = ""; } ps.setNull(1, Types.VARCHAR); ps.setNull(2, Types.TIMESTAMP); // Patched by Edson Richter for MS SQL Server JDBC Support! // Oracle support suggestion also Michael G. Slack if ((driverName.indexOf("SQLSERVER") >= 0) || (driverName.indexOf("ORACLE") >= 0)) { ps.setNull(3, Types.BINARY); } else { ps.setNull(3, Types.BLOB); } ps.setNull(4, Types.FLOAT); ps.setNull(5, Types.NUMERIC); ps.setInt(6, type); ps.setString(7, globalKey); ps.setString(8, key); //System.out.println(type); switch (type) { case PropertySet.BOOLEAN: Boolean boolVal = (Boolean) value; ps.setInt(5, boolVal.booleanValue() ? 1 : 0); break; case PropertySet.DATA: { Data data = (Data) value; ps.setBytes(3, data.getBytes()); /* if(CmsPropertyHandler.getDatabaseEngine().equalsIgnoreCase("oracle")) { ps.setBinaryStream(3,new ByteArrayInputStream(data.getBytes()),data.getBytes().length); } else { ps.setBytes(3, data.getBytes()); } */ break; } case PropertySet.DATE: Date date = (Date) value; ps.setTimestamp(2, new Timestamp(date.getTime())); break; case PropertySet.DOUBLE: Double d = (Double) value; ps.setDouble(4, d.doubleValue()); break; case PropertySet.INT: Integer i = (Integer) value; ps.setInt(5, i.intValue()); break; case PropertySet.LONG: Long l = (Long) value; ps.setLong(5, l.longValue()); break; case PropertySet.STRING: ps.setString(1, (String) value); break; default: throw new PropertyException("This type isn't supported!"); } if(type != 10 && valueMapType5 == null) valueMapType5 = new HashMap(); if(type != 10 && type5Map == null) type5Map = new HashMap(); if(type == 10 && valueMapType10 == null) valueMapType10 = new HashMap(); if(type == 10 && type10Map == null) type10Map = new HashMap(); if(type != 10) { valueMapType5.put(key, value); type5Map.put(key, new Integer(type)); } if(type == 10) { valueMapType10.put(key, value); type10Map.put(key, new Integer(type)); } } private static long lastErrorCheck = -1; private static boolean wasDatabaseFaulty = false; protected Connection getConnection() throws SQLException { //System.out.println("getConnection start"); Connection conn = null; if(lastErrorCheck > -1) { if((wasDatabaseFaulty || !CmsPropertyHandler.getIsValidSetup())/* && (System.currentTimeMillis() - lastErrorCheck < 10000)*/) { //System.out.println("Returning : " + wasDatabaseFaulty + ": " + CmsPropertyHandler.getIsValidSetup() + " : " + (System.currentTimeMillis() - lastErrorCheck)); return conn; } } else lastErrorCheck = System.currentTimeMillis(); wasDatabaseFaulty = false; boolean reloadingConfiguration = false; if(reloadConfiguration) { try { reloadingConfiguration = true; System.out.println("Reloading config........"); reloadConfiguration(); //connectionPool = null; } catch (Exception e) { e.printStackTrace(); } } try { if(connectionPool == null || reloadingConfiguration) { logger.info("Establishing connection to database '" + this.url + "'"); try { setupDriver(url, this.userName, this.password); } catch (Exception e) { if(CmsPropertyHandler.getIsConfigurationFinished()) logger.error("Error setting up driver for [" + this.url + "]: " + e.getMessage()); } logger.info("Done."); } conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:infoGlueJDBCPropertySet"); if(logger.isDebugEnabled()) { logger.debug("Fetched connection from pool..."); printDriverStats(); } //conn = DriverManager.getConnection(url, this.userName, this.password); } catch (Exception ex) { //if(CmsPropertyHandler.getIsConfigurationFinished()) //logger.error("Error connecting to [" + this.url + "]: " + ex.getMessage(), ex); logger.error("Error connecting to [" + this.url + "]: " + ex.getMessage()); lastErrorCheck = System.currentTimeMillis(); int reason = InstallationController.getController().getBrokenDatabaseReason(); if(reason == InstallationController.DATABASE_PARAMETERS_MISSING || reason == InstallationController.DATABASE_SERVER_DOWN || reason == InstallationController.DATABASE_SERVER_MISSING_DATABASE || reason == InstallationController.DATABASE_SERVER_MISSING_DATABASE_TABLES) { wasDatabaseFaulty = true; } //ex.printStackTrace(); } return conn; } private void closeConnection(Connection conn) { try { if ((conn != null) && !conn.isClosed()) { conn.close(); } } catch (SQLException e) { logger.error("Could not close connection"); } } public void setupDriver(String connectURI, String userName, String password) throws Exception { String validationQuery = "select 1 from cmInfoGlueProperties"; logger.info("Setting up driver."); Class.forName(this.driverClassName).newInstance(); logger.info("dbcpWhenExhaustedAction:" + dbcpWhenExhaustedAction); logger.info("dbcpMaxActive:" + dbcpMaxActive); logger.info("dbcpMaxWait:" + dbcpMaxWait); logger.info("dbcpMaxIdle:" + dbcpMaxIdle); logger.info("dbcpValidationQuery:" + dbcpValidationQuery); validationQuery = dbcpValidationQuery; //System.out.println("validationQuery:" + validationQuery); int dbcpMaxActiveInt = 200; if(dbcpMaxActive != null && !dbcpMaxActive.equals("")) dbcpMaxActiveInt = Integer.parseInt(dbcpMaxActive); logger.info("dbcpMaxActiveInt:" + dbcpMaxActiveInt); connectionPool = new GenericObjectPool(null, dbcpMaxActiveInt); connectionPool.setTestOnBorrow(false); //connectionPool.setTestOnReturn(true); connectionPool.setTestWhileIdle(true); connectionPool.setTimeBetweenEvictionRunsMillis(10000); Properties properties = new Properties(); properties.put("user", userName); properties.put("password", password); properties.put("defaultRowPrefetch","1000"); connectionFactory = new DriverManagerConnectionFactory(connectURI, properties /*userName, password*/); poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,validationQuery,false,true); poolableConnectionFactory.getPool().addObject(); Class.forName("org.apache.commons.dbcp.PoolingDriver"); driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:"); driver.registerPool("infoGlueJDBCPropertySet",connectionPool); } public void printDriverStats() throws Exception { PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:"); ObjectPool connectionPool = driver.getConnectionPool("infoGlueJDBCPropertySet"); //System.out.println("NumActive: " + connectionPool.getNumActive()); //System.out.println("NumIdle: " + connectionPool.getNumIdle()); if(logger.isInfoEnabled()) { logger.info("NumActive: " + connectionPool.getNumActive()); logger.info("NumIdle: " + connectionPool.getNumIdle()); } } public void shutdownDriver() throws Exception { PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:"); driver.closePool("infoGlueJDBCPropertySet"); } public static void clearCaches() { /* try { throw new Exception("Clearing caches......................................................."); } catch (Exception e) { e.printStackTrace(); } */ //System.out.println("Setting to null:" + valueMap.hashCode()); if(valueMapType5 != null) { synchronized (valueMapType5) { valueMapType5 = null; } } if(type5Map != null) { synchronized (type5Map) { type5Map = null; } } if(valueMapType10 != null) { synchronized (valueMapType5) { valueMapType5 = null; } } if(type10Map != null) { synchronized (type10Map) { type10Map = null; } } instance.allKeysCachedType5 = false; instance.allKeysCachedType10 = false; } public static void reCache() { //clearCaches(); /* try { System.out.println("Cleared caches - pausing"); Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } */ //System.out.println("Recaching keys"); isRecacheCall = true; instance.getKeys(); //System.out.println("Recached keys"); } public void reloadConfiguration() throws Exception { //logger.warn("Reloading configuration..."); String oldGlobalKey = this.globalKey; //logger.warn("oldGlobalKey:" + oldGlobalKey); DOMBuilder domBuilder = new DOMBuilder(); String propertySetXMLPath = CastorDatabaseService.class.getResource("/propertyset.xml").getPath(); String content = FileHelper.getFileAsString(new File(propertySetXMLPath)); //logger.info("propertyset.xml:\n" + content); Document doc = domBuilder.getDocument(content); Element propertySet = (Element)doc.selectSingleNode("//propertyset[@name='jdbc']"); String name = propertySet.attributeValue("name"); String clazz = propertySet.attributeValue("class"); // get args now List args = propertySet.selectNodes("arg"); Map argsMap = new HashMap(); Iterator argsIterator = args.iterator(); while(argsIterator.hasNext()) { Element arg = (Element) argsIterator.next(); String argName = arg.attributeValue("name"); String argValue = arg.attributeValue("value"); argsMap.put(argName, argValue); //logger.info("" + argName + "=" + argValue); } init(argsMap, argsMap); //Resetting the key to the old global key as this should not be reset this.globalKey = oldGlobalKey; } public static void initReloadConfiguration() throws Exception { reloadConfiguration = true; } }