DbUnitDtdGenerator.java

1
package com.reallifedeveloper.tools.test.database.dbunit;
2
3
import java.io.StringWriter;
4
import java.sql.SQLException;
5
import java.util.Optional;
6
7
import javax.sql.DataSource;
8
9
import org.dbunit.DatabaseUnitException;
10
import org.dbunit.database.DatabaseConfig;
11
import org.dbunit.database.DatabaseConnection;
12
import org.dbunit.database.IDatabaseConnection;
13
import org.dbunit.dataset.IDataSet;
14
import org.dbunit.dataset.datatype.IDataTypeFactory;
15
import org.dbunit.dataset.xml.FlatDtdWriter;
16
import org.slf4j.Logger;
17
import org.slf4j.LoggerFactory;
18
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
19
import org.springframework.context.ApplicationContext;
20
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
21
import org.springframework.context.support.ClassPathXmlApplicationContext;
22
23
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
24
25
/**
26
 * Generates a DTD for DbUnit XML files used to populate the test database.
27
 *
28
 * @author RealLifeDeveloper
29
 *
30
 */
31
@SuppressFBWarnings(value = "CRLF_INJECTION_LOGS", justification = "This is intended to log the DTD including line breaks")
32
public class DbUnitDtdGenerator {
33
34
    private static final Logger LOG = LoggerFactory.getLogger(DbUnitDtdGenerator.class);
35
36
    private final ApplicationContext applicationContext;
37
38
    /**
39
     * Creates a new {@code DbUnitDtdGenerator} using the given Spring application context. It reads all tables in the database pointed to
40
     * by a data source from the application context and generates a DTD matching that database.
41
     * <p>
42
     * The application context should define at least a {@code javax.sql.DataSource} to read from. It may optionally define a
43
     * {@code org.dbunit.dataset.datatype.IDataTypeFactory} matching the database used.
44
     *
45
     * @param applicationContext the application context to use to find the {@code DataSource} and possibly {@code IDataTypeFactory}
46
     */
47
    public DbUnitDtdGenerator(ApplicationContext applicationContext) {
48
        this.applicationContext = applicationContext;
49
    }
50
51
    /**
52
     * Factory method to create a new {@code DbUnitDtdGenerator} instance using an application context constructed from a Spring XML
53
     * configuration file loaded from the classpath.
54
     *
55
     * @param springConfigResourceName the name of the classpath resource containing the Spring XML configuration
56
     *
57
     * @return the new {@code DbUnitDtdGenerator} instance
58
     */
59
    public static DbUnitDtdGenerator createFromSpringXmlConfiguration(String springConfigResourceName) {
60
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(springConfigResourceName);
61 1 1. createFromSpringXmlConfiguration : replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::createFromSpringXmlConfiguration → KILLED
        return new DbUnitDtdGenerator(applicationContext);
62
    }
63
64
    /**
65
     * Factory method to create a new {@code DbUnitDtdGenerator} instance using an application context constructed from a Spring
66
     * configuration class, i.e., a class annotated with {@code org.springframework.context.annotation.Configuration}.
67
     *
68
     * @param configClass the {@code @Configuration} class
69
     *
70
     * @return the new {@code DbUnitDtdGenerator} instance
71
     */
72
    public static DbUnitDtdGenerator createFromSpringConfigurationClass(Class<?> configClass) {
73
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(configClass);
74 1 1. createFromSpringConfigurationClass : replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::createFromSpringConfigurationClass → KILLED
        return new DbUnitDtdGenerator(applicationContext);
75
    }
76
77
    /**
78
     * Main method that logs the generated DTD on info level. The only argument should be either the fully-qualified name of a Spring
79
     * configuration class on the classpath, or the name of a Spring XML configuration file, also on the classpath.
80
     *
81
     * @param args should contain one argument, either configuration class or XML configuration file on classpath
82
     *
83
     * @throws SQLException          if a database problem occurred
84
     * @throws DatabaseUnitException if a DbUnit problem occurred
85
     */
86
    public static void main(String... args) throws SQLException, DatabaseUnitException {
87 1 1. main : negated conditional → KILLED
        if (args.length != 1) {
88
            throw new IllegalArgumentException(
89
                    "Usage: java %s <classpath Spring config class or XML file>".formatted(DbUnitDtdGenerator.class.getName()));
90
        }
91
        DbUnitDtdGenerator generator;
92
        try {
93
            Class<?> configClass = Class.forName(args[0]);
94
            generator = createFromSpringConfigurationClass(configClass);
95
        } catch (ClassNotFoundException e) {
96
            generator = createFromSpringXmlConfiguration(args[0]);
97
        }
98
        String dtd = generator.generateDtd();
99
        LOG.info(dtd);
100
    }
101
102
    /**
103
     * Gives the DbUnit DTD as a string.
104
     *
105
     * @return the DbUnit DTD
106
     *
107
     * @throws SQLException          if a database problem occurred
108
     * @throws DatabaseUnitException if a DbUnit problem occurred
109
     */
110
    public String generateDtd() throws SQLException, DatabaseUnitException {
111
        IDatabaseConnection connection = new DatabaseConnection(getDataSource().getConnection());
112 1 1. generateDtd : negated conditional → SURVIVED
        if (getDataTypeFactory().isPresent()) {
113 1 1. generateDtd : removed call to org/dbunit/database/DatabaseConfig::setProperty → SURVIVED
            connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, getDataTypeFactory().get());
114
        }
115
        IDataSet dataSet = connection.createDataSet();
116
        StringWriter stringWriter = new StringWriter();
117
        FlatDtdWriter datasetWriter = new FlatDtdWriter(stringWriter);
118 1 1. generateDtd : removed call to org/dbunit/dataset/xml/FlatDtdWriter::setContentModel → SURVIVED
        datasetWriter.setContentModel(FlatDtdWriter.SEQUENCE);
119 1 1. generateDtd : removed call to org/dbunit/dataset/xml/FlatDtdWriter::write → KILLED
        datasetWriter.write(dataSet);
120 1 1. generateDtd : replaced return value with "" for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::generateDtd → KILLED
        return stringWriter.toString();
121
    }
122
123
    private DataSource getDataSource() {
124 1 1. getDataSource : replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::getDataSource → RUN_ERROR
        return applicationContext.getBean(DataSource.class);
125
    }
126
127
    private Optional<IDataTypeFactory> getDataTypeFactory() {
128
        IDataTypeFactory dataTypeFactory = null;
129
        try {
130
            dataTypeFactory = applicationContext.getBean(IDataTypeFactory.class);
131
        } catch (NoSuchBeanDefinitionException e) {
132
            LOG.warn(e.getMessage());
133
        }
134 1 1. getDataTypeFactory : replaced return value with Optional.empty for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::getDataTypeFactory → SURVIVED
        return Optional.ofNullable(dataTypeFactory);
135
    }
136
}

Mutations

61

1.1
Location : createFromSpringXmlConfiguration
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest]/[method:mainWithConfigurationFile()]
replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::createFromSpringXmlConfiguration → KILLED

74

1.1
Location : createFromSpringConfigurationClass
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest]/[method:mainWithConfigurationClass()]
replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::createFromSpringConfigurationClass → KILLED

87

1.1
Location : main
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest]/[method:mainTwoArguments()]
negated conditional → KILLED

112

1.1
Location : generateDtd
Killed by : none
negated conditional → SURVIVED
Covering tests

113

1.1
Location : generateDtd
Killed by : none
removed call to org/dbunit/database/DatabaseConfig::setProperty → SURVIVED
Covering tests

118

1.1
Location : generateDtd
Killed by : none
removed call to org/dbunit/dataset/xml/FlatDtdWriter::setContentModel → SURVIVED
Covering tests

119

1.1
Location : generateDtd
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest]/[method:generateDtd()]
removed call to org/dbunit/dataset/xml/FlatDtdWriter::write → KILLED

120

1.1
Location : generateDtd
Killed by : com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.tools.test.database.dbunit.DbUnitDtdGeneratorTest]/[method:generateDtd()]
replaced return value with "" for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::generateDtd → KILLED

124

1.1
Location : getDataSource
Killed by : none
replaced return value with null for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::getDataSource → RUN_ERROR

134

1.1
Location : getDataTypeFactory
Killed by : none
replaced return value with Optional.empty for com/reallifedeveloper/tools/test/database/dbunit/DbUnitDtdGenerator::getDataTypeFactory → SURVIVED
Covering tests

Active mutators

Tests examined


Report generated by PIT 1.20.2