// Copyright 2012 Citrix Systems, Inc. Licensed under the // Apache License, Version 2.0 (the "License"); you may not use this // file except in compliance with the License. Citrix Systems, Inc. // reserves all rights not expressly granted by the License. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.utils.db; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.Embedded; import javax.persistence.EmbeddedId; import javax.persistence.Id; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.PrimaryKeyJoinColumns; import javax.persistence.SecondaryTable; import javax.persistence.SecondaryTables; import javax.persistence.Table; import javax.persistence.Transient; import org.apache.log4j.Logger; public class DbUtil { protected final static Logger s_logger = Logger.getLogger(DbUtil.class); private static Map<String, Connection> s_connectionForGlobalLocks = new HashMap<String, Connection>(); public static Connection getConnectionForGlobalLocks(String name, boolean forLock) { synchronized(s_connectionForGlobalLocks) { if(forLock) { if(s_connectionForGlobalLocks.get(name) != null) { s_logger.error("Sanity check failed, global lock name " + name + " is already in use"); assert(false); } Connection connection = Transaction.getStandaloneConnection(); if(connection != null) { try { connection.setAutoCommit(true); } catch (SQLException e) { try { connection.close(); } catch(SQLException sqlException) { } return null; } s_connectionForGlobalLocks.put(name, connection); return connection; } return null; } else { Connection connection = s_connectionForGlobalLocks.get(name); s_connectionForGlobalLocks.remove(name); return connection; } } } public static void removeConnectionForGlobalLocks(String name) { synchronized(s_connectionForGlobalLocks) { s_connectionForGlobalLocks.remove(name); } } public static String getColumnName(Field field, AttributeOverride[] overrides) { if (overrides != null) { for (AttributeOverride override : overrides) { if (override.name().equals(field.getName())) { return override.column().name(); } } } assert(field.getAnnotation(Embedded.class) == null) : "Cannot get column name from embedded field: " + field.getName(); Column column = field.getAnnotation(Column.class); return column != null ? column.name() : field.getName(); } public static String getColumnName(Field field) { return getColumnName(field, null); } public static String getReferenceColumn(PrimaryKeyJoinColumn pkjc) { return pkjc.referencedColumnName().length() != 0 ? pkjc.referencedColumnName() : pkjc.name(); } public static PrimaryKeyJoinColumn[] getPrimaryKeyJoinColumns(Class<?> clazz) { PrimaryKeyJoinColumn pkjc = clazz.getAnnotation(PrimaryKeyJoinColumn.class); if (pkjc != null) { return new PrimaryKeyJoinColumn[] { pkjc }; } PrimaryKeyJoinColumns pkjcs = clazz.getAnnotation(PrimaryKeyJoinColumns.class); if (pkjcs != null) { return pkjcs.value(); } return null; } public static Field findField(Class<?> clazz, String columnName) { for (Field field : clazz.getDeclaredFields()) { if (field.getAnnotation(Embedded.class) != null || field.getAnnotation(EmbeddedId.class) != null) { findField(field.getClass(), columnName); } else { if (columnName.equals(DbUtil.getColumnName(field))) { return field; } } } return null; } public static final AttributeOverride[] getAttributeOverrides(AnnotatedElement ae) { AttributeOverride[] overrides = null; AttributeOverrides aos = ae.getAnnotation(AttributeOverrides.class); if (aos != null) { overrides = aos.value(); } if (overrides == null || overrides.length == 0) { AttributeOverride override = ae.getAnnotation(AttributeOverride.class); if (override != null) { overrides = new AttributeOverride[1]; overrides[0] = override; } else { overrides = new AttributeOverride[0]; } } return overrides; } public static final boolean isPersistable(Field field) { if (field.getAnnotation(Transient.class) != null) { return false; } int modifiers = field.getModifiers(); return !(Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)); } public static final boolean isIdField(Field field) { if (field.getAnnotation(Id.class) != null) { return true; } if (field.getAnnotation(EmbeddedId.class) != null) { assert (field.getClass().getAnnotation(Embeddable.class) != null) : "Class " + field.getClass().getName() + " must be Embeddable to be used as Embedded Id"; return true; } return false; } public static final SecondaryTable[] getSecondaryTables(AnnotatedElement clazz) { SecondaryTable[] sts = null; SecondaryTable stAnnotation = clazz.getAnnotation(SecondaryTable.class); if (stAnnotation == null) { SecondaryTables stsAnnotation = clazz.getAnnotation(SecondaryTables.class); sts = stsAnnotation != null ? stsAnnotation.value() : new SecondaryTable[0]; } else { sts = new SecondaryTable[] {stAnnotation}; } return sts; } public static final String getTableName(Class<?> clazz) { Table table = clazz.getAnnotation(Table.class); return table != null ? table.name() : clazz.getSimpleName(); } public static boolean getGlobalLock(String name, int timeoutSeconds) { Connection conn = getConnectionForGlobalLocks(name, true); if(conn == null) { s_logger.error("Unable to acquire DB connection for global lock system"); return false; } PreparedStatement pstmt = null; try { pstmt = conn.prepareStatement("SELECT COALESCE(GET_LOCK(?, ?),0)"); pstmt.setString(1, name); pstmt.setInt(2, timeoutSeconds); ResultSet rs = pstmt.executeQuery(); if (rs != null && rs.first()) { if(rs.getInt(1) > 0) { return true; } else { if(s_logger.isDebugEnabled()) s_logger.debug("GET_LOCK() timed out on lock : " + name); } } } catch (SQLException e) { s_logger.error("GET_LOCK() throws exception ", e); } catch (Throwable e) { s_logger.error("GET_LOCK() throws exception ", e); } finally { if (pstmt != null) { try { pstmt.close(); } catch (Throwable e) { s_logger.error("What the heck? ", e); } } } removeConnectionForGlobalLocks(name); try { conn.close(); } catch (SQLException e) { } return false; } public static boolean releaseGlobalLock(String name) { Connection conn = getConnectionForGlobalLocks(name, false); if(conn == null) { s_logger.error("Unable to acquire DB connection for global lock system"); assert(false); return false; } PreparedStatement pstmt = null; try { pstmt = conn.prepareStatement("SELECT COALESCE(RELEASE_LOCK(?), 0)"); pstmt.setString(1, name); ResultSet rs = pstmt.executeQuery(); if(rs != null && rs.first()) return rs.getInt(1) > 0; s_logger.error("RELEASE_LOCK() returns unexpected result : " + rs.getInt(1)); } catch (SQLException e) { s_logger.error("RELEASE_LOCK() throws exception ", e); } catch (Throwable e) { s_logger.error("RELEASE_LOCK() throws exception ", e); } finally { try { if (pstmt != null) { pstmt.close(); } conn.close(); } catch(SQLException e) { } } return false; } }