/* * Copyright (c) 2006 Rogério Liesenfeld * This file is subject to the terms of the MIT license (see LICENSE.txt). */ package mockit.internal.injection.full; import java.beans.*; import java.lang.annotation.*; import java.lang.reflect.*; import javax.annotation.*; import javax.annotation.sql.*; import javax.sql.*; import mockit.internal.injection.*; final class TestDataSource { @Nullable private final String dsName; private Class<? extends CommonDataSource> dsClass; private CommonDataSource ds; TestDataSource(@Nonnull InjectionPoint injectionPoint) { dsName = injectionPoint.name; } @Nullable CommonDataSource createIfDataSourceDefinitionAvailable(@Nonnull TestedClass testedClass) { if (dsName == null) { return null; } Class<?> targetClass = testedClass.targetClass; do { createDataSource(targetClass); if (ds != null) { return ds; } targetClass = targetClass.getSuperclass(); } while (targetClass != Object.class); throw new IllegalStateException( "Missing @DataSourceDefinition of name \"" + dsName + "\" on " + testedClass.nameOfTestedClass); } private void createDataSource(@Nonnull Class<?> targetClass) { for (Annotation annotation : targetClass.getDeclaredAnnotations()) { String annotationName = annotation.annotationType().getName(); if ("javax.annotation.sql.DataSourceDefinitions".equals(annotationName)) { createDataSource((DataSourceDefinitions) annotation); } else if ("javax.annotation.sql.DataSourceDefinition".equals(annotationName)) { createDataSource((DataSourceDefinition) annotation); } if (ds != null) { return; } } } private void createDataSource(@Nonnull DataSourceDefinitions dsDefs) { for (DataSourceDefinition dsDef : dsDefs.value()) { createDataSource(dsDef); if (ds != null) { return; } } } private void createDataSource(@Nonnull DataSourceDefinition dsDef) { String configuredDataSourceName = InjectionPoint.getNameFromJNDILookup(dsDef.name()); if (configuredDataSourceName.equals(dsName)) { instantiateConfiguredDataSourceClass(dsDef); setDataSourcePropertiesFromConfiguredValues(dsDef); } } private void instantiateConfiguredDataSourceClass(@Nonnull DataSourceDefinition dsDef) { String className = dsDef.className(); try { //noinspection unchecked dsClass = (Class<? extends CommonDataSource>) Class.forName(className); ds = dsClass.newInstance(); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e.getCause()); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } private void setDataSourcePropertiesFromConfiguredValues(@Nonnull DataSourceDefinition dsDef) { try { BeanInfo beanInfo = Introspector.getBeanInfo(dsClass, Object.class); PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors(); setProperty(properties, "url", dsDef.url()); setProperty(properties, "user", dsDef.user()); setProperty(properties, "password", dsDef.password()); } catch (IntrospectionException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } private void setProperty(@Nonnull PropertyDescriptor[] properties, @Nonnull String name, @Nonnull String value) throws InvocationTargetException, IllegalAccessException { for (PropertyDescriptor property : properties) { if (property.getName().equals(name)) { Method writeMethod = property.getWriteMethod(); if (writeMethod != null) { writeMethod.invoke(ds, value); } return; } } } }