@@ -818,49 +818,6 @@ | |||
</exclusion> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-annotations</artifactId> | |||
<version>3.4.0.GA</version> | |||
<exclusions> | |||
<exclusion> | |||
<!-- provided by Java 1.7 --> | |||
<groupId>xml-apis</groupId> | |||
<artifactId>xml-apis</artifactId> | |||
</exclusion> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-commons-annotations</artifactId> | |||
<version>3.1.0.GA</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-core</artifactId> | |||
<version>3.3.2.GA</version> | |||
<exclusions> | |||
<exclusion> | |||
<groupId>javax.transaction</groupId> | |||
<artifactId>jta</artifactId> | |||
</exclusion> | |||
<exclusion> | |||
<groupId>xml-apis</groupId> | |||
<artifactId>xml-apis</artifactId> | |||
</exclusion> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-entitymanager</artifactId> | |||
<version>3.4.0.GA</version> | |||
<exclusions> | |||
<exclusion> | |||
<groupId>javax.transaction</groupId> | |||
<artifactId>jta</artifactId> | |||
</exclusion> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.mybatis</groupId> | |||
<artifactId>mybatis</artifactId> | |||
@@ -1007,11 +964,6 @@ | |||
<!-- do not upgrade to 1.7.10, much slower at startup --> | |||
<version>1.7.9</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>geronimo-spec</groupId> | |||
<artifactId>geronimo-spec-jta</artifactId> | |||
<version>1.0-M1</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.codehaus.woodstox</groupId> | |||
<artifactId>stax2-api</artifactId> | |||
@@ -1365,7 +1317,7 @@ | |||
<artifactId>maven-javadoc-plugin</artifactId> | |||
<configuration> | |||
<excludePackageNames> | |||
net.*:org.sonar.application:org.sonar.server:org.sonar.graph:org.sonar.batch:org.sonar.channel:org.sonar.java:org.sonar.maven*:org.sonar.plugins.*:org.sonar.colorizer:org.sonar.core:org.sonar.jpa:org.sonar.duplications:org.sonar.markdown:com.* | |||
net.*:org.sonar.application:org.sonar.server:org.sonar.graph:org.sonar.batch:org.sonar.channel:org.sonar.java:org.sonar.maven*:org.sonar.plugins.*:org.sonar.colorizer:org.sonar.core:org.sonar.duplications:org.sonar.markdown:com.* | |||
</excludePackageNames> | |||
<author>false</author> | |||
<linksource>true</linksource> |
@@ -11,10 +11,6 @@ | |||
</encoder> | |||
</appender> | |||
<logger name="org.hibernate"> | |||
<level value="WARN"/> | |||
</logger> | |||
<logger name="org.dbunit"> | |||
<level value="WARN"/> | |||
</logger> |
@@ -65,9 +65,6 @@ class WebLogging { | |||
private void configureLevels(LoggerContext ctx, Props props) { | |||
// override level of some loggers | |||
helper.configureLogger(ctx, "rails", Level.WARN); | |||
helper.configureLogger(ctx, "org.hibernate.cache.ReadWriteCache", Level.ERROR); | |||
helper.configureLogger(ctx, "org.hibernate", Level.WARN); | |||
helper.configureLogger(ctx, "org.hibernate.SQL", Level.WARN); | |||
helper.configureLogger(ctx, "org.apache.ibatis", Level.WARN); | |||
helper.configureLogger(ctx, "java.sql", Level.WARN); | |||
helper.configureLogger(ctx, "java.sql.ResultSet", Level.WARN); |
@@ -107,28 +107,6 @@ | |||
<artifactId>freemarker</artifactId> | |||
</dependency> | |||
<!-- hibernate --> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-core</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-annotations</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-commons-annotations</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-entitymanager</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>geronimo-spec</groupId> | |||
<artifactId>geronimo-spec-jta</artifactId> | |||
</dependency> | |||
<!-- unit tests --> | |||
<dependency> | |||
<groupId>org.codehaus.sonar</groupId> |
@@ -22,7 +22,6 @@ package org.sonar.batch.bootstrap; | |||
import com.google.common.collect.Lists; | |||
import java.util.Collection; | |||
import java.util.List; | |||
import org.sonar.batch.components.TimeMachineConfiguration; | |||
import org.sonar.batch.compute.BranchCoverageDecorator; | |||
import org.sonar.batch.compute.CommentDensityDecorator; | |||
import org.sonar.batch.compute.CoverageDecorator; | |||
@@ -94,8 +93,7 @@ public class BatchComponents { | |||
OverallBranchCoverageDecorator.class, | |||
CommentDensityDecorator.class, | |||
DirectoriesDecorator.class, | |||
FilesDecorator.class, | |||
TimeMachineConfiguration.class | |||
FilesDecorator.class | |||
); | |||
components.addAll(CorePropertyDefinitions.all()); | |||
// CPD |
@@ -1,47 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import java.util.Properties; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.core.persistence.DefaultDatabase; | |||
/** | |||
* @since 2.12 | |||
*/ | |||
public class BatchDatabase extends DefaultDatabase { | |||
public BatchDatabase(Settings settings, | |||
// The dependency on JdbcDriverHolder is required to be sure that the JDBC driver | |||
// has been downloaded and injected into classloader | |||
JdbcDriverHolder jdbcDriverHolder) { | |||
super(settings); | |||
} | |||
@Override | |||
protected void doCompleteProperties(Properties properties) { | |||
// two connections are required : one for Hibernate, and one for MyBatis for regular operations | |||
// Note that Hibernate will be removed soon | |||
properties.setProperty("sonar.jdbc.initialSize", "2"); | |||
properties.setProperty("sonar.jdbc.maxActive", "2"); | |||
// SONAR-2965 | |||
properties.setProperty("sonar.jdbc.defaultAutoCommit", "false"); | |||
} | |||
} |
@@ -1,41 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.jpa.session.DatabaseSessionFactory; | |||
public class BatchDatabaseSessionFactory implements DatabaseSessionFactory { | |||
private DatabaseSession session; | |||
public BatchDatabaseSessionFactory(DatabaseSession session) { | |||
this.session = session; | |||
} | |||
@Override | |||
public DatabaseSession getSession() { | |||
return session; | |||
} | |||
@Override | |||
public void clear() { | |||
} | |||
} |
@@ -1,100 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import org.sonar.api.utils.MessageException; | |||
import org.sonar.core.persistence.DatabaseVersion; | |||
import org.sonar.core.properties.PropertiesDao; | |||
/** | |||
* Detects if database is not up-to-date with the version required by the batch. | |||
*/ | |||
@BatchSide | |||
public class DatabaseCompatibility { | |||
private DatabaseVersion version; | |||
private Settings settings; | |||
private PropertiesDao propertiesDao; | |||
private ServerClient server; | |||
private DefaultAnalysisMode analysisMode; | |||
public DatabaseCompatibility(DatabaseVersion version, ServerClient server, Settings settings, PropertiesDao propertiesDao, DefaultAnalysisMode mode) { | |||
this.version = version; | |||
this.server = server; | |||
this.settings = settings; | |||
this.propertiesDao = propertiesDao; | |||
this.analysisMode = mode; | |||
} | |||
public void start() { | |||
if (!analysisMode.isPreview()) { | |||
checkCorrectServerId(); | |||
checkDatabaseStatus(); | |||
} | |||
} | |||
private void checkCorrectServerId() { | |||
if (!propertiesDao.selectGlobalProperty(CoreProperties.SERVER_ID).getValue().equals(getServerId())) { | |||
StringBuilder message = new StringBuilder("The current batch process and the configured remote server do not share the same DB configuration.\n"); | |||
message.append("\t- Batch side: "); | |||
message.append(settings.getString(DatabaseProperties.PROP_URL)); | |||
message.append(" ("); | |||
String userName = settings.getString(DatabaseProperties.PROP_USER); | |||
message.append(userName == null ? "sonar" : userName); | |||
message.append(" / *****)\n\t- Server side: check the configuration at "); | |||
message.append(server.getURL()); | |||
message.append("/system\n"); | |||
throw MessageException.of(message.toString()); | |||
} | |||
} | |||
private String getServerId() { | |||
String remoteServerInfo = server.request("/api/server"); | |||
// don't use JSON utilities to extract ID from such a small string | |||
return extractServerId(remoteServerInfo); | |||
} | |||
@VisibleForTesting | |||
String extractServerId(String remoteServerInfo) { | |||
String partialId = StringUtils.substringAfter(remoteServerInfo, "\"id\":\""); | |||
return StringUtils.substringBefore(partialId, "\""); | |||
} | |||
private void checkDatabaseStatus() { | |||
DatabaseVersion.Status status = version.getStatus(); | |||
if (status == DatabaseVersion.Status.REQUIRES_DOWNGRADE) { | |||
throw MessageException.of("Database relates to a more recent version of SonarQube. Please check your settings (JDBC settings, version of Maven plugin)"); | |||
} | |||
if (status == DatabaseVersion.Status.REQUIRES_UPGRADE) { | |||
throw MessageException.of("Database must be upgraded. Please browse " + server.getURL() + "/setup"); | |||
} | |||
if (status != DatabaseVersion.Status.UP_TO_DATE) { | |||
// Support other future values | |||
throw MessageException.of("Unknown database status: " + status); | |||
} | |||
} | |||
} |
@@ -43,10 +43,6 @@ public class DefaultAnalysisMode implements AnalysisMode { | |||
init(props); | |||
} | |||
public boolean isDb() { | |||
return !preview && !incremental && !mediumTestMode; | |||
} | |||
@Override | |||
public boolean isPreview() { | |||
return preview || incremental; |
@@ -19,6 +19,8 @@ | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import java.util.List; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.ExtensionProvider; | |||
import org.sonar.api.Plugin; | |||
import org.sonar.batch.bootstrapper.EnvironmentInformation; | |||
@@ -26,10 +28,6 @@ import org.sonar.core.platform.ComponentContainer; | |||
import org.sonar.core.platform.PluginInfo; | |||
import org.sonar.core.platform.PluginRepository; | |||
import javax.annotation.Nullable; | |||
import java.util.List; | |||
public class ExtensionInstaller { | |||
private final PluginRepository pluginRepository; | |||
@@ -72,7 +70,6 @@ public class ExtensionInstaller { | |||
private void doInstall(ComponentContainer container, ExtensionMatcher matcher, @Nullable PluginInfo pluginInfo, Object extension) { | |||
if (ExtensionUtils.supportsEnvironment(extension, env) | |||
&& (analysisMode.isDb() || !ExtensionUtils.requiresDB(extension)) | |||
&& matcher.accept(extension)) { | |||
container.addExtension(pluginInfo, extension); | |||
} else { |
@@ -22,7 +22,6 @@ package org.sonar.batch.bootstrap; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.batch.RequiresDB; | |||
import org.sonar.api.batch.SupportedEnvironment; | |||
import org.sonar.api.utils.AnnotationUtils; | |||
import org.sonar.batch.bootstrapper.EnvironmentInformation; | |||
@@ -58,10 +57,6 @@ public class ExtensionUtils { | |||
return false; | |||
} | |||
public static boolean requiresDB(Object extension) { | |||
return AnnotationUtils.getAnnotation(extension, RequiresDB.class) != null; | |||
} | |||
public static boolean isMavenExtensionOnly(Object extension) { | |||
SupportedEnvironment env = AnnotationUtils.getAnnotation(extension, SupportedEnvironment.class); | |||
return env != null && env.value().length == 1 && StringUtils.equalsIgnoreCase("maven", env.value()[0]); |
@@ -19,22 +19,14 @@ | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import org.sonar.batch.index.CachesManager; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.Plugin; | |||
import org.sonar.api.utils.Durations; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.utils.UriReader; | |||
import org.sonar.batch.components.PastSnapshotFinder; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByDate; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByDays; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousAnalysis; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousVersion; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByVersion; | |||
import org.sonar.batch.index.CachesManager; | |||
import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader; | |||
import org.sonar.batch.issue.tracking.ServerLineHashesLoader; | |||
import org.sonar.batch.platform.DefaultServer; | |||
@@ -47,21 +39,14 @@ import org.sonar.batch.repository.ProjectRepositoriesLoader; | |||
import org.sonar.batch.repository.ServerIssuesLoader; | |||
import org.sonar.batch.repository.user.UserRepository; | |||
import org.sonar.batch.scan.ProjectScanContainer; | |||
import org.sonar.core.cluster.NullQueue; | |||
import org.sonar.core.config.Logback; | |||
import org.sonar.core.i18n.DefaultI18n; | |||
import org.sonar.core.i18n.RuleI18nManager; | |||
import org.sonar.core.persistence.DaoUtils; | |||
import org.sonar.core.persistence.DatabaseVersion; | |||
import org.sonar.core.persistence.MyBatis; | |||
import org.sonar.core.platform.ComponentContainer; | |||
import org.sonar.core.platform.PluginClassloaderFactory; | |||
import org.sonar.core.platform.PluginInfo; | |||
import org.sonar.core.platform.PluginLoader; | |||
import org.sonar.core.platform.PluginRepository; | |||
import org.sonar.core.util.DefaultHttpDownloader; | |||
import org.sonar.jpa.session.DefaultDatabaseConnector; | |||
import org.sonar.jpa.session.JpaDatabaseSession; | |||
public class GlobalContainer extends ComponentContainer { | |||
@@ -85,10 +70,6 @@ public class GlobalContainer extends ComponentContainer { | |||
DefaultAnalysisMode analysisMode = new DefaultAnalysisMode(bootstrapProps.properties()); | |||
add(bootstrapProps, analysisMode); | |||
addBootstrapComponents(); | |||
if (analysisMode.isDb()) { | |||
addDatabaseComponents(); | |||
} | |||
} | |||
private void addBootstrapComponents() { | |||
@@ -131,27 +112,6 @@ public class GlobalContainer extends ComponentContainer { | |||
} | |||
} | |||
private void addDatabaseComponents() { | |||
add( | |||
JdbcDriverHolder.class, | |||
BatchDatabase.class, | |||
MyBatis.class, | |||
NullQueue.class, | |||
DatabaseVersion.class, | |||
DatabaseCompatibility.class, | |||
DefaultDatabaseConnector.class, | |||
JpaDatabaseSession.class, | |||
BatchDatabaseSessionFactory.class, | |||
DaoUtils.getDaoClasses(), | |||
RuleI18nManager.class, | |||
PastSnapshotFinderByDate.class, | |||
PastSnapshotFinderByDays.class, | |||
PastSnapshotFinderByPreviousAnalysis.class, | |||
PastSnapshotFinderByVersion.class, | |||
PastSnapshotFinderByPreviousVersion.class, | |||
PastSnapshotFinder.class); | |||
} | |||
@Override | |||
protected void doAfterStart() { | |||
installPlugins(); |
@@ -1,195 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.base.Strings; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.home.cache.FileCache; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.net.URLClassLoader; | |||
/** | |||
* Contains and provides class loader extended with the JDBC Driver hosted on the server-side. | |||
*/ | |||
public class JdbcDriverHolder { | |||
private static final Logger LOG = LoggerFactory.getLogger(JdbcDriverHolder.class); | |||
private ServerClient serverClient; | |||
private DefaultAnalysisMode analysisMode; | |||
private FileCache fileCache; | |||
// initialized in start() | |||
private JdbcDriverClassLoader classLoader = null; | |||
public JdbcDriverHolder(FileCache fileCache, DefaultAnalysisMode analysisMode, ServerClient serverClient) { | |||
this.serverClient = serverClient; | |||
this.analysisMode = analysisMode; | |||
this.fileCache = fileCache; | |||
} | |||
public void start() { | |||
if (!analysisMode.isPreview()) { | |||
try { | |||
LOG.info("Install JDBC driver"); | |||
String[] nameAndHash = downloadJdbcDriverIndex(); | |||
if (nameAndHash.length > 0) { | |||
String filename = nameAndHash[0]; | |||
String hash = nameAndHash[1]; | |||
File jdbcDriver = fileCache.get(filename, hash, new FileCache.Downloader() { | |||
@Override | |||
public void download(String filename, File toFile) throws IOException { | |||
String url = "/deploy/" + filename; | |||
if (LOG.isDebugEnabled()) { | |||
LOG.debug("Download {} to {}", url, toFile.getAbsolutePath()); | |||
} else { | |||
LOG.info("Download {}", filename); | |||
} | |||
serverClient.download(url, toFile); | |||
} | |||
}); | |||
classLoader = initClassloader(jdbcDriver); | |||
} | |||
} catch (SonarException e) { | |||
throw e; | |||
} catch (Exception e) { | |||
throw new SonarException("Fail to install JDBC driver", e); | |||
} | |||
} | |||
} | |||
@VisibleForTesting | |||
JdbcDriverClassLoader getClassLoader() { | |||
return classLoader; | |||
} | |||
@VisibleForTesting | |||
static JdbcDriverClassLoader initClassloader(File jdbcDriver) { | |||
JdbcDriverClassLoader classLoader; | |||
try { | |||
ClassLoader parentClassLoader = JdbcDriverHolder.class.getClassLoader(); | |||
classLoader = new JdbcDriverClassLoader(jdbcDriver.toURI().toURL(), parentClassLoader); | |||
} catch (MalformedURLException e) { | |||
throw new SonarException("Fail to get URL of : " + jdbcDriver.getAbsolutePath(), e); | |||
} | |||
// set as the current context classloader for hibernate, else it does not find the JDBC driver. | |||
Thread.currentThread().setContextClassLoader(classLoader); | |||
return classLoader; | |||
} | |||
/** | |||
* This method automatically invoked by PicoContainer and unregisters JDBC drivers, which were forgotten. | |||
* <p> | |||
* Dynamically loaded JDBC drivers can not be simply used and this is a well known problem of {@link java.sql.DriverManager}, | |||
* so <a href="http://stackoverflow.com/questions/288828/how-to-use-a-jdbc-driver-from-an-arbitrary-location">workaround is to use proxy</a>. | |||
* However DriverManager also contains memory leak, thus not only proxy, but also original driver must be unregistered, | |||
* otherwise our class loader would be kept in memory. | |||
* </p> | |||
* <p> | |||
* This operation contains unnecessary complexity because: | |||
* <ul> | |||
* <li>DriverManager checks the class loader of the calling class. Thus we can't simply ask it about deregistration.</li> | |||
* <li>We can't use reflection against DriverManager, since it would create a dependency on DriverManager implementation, | |||
* which can be changed (like it was done - compare Java 1.5 and 1.6).</li> | |||
* <li>So we use companion - {@link JdbcLeakPrevention}. But we can't just create an instance, | |||
* since it will be loaded by parent class loader and again will not pass DriverManager's check. | |||
* So, we load the bytes via our parent class loader, but define the class with this class loader | |||
* thus JdbcLeakPrevention looks like our class to the DriverManager.</li> | |||
* </li> | |||
* </p> | |||
*/ | |||
public void stop() { | |||
if (classLoader != null) { | |||
classLoader.clearReferencesJdbc(); | |||
if (Thread.currentThread().getContextClassLoader() == classLoader) { | |||
Thread.currentThread().setContextClassLoader(classLoader.getParent()); | |||
} | |||
classLoader = null; | |||
} | |||
} | |||
private String[] downloadJdbcDriverIndex() { | |||
String url = "/deploy/jdbc-driver.txt"; | |||
try { | |||
LOG.debug("Download index of jdbc-driver"); | |||
String indexContent = serverClient.request(url); | |||
// File is empty when H2 is used | |||
if (Strings.isNullOrEmpty(indexContent)) { | |||
return new String[] {}; | |||
} | |||
return indexContent.split("\\|"); | |||
} catch (Exception e) { | |||
throw new SonarException("Fail to download jdbc-driver index: " + url, e); | |||
} | |||
} | |||
static class JdbcDriverClassLoader extends URLClassLoader { | |||
public JdbcDriverClassLoader(URL jdbcDriver, ClassLoader parent) { | |||
super(new URL[] {jdbcDriver}, parent); | |||
} | |||
public void clearReferencesJdbc() { | |||
InputStream is = getResourceAsStream("org/sonar/batch/bootstrap/JdbcLeakPrevention.class"); | |||
byte[] classBytes = new byte[2048]; | |||
int offset = 0; | |||
try { | |||
int read = is.read(classBytes, offset, classBytes.length - offset); | |||
while (read > -1) { | |||
offset += read; | |||
if (offset == classBytes.length) { | |||
// Buffer full - double size | |||
byte[] tmp = new byte[classBytes.length * 2]; | |||
System.arraycopy(classBytes, 0, tmp, 0, classBytes.length); | |||
classBytes = tmp; | |||
} | |||
read = is.read(classBytes, offset, classBytes.length - offset); | |||
} | |||
Class<?> lpClass = defineClass("org.sonar.batch.bootstrap.JdbcLeakPrevention", classBytes, 0, offset, this.getClass().getProtectionDomain()); | |||
Object obj = lpClass.newInstance(); | |||
obj.getClass().getMethod("unregisterDrivers").invoke(obj); | |||
} catch (Exception e) { | |||
LOG.warn("JDBC driver deregistration failed", e); | |||
} finally { | |||
if (is != null) { | |||
try { | |||
is.close(); | |||
} catch (IOException ioe) { | |||
LOG.warn(ioe.getMessage(), ioe); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -1,72 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import java.sql.Driver; | |||
import java.sql.DriverManager; | |||
import java.sql.SQLException; | |||
import java.util.ArrayList; | |||
import java.util.Enumeration; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import java.util.Set; | |||
/** | |||
* Companion of {@link JdbcDriverHolder} and allows it to deregister JDBC drivers. | |||
* <p> | |||
* Some hacks are involved in the loading of the class - see {@link JdbcDriverHolder#stop()}, | |||
* so this class can refer to classes only from java.* package and must not be referred from other classes. | |||
* Placement and naming of this class and methods are very important, since it loaded and invoked via reflection. | |||
* </p> | |||
*/ | |||
public class JdbcLeakPrevention { | |||
/** | |||
* @return names of the drivers that have been unregistered | |||
*/ | |||
public List<String> unregisterDrivers() throws SQLException { | |||
Set<Driver> registeredDrivers = registeredDrivers(); | |||
List<String> unregisteredNames = new ArrayList<>(); | |||
Enumeration<Driver> drivers = DriverManager.getDrivers(); | |||
while (drivers.hasMoreElements()) { | |||
Driver driver = drivers.nextElement(); | |||
if (driver.getClass().getClassLoader() != this.getClass().getClassLoader()) { | |||
continue; | |||
} | |||
if (registeredDrivers.contains(driver)) { | |||
unregisteredNames.add(driver.getClass().getCanonicalName()); | |||
} | |||
DriverManager.deregisterDriver(driver); | |||
} | |||
return unregisteredNames; | |||
} | |||
private static Set<Driver> registeredDrivers() { | |||
Set<Driver> registeredDrivers = new HashSet<>(); | |||
Enumeration<Driver> drivers = DriverManager.getDrivers(); | |||
while (drivers.hasMoreElements()) { | |||
Driver driver = drivers.nextElement(); | |||
registeredDrivers.add(driver); | |||
} | |||
return registeredDrivers; | |||
} | |||
} |
@@ -1,125 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.components; | |||
import com.google.common.collect.Maps; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import java.util.Map; | |||
import javax.annotation.Nullable; | |||
import javax.persistence.Query; | |||
import org.apache.commons.lang.ObjectUtils; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.measures.Metric; | |||
import org.sonar.api.measures.MetricFinder; | |||
import org.sonar.api.resources.Resource; | |||
/** | |||
* Can't be moved. Used by devcockpit. | |||
*/ | |||
@BatchSide | |||
public class PastMeasuresLoader { | |||
private Map<Integer, Metric> metricByIds; | |||
private DatabaseSession session; | |||
public PastMeasuresLoader(DatabaseSession session, MetricFinder metricFinder) { | |||
this(session, metricFinder.findAll()); | |||
} | |||
PastMeasuresLoader(DatabaseSession session, Collection<Metric> metrics) { | |||
this.session = session; | |||
this.metricByIds = Maps.newHashMap(); | |||
for (Metric metric : metrics) { | |||
if (metric.isNumericType()) { | |||
metricByIds.put(metric.getId(), metric); | |||
} | |||
} | |||
} | |||
public Collection<Metric> getMetrics() { | |||
return metricByIds.values(); | |||
} | |||
public List<Object[]> getPastMeasures(Resource resource, PastSnapshot projectPastSnapshot) { | |||
if (projectPastSnapshot != null && projectPastSnapshot.getProjectSnapshot() != null) { | |||
return getPastMeasures(resource.getEffectiveKey(), resource.getPath(), projectPastSnapshot.getProjectSnapshot()); | |||
} | |||
return Collections.emptyList(); | |||
} | |||
public List<Object[]> getPastMeasures(String resourceKey, Snapshot projectPastSnapshot) { | |||
return getPastMeasures(resourceKey, null, projectPastSnapshot); | |||
} | |||
public List<Object[]> getPastMeasures(String resourceKey, @Nullable String path, Snapshot projectPastSnapshot) { | |||
String sql = "select m.metric_id, m.characteristic_id, m.person_id, m.rule_id, m.value from project_measures m, snapshots s" + | |||
" where m.snapshot_id=s.id and m.metric_id in (:metricIds) " + | |||
" and (s.root_snapshot_id=:rootSnapshotId or s.id=:rootSnapshotId) " + | |||
" and s.status=:status and s.project_id=(select p.id from projects p where p.kee=:resourceKey" | |||
+ (StringUtils.isNotBlank(path) ? " and p.path=:path" : "") | |||
+ ")"; | |||
Query q = session.createNativeQuery(sql) | |||
.setParameter("metricIds", metricByIds.keySet()) | |||
.setParameter("rootSnapshotId", ObjectUtils.defaultIfNull(projectPastSnapshot.getRootId(), projectPastSnapshot.getId())) | |||
.setParameter("resourceKey", resourceKey) | |||
.setParameter("status", Snapshot.STATUS_PROCESSED); | |||
if (StringUtils.isNotBlank(path)) { | |||
q.setParameter("path", path); | |||
} | |||
return q.getResultList(); | |||
} | |||
public static int getMetricId(Object[] row) { | |||
// can be BigDecimal on Oracle | |||
return ((Number) row[0]).intValue(); | |||
} | |||
public static Integer getCharacteristicId(Object[] row) { | |||
// can be BigDecimal on Oracle | |||
Number number = (Number) row[1]; | |||
return number != null ? number.intValue() : null; | |||
} | |||
public static Integer getPersonId(Object[] row) { | |||
// can be BigDecimal on Oracle | |||
Number number = (Number) row[2]; | |||
return number != null ? number.intValue() : null; | |||
} | |||
public static Integer getRuleId(Object[] row) { | |||
// can be BigDecimal on Oracle | |||
Number number = (Number) row[3]; | |||
return number != null ? number.intValue() : null; | |||
} | |||
public static boolean hasValue(Object[] row) { | |||
return row[4] != null; | |||
} | |||
public static double getValue(Object[] row) { | |||
return ((Number) row[4]).doubleValue(); | |||
} | |||
} |
@@ -1,168 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.components; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.apache.commons.lang.builder.ReflectionToStringBuilder; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.utils.DateUtils; | |||
import javax.annotation.Nullable; | |||
import java.util.Calendar; | |||
import java.util.Date; | |||
import static org.sonar.api.utils.DateUtils.longToDate; | |||
/** | |||
* Used by devcockpit | |||
*/ | |||
public class PastSnapshot { | |||
private int index; | |||
private String mode; | |||
private String modeParameter; | |||
private Snapshot projectSnapshot; | |||
private Date targetDate = null; | |||
public PastSnapshot(String mode, @Nullable Date targetDate, @Nullable Snapshot projectSnapshot) { | |||
this.mode = mode; | |||
if (targetDate != null) { | |||
this.targetDate = org.apache.commons.lang.time.DateUtils.truncate(targetDate, Calendar.SECOND); | |||
} | |||
this.projectSnapshot = projectSnapshot; | |||
} | |||
public PastSnapshot(String mode, @Nullable Date targetDate) { | |||
this(mode, targetDate, null); | |||
} | |||
/** | |||
* See SONAR-2428 : even if previous analysis does not exist (no snapshot and no target date), we should perform comparison. | |||
*/ | |||
public PastSnapshot(String mode) { | |||
this(mode, null, null); | |||
} | |||
public PastSnapshot setIndex(int index) { | |||
this.index = index; | |||
return this; | |||
} | |||
public int getIndex() { | |||
return index; | |||
} | |||
public boolean isRelatedToSnapshot() { | |||
return projectSnapshot != null; | |||
} | |||
public Snapshot getProjectSnapshot() { | |||
return projectSnapshot; | |||
} | |||
public Date getDate() { | |||
return projectSnapshot != null ? longToDate(projectSnapshot.getCreatedAtMs()) : null; | |||
} | |||
public PastSnapshot setMode(String mode) { | |||
this.mode = mode; | |||
return this; | |||
} | |||
public String getMode() { | |||
return mode; | |||
} | |||
public String getModeParameter() { | |||
return modeParameter; | |||
} | |||
public PastSnapshot setModeParameter(String s) { | |||
this.modeParameter = s; | |||
return this; | |||
} | |||
public Integer getProjectSnapshotId() { | |||
return projectSnapshot != null ? projectSnapshot.getId() : null; | |||
} | |||
public String getQualifier() { | |||
return projectSnapshot != null ? projectSnapshot.getQualifier() : null; | |||
} | |||
/** | |||
* @deprecated in 4.2. Target date should only be used in labels. | |||
*/ | |||
@Deprecated | |||
public Date getTargetDate() { | |||
return targetDate; | |||
} | |||
public PastSnapshot clonePastSnapshot() { | |||
PastSnapshot clone = new PastSnapshot(mode, targetDate, projectSnapshot); | |||
clone.setIndex(index); | |||
clone.setModeParameter(modeParameter); | |||
return clone; | |||
} | |||
@Override | |||
public String toString() { | |||
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_VERSION)) { | |||
String label = String.format("Compare to version %s", modeParameter); | |||
if (targetDate != null) { | |||
label += String.format(" (%s)", DateUtils.formatDate(getDate())); | |||
} | |||
return label; | |||
} | |||
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_DAYS)) { | |||
String label = String.format("Compare over %s days (%s", modeParameter, DateUtils.formatDate(targetDate)); | |||
if (isRelatedToSnapshot()) { | |||
label += ", analysis of " + getDate(); | |||
} | |||
label += ")"; | |||
return label; | |||
} | |||
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS)) { | |||
String label = "Compare to previous analysis"; | |||
if (isRelatedToSnapshot()) { | |||
label += String.format(" (%s)", DateUtils.formatDate(getDate())); | |||
} | |||
return label; | |||
} | |||
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION)) { | |||
String label = "Compare to previous version"; | |||
if (isRelatedToSnapshot()) { | |||
label += String.format(" (%s)", DateUtils.formatDate(getDate())); | |||
} | |||
return label; | |||
} | |||
if (StringUtils.equals(mode, CoreProperties.TIMEMACHINE_MODE_DATE)) { | |||
String label = "Compare to date " + DateUtils.formatDate(targetDate); | |||
if (isRelatedToSnapshot()) { | |||
label += String.format(" (analysis of %s)", DateUtils.formatDate(getDate())); | |||
} | |||
return label; | |||
} | |||
return ReflectionToStringBuilder.toString(this); | |||
} | |||
} |
@@ -1,164 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.components; | |||
import com.google.common.base.Strings; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByDate; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByDays; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousAnalysis; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousVersion; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByVersion; | |||
import javax.annotation.Nullable; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
/** | |||
* Can't be moved since it is used by devcockpit. | |||
*/ | |||
@BatchSide | |||
public class PastSnapshotFinder { | |||
private static final Logger LOG = LoggerFactory.getLogger(PastSnapshotFinder.class); | |||
private PastSnapshotFinderByDays finderByDays; | |||
private PastSnapshotFinderByVersion finderByVersion; | |||
private PastSnapshotFinderByDate finderByDate; | |||
private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis; | |||
private PastSnapshotFinderByPreviousVersion finderByPreviousVersion; | |||
public PastSnapshotFinder(PastSnapshotFinderByDays finderByDays, PastSnapshotFinderByVersion finderByVersion, | |||
PastSnapshotFinderByDate finderByDate, PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis, | |||
PastSnapshotFinderByPreviousVersion finderByPreviousVersion) { | |||
this.finderByDays = finderByDays; | |||
this.finderByVersion = finderByVersion; | |||
this.finderByDate = finderByDate; | |||
this.finderByPreviousAnalysis = finderByPreviousAnalysis; | |||
this.finderByPreviousVersion = finderByPreviousVersion; | |||
} | |||
public PastSnapshot find(Snapshot projectSnapshot, @Nullable String rootQualifier, Settings settings, int index) { | |||
String propertyValue = getPropertyValue(rootQualifier, settings, index); | |||
PastSnapshot pastSnapshot = find(projectSnapshot, index, propertyValue); | |||
if (pastSnapshot == null && StringUtils.isNotBlank(propertyValue)) { | |||
LOG.debug("Property " + CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index + " is not valid: " + propertyValue); | |||
} | |||
return pastSnapshot; | |||
} | |||
public PastSnapshot find(Snapshot projectSnapshot, Settings settings, int index) { | |||
return find(projectSnapshot, null, settings, index); | |||
} | |||
static String getPropertyValue(@Nullable String rootQualifier, Settings settings, int index) { | |||
String value = settings.getString(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index); | |||
// For periods 4 and 5 we're searching for a property prefixed by the qualifier | |||
if (index > 3 && Strings.isNullOrEmpty(value)) { | |||
value = settings.getString(CoreProperties.TIMEMACHINE_PERIOD_PREFIX + index + "." + rootQualifier); | |||
} | |||
return value; | |||
} | |||
public PastSnapshot findPreviousAnalysis(Snapshot projectSnapshot) { | |||
return finderByPreviousAnalysis.findByPreviousAnalysis(projectSnapshot); | |||
} | |||
@Nullable | |||
public PastSnapshot find(Snapshot projectSnapshot, int index, String property) { | |||
if (StringUtils.isBlank(property)) { | |||
return null; | |||
} | |||
PastSnapshot result = findByDays(projectSnapshot, property); | |||
if (result == null) { | |||
result = findByDate(projectSnapshot, property); | |||
if (result == null) { | |||
result = findByPreviousAnalysis(projectSnapshot, property); | |||
if (result == null) { | |||
result = findByPreviousVersion(projectSnapshot, property); | |||
if (result == null) { | |||
result = findByVersion(projectSnapshot, property); | |||
} | |||
} | |||
} | |||
} | |||
if (result != null) { | |||
result.setIndex(index); | |||
} | |||
return result; | |||
} | |||
@Nullable | |||
private PastSnapshot findByPreviousAnalysis(Snapshot projectSnapshot, String property) { | |||
PastSnapshot pastSnapshot = null; | |||
if (StringUtils.equals(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, property)) { | |||
pastSnapshot = finderByPreviousAnalysis.findByPreviousAnalysis(projectSnapshot); | |||
} | |||
return pastSnapshot; | |||
} | |||
@Nullable | |||
private PastSnapshot findByPreviousVersion(Snapshot projectSnapshot, String property) { | |||
PastSnapshot pastSnapshot = null; | |||
if (StringUtils.equals(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION, property)) { | |||
pastSnapshot = finderByPreviousVersion.findByPreviousVersion(projectSnapshot); | |||
} | |||
return pastSnapshot; | |||
} | |||
@Nullable | |||
private PastSnapshot findByDate(Snapshot projectSnapshot, String property) { | |||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); | |||
try { | |||
Date date = format.parse(property); | |||
return finderByDate.findByDate(projectSnapshot, date); | |||
} catch (ParseException e) { | |||
return null; | |||
} | |||
} | |||
private PastSnapshot findByVersion(Snapshot projectSnapshot, String property) { | |||
return finderByVersion.findByVersion(projectSnapshot, property); | |||
} | |||
@Nullable | |||
private PastSnapshot findByDays(Snapshot projectSnapshot, String property) { | |||
try { | |||
int days = Integer.parseInt(property); | |||
return finderByDays.findFromDays(projectSnapshot, days); | |||
} catch (NumberFormatException e) { | |||
return null; | |||
} | |||
} | |||
} |
@@ -1,49 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.components; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import java.util.Date; | |||
/** | |||
* Used by devcockpit | |||
*/ | |||
public class Period { | |||
private int index; | |||
private Date date; | |||
public Period(int index, @Nullable Date date) { | |||
this.index = index; | |||
this.date = date; | |||
} | |||
public int getIndex() { | |||
return index; | |||
} | |||
@CheckForNull | |||
public Date getDate() { | |||
return date; | |||
} | |||
} |
@@ -1,91 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.components; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.batch.RequiresDB; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.deprecated.components.PeriodsDefinition; | |||
import javax.annotation.CheckForNull; | |||
import java.util.List; | |||
import static com.google.common.collect.Lists.newLinkedList; | |||
import static org.sonar.api.utils.DateUtils.longToDate; | |||
@RequiresDB | |||
@BatchSide | |||
public class TimeMachineConfiguration { | |||
private static final Logger LOG = LoggerFactory.getLogger(TimeMachineConfiguration.class); | |||
private final DatabaseSession session; | |||
private final PeriodsDefinition periodsDefinition; | |||
private List<Period> periods; | |||
private List<PastSnapshot> modulePastSnapshots; | |||
public TimeMachineConfiguration(DatabaseSession session, PeriodsDefinition periodsDefinition) { | |||
this.session = session; | |||
this.periodsDefinition = periodsDefinition; | |||
initModulePastSnapshots(); | |||
} | |||
private void initModulePastSnapshots() { | |||
periods = newLinkedList(); | |||
modulePastSnapshots = newLinkedList(); | |||
for (PastSnapshot projectPastSnapshot : periodsDefinition.getRootProjectPastSnapshots()) { | |||
Snapshot snapshot = findSnapshot(projectPastSnapshot.getProjectSnapshot()); | |||
PastSnapshot pastSnapshot = projectPastSnapshot.clonePastSnapshot(); | |||
modulePastSnapshots.add(pastSnapshot); | |||
// When no snapshot is found, date of the period is null | |||
periods.add(new Period(pastSnapshot.getIndex(), snapshot != null ? longToDate(snapshot.getCreatedAtMs()) : null)); | |||
LOG.info(pastSnapshot.toString()); | |||
} | |||
} | |||
/** | |||
* Only used to get the real date of the snapshot on the current period. | |||
* The date is used to calculate new_violations measures | |||
*/ | |||
@CheckForNull | |||
private Snapshot findSnapshot(Snapshot projectSnapshot) { | |||
String hql = "from " + Snapshot.class.getSimpleName() + " where resourceId=:resourceId and (rootId=:rootSnapshotId or id=:rootSnapshotId)"; | |||
List<Snapshot> snapshots = session.createQuery(hql) | |||
.setParameter("resourceId", projectSnapshot.getResourceId()) | |||
.setParameter("rootSnapshotId", projectSnapshot.getId()) | |||
.setMaxResults(1) | |||
.getResultList(); | |||
return snapshots.isEmpty() ? null : snapshots.get(0); | |||
} | |||
public List<Period> periods() { | |||
return periods; | |||
} | |||
public List<PastSnapshot> getProjectPastSnapshots() { | |||
return modulePastSnapshots; | |||
} | |||
} |
@@ -1,23 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.batch.components; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -1,70 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import java.util.List; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import static org.sonar.api.utils.DateUtils.dateToLong; | |||
@BatchSide | |||
public class PastSnapshotFinderByDate { | |||
private DatabaseSession session; | |||
public PastSnapshotFinderByDate(DatabaseSession session) { | |||
this.session = session; | |||
} | |||
public PastSnapshot findByDate(Snapshot projectSnapshot, Date date) { | |||
Integer projectId = projectSnapshot != null ? projectSnapshot.getResourceId() : null; | |||
return findByDate(projectId, date); | |||
} | |||
PastSnapshot findByDate(Integer projectId, Date date) { | |||
Snapshot snapshot = null; | |||
if (projectId != null) { | |||
snapshot = findSnapshot(projectId, date); | |||
} | |||
SimpleDateFormat format = new SimpleDateFormat(DateUtils.DATE_FORMAT); | |||
return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DATE, date, snapshot).setModeParameter(format.format(date)); | |||
} | |||
@CheckForNull | |||
private Snapshot findSnapshot(Integer projectId, Date date) { | |||
String hql = "from " + Snapshot.class.getSimpleName() + " where createdAt>=:date AND resourceId=:resourceId AND status=:status order by createdAt asc"; | |||
List<Snapshot> snapshots = session.createQuery(hql) | |||
.setParameter("date", dateToLong(date)) | |||
.setParameter("resourceId", projectId) | |||
.setParameter("status", Snapshot.STATUS_PROCESSED) | |||
.setMaxResults(1) | |||
.getResultList(); | |||
return snapshots.isEmpty() ? null : snapshots.get(0); | |||
} | |||
} |
@@ -1,77 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import java.util.Date; | |||
import java.util.List; | |||
import javax.annotation.CheckForNull; | |||
import org.apache.commons.lang.time.DateUtils; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.components.PastSnapshot; | |||
@BatchSide | |||
public class PastSnapshotFinderByDays { | |||
private DatabaseSession session; | |||
public PastSnapshotFinderByDays(DatabaseSession session) { | |||
this.session = session; | |||
} | |||
public PastSnapshot findFromDays(Snapshot projectSnapshot, int days) { | |||
Date targetDate = DateUtils.addDays(projectSnapshot.getCreatedAt(), -days); | |||
String hql = "from " + Snapshot.class.getSimpleName() + " where resourceId=:resourceId AND status=:status AND createdAt<:date order by createdAt asc"; | |||
List<Snapshot> snapshots = session.createQuery(hql) | |||
.setParameter("date", projectSnapshot.getCreatedAtMs()) | |||
.setParameter("resourceId", projectSnapshot.getResourceId()) | |||
.setParameter("status", Snapshot.STATUS_PROCESSED) | |||
.getResultList(); | |||
Snapshot snapshot = getNearestToTarget(snapshots, targetDate); | |||
return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DAYS, targetDate, snapshot).setModeParameter(String.valueOf(days)); | |||
} | |||
@CheckForNull | |||
static Snapshot getNearestToTarget(List<Snapshot> snapshots, Date currentDate, int distanceInDays) { | |||
Date targetDate = DateUtils.addDays(currentDate, -distanceInDays); | |||
return getNearestToTarget(snapshots, targetDate); | |||
} | |||
@CheckForNull | |||
static Snapshot getNearestToTarget(List<Snapshot> snapshots, Date targetDate) { | |||
long bestDistance = Long.MAX_VALUE; | |||
Snapshot nearest = null; | |||
for (Snapshot snapshot : snapshots) { | |||
long distance = distance(snapshot.getCreatedAt(), targetDate); | |||
if (distance <= bestDistance) { | |||
bestDistance = distance; | |||
nearest = snapshot; | |||
} | |||
} | |||
return nearest; | |||
} | |||
static long distance(Date d1, Date d2) { | |||
return Math.abs(d1.getTime() - d2.getTime()); | |||
} | |||
} |
@@ -1,62 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import java.util.List; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import static org.sonar.api.utils.DateUtils.longToDate; | |||
@BatchSide | |||
public class PastSnapshotFinderByPreviousAnalysis { | |||
private DatabaseSession session; | |||
public PastSnapshotFinderByPreviousAnalysis(DatabaseSession session) { | |||
this.session = session; | |||
} | |||
public PastSnapshot findByPreviousAnalysis(Snapshot projectSnapshot) { | |||
String hql = "from " + Snapshot.class.getSimpleName() | |||
+ " where createdAt<:date AND resourceId=:resourceId AND status=:status and last=:last order by createdAt desc"; | |||
List<Snapshot> snapshots = session.createQuery(hql) | |||
.setParameter("date", projectSnapshot.getCreatedAtMs()) | |||
.setParameter("resourceId", projectSnapshot.getResourceId()) | |||
.setParameter("status", Snapshot.STATUS_PROCESSED) | |||
.setParameter("last", true) | |||
.setMaxResults(1) | |||
.getResultList(); | |||
if (snapshots.isEmpty()) { | |||
return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS); | |||
} | |||
Snapshot snapshot = snapshots.get(0); | |||
Date targetDate = longToDate(snapshot.getCreatedAtMs()); | |||
SimpleDateFormat format = new SimpleDateFormat(DateUtils.DATE_FORMAT); | |||
return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, targetDate, snapshot).setModeParameter(format.format(targetDate)); | |||
} | |||
} |
@@ -1,63 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import org.sonar.core.event.db.EventMapper; | |||
import org.sonar.core.persistence.DbSession; | |||
import org.sonar.core.persistence.MyBatis; | |||
import static org.sonar.api.utils.DateUtils.longToDate; | |||
@BatchSide | |||
public class PastSnapshotFinderByPreviousVersion { | |||
private final DatabaseSession session; | |||
private final MyBatis mybatis; | |||
public PastSnapshotFinderByPreviousVersion(DatabaseSession session, MyBatis mybatis) { | |||
this.session = session; | |||
this.mybatis = mybatis; | |||
} | |||
public PastSnapshot findByPreviousVersion(Snapshot projectSnapshot) { | |||
String currentVersion = projectSnapshot.getVersion(); | |||
Integer resourceId = projectSnapshot.getResourceId(); | |||
Long snapshotId; | |||
// Commit Hibernate transaction to avoid lock of project table | |||
session.commit(); | |||
try (DbSession dbSession = mybatis.openSession(false)) { | |||
snapshotId = dbSession.getMapper(EventMapper.class).findSnapshotIdOfPreviousVersion(resourceId, currentVersion); | |||
} | |||
if (snapshotId == null) { | |||
return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION); | |||
} | |||
Snapshot snapshot = session.getSingleResult(Snapshot.class, "id", snapshotId.intValue()); | |||
return new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION, longToDate(snapshot.getCreatedAtMs()), snapshot).setModeParameter(snapshot.getVersion()); | |||
} | |||
} |
@@ -1,61 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import java.util.Date; | |||
import java.util.List; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import static org.sonar.api.utils.DateUtils.longToDate; | |||
@BatchSide | |||
public class PastSnapshotFinderByVersion { | |||
private final DatabaseSession session; | |||
public PastSnapshotFinderByVersion(DatabaseSession session) { | |||
this.session = session; | |||
} | |||
public PastSnapshot findByVersion(Snapshot projectSnapshot, String version) { | |||
String hql = "from " + Snapshot.class.getSimpleName() + " where version=:version AND resourceId=:resourceId AND status=:status order by createdAt desc"; | |||
List<Snapshot> snapshots = session.createQuery(hql) | |||
.setParameter("version", version) | |||
.setParameter("resourceId", projectSnapshot.getResourceId()) | |||
.setParameter("status", Snapshot.STATUS_PROCESSED) | |||
.setMaxResults(1) | |||
.getResultList(); | |||
PastSnapshot result; | |||
if (snapshots.isEmpty()) { | |||
result = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION); | |||
} else { | |||
Snapshot snapshot = snapshots.get(0); | |||
Date targetDate = longToDate(snapshot.getCreatedAtMs()); | |||
result = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION, targetDate, snapshot).setModeParameter(version); | |||
} | |||
return result; | |||
} | |||
} |
@@ -1,95 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import java.util.List; | |||
import javax.persistence.Query; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.DefaultProjectTree; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import org.sonar.batch.components.PastSnapshotFinder; | |||
import static com.google.common.collect.Lists.newLinkedList; | |||
import static org.sonar.api.utils.DateUtils.dateToLong; | |||
@BatchSide | |||
public class PeriodsDefinition { | |||
private static final int NUMBER_OF_VARIATION_SNAPSHOTS = 5; | |||
private DatabaseSession session; | |||
private DefaultProjectTree projectTree; | |||
private final Settings settings; | |||
private List<PastSnapshot> projectPastSnapshots; | |||
public PeriodsDefinition(DatabaseSession session, DefaultProjectTree projectTree, Settings settings, | |||
PastSnapshotFinder pastSnapshotFinder) { | |||
this.session = session; | |||
this.projectTree = projectTree; | |||
this.settings = settings; | |||
initPastSnapshots(pastSnapshotFinder, projectTree.getRootProject().getQualifier()); | |||
} | |||
private void initPastSnapshots(PastSnapshotFinder pastSnapshotFinder, String rootQualifier) { | |||
Snapshot projectSnapshot = buildProjectSnapshot(); | |||
projectPastSnapshots = newLinkedList(); | |||
if (projectSnapshot != null) { | |||
for (int index = 1; index <= NUMBER_OF_VARIATION_SNAPSHOTS; index++) { | |||
PastSnapshot pastSnapshot = pastSnapshotFinder.find(projectSnapshot, rootQualifier, settings, index); | |||
// SONAR-4700 Add a past snapshot only if it exists | |||
if (pastSnapshot != null && pastSnapshot.getProjectSnapshot() != null) { | |||
projectPastSnapshots.add(pastSnapshot); | |||
} | |||
} | |||
} | |||
} | |||
private Snapshot buildProjectSnapshot() { | |||
Query query = session | |||
.createNativeQuery("select p.id from projects p where p.kee=:resourceKey and p.enabled=:enabled"); | |||
query.setParameter("resourceKey", projectTree.getRootProject().getKey()); | |||
query.setParameter("enabled", Boolean.TRUE); | |||
Snapshot snapshot = null; | |||
Number projectId = session.getSingleResult(query, null); | |||
if (projectId != null) { | |||
snapshot = new Snapshot(); | |||
snapshot.setResourceId(projectId.intValue()); | |||
snapshot.setCreatedAtMs(dateToLong(projectTree.getRootProject().getAnalysisDate())); | |||
snapshot.setBuildDateMs(System.currentTimeMillis()); | |||
snapshot.setVersion(projectTree.getRootProject().getAnalysisVersion()); | |||
} | |||
return snapshot; | |||
} | |||
/** | |||
* @return past snapshots of root project | |||
*/ | |||
public List<PastSnapshot> getRootProjectPastSnapshots() { | |||
return projectPastSnapshots; | |||
} | |||
} |
@@ -56,7 +56,7 @@ public class MeasuresPublisher implements ReportPublisherStep { | |||
batchMeasures = Iterables.filter(batchMeasures, new Predicate<Measure>() { | |||
@Override | |||
public boolean apply(Measure input) { | |||
// Reload Metric to have all Hibernate fields populated | |||
// Reload Metric to have all fields populated | |||
input.setMetric(metricFinder.findByKey(input.getMetricKey())); | |||
return shouldPersistMeasure(resource.resource(), input); | |||
} |
@@ -82,7 +82,6 @@ import org.sonar.batch.sensor.coverage.CoverageExclusions; | |||
import org.sonar.batch.source.HighlightableBuilder; | |||
import org.sonar.batch.source.SymbolizableBuilder; | |||
import org.sonar.core.platform.ComponentContainer; | |||
import org.sonar.core.timemachine.Periods; | |||
public class ModuleScanContainer extends ComponentContainer { | |||
private static final Logger LOG = LoggerFactory.getLogger(ModuleScanContainer.class); | |||
@@ -113,7 +112,6 @@ public class ModuleScanContainer extends ComponentContainer { | |||
add( | |||
EventBus.class, | |||
Periods.class, | |||
PhaseExecutor.class, | |||
RuleFinderCompatibility.class, | |||
PostJobsExecutor.class, |
@@ -42,9 +42,7 @@ import org.sonar.batch.bootstrap.ExtensionMatcher; | |||
import org.sonar.batch.bootstrap.ExtensionUtils; | |||
import org.sonar.batch.bootstrap.MetricProvider; | |||
import org.sonar.batch.bootstrapper.EnvironmentInformation; | |||
import org.sonar.batch.components.PastMeasuresLoader; | |||
import org.sonar.batch.deprecated.components.DefaultResourceCreationLock; | |||
import org.sonar.batch.deprecated.components.PeriodsDefinition; | |||
import org.sonar.batch.duplication.DuplicationCache; | |||
import org.sonar.batch.events.EventBus; | |||
import org.sonar.batch.index.BatchComponentCache; | |||
@@ -103,9 +101,6 @@ public class ProjectScanContainer extends ComponentContainer { | |||
add(component); | |||
} | |||
addBatchComponents(); | |||
if (analysisMode.isDb()) { | |||
addDataBaseComponents(); | |||
} | |||
addBatchExtensions(); | |||
Settings settings = getComponentByType(Settings.class); | |||
if (settings != null && settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)) { | |||
@@ -181,9 +176,6 @@ public class ProjectScanContainer extends ComponentContainer { | |||
Languages.class, | |||
DefaultLanguagesRepository.class, | |||
// Differential periods | |||
PeriodsDefinition.class, | |||
// Measures | |||
MeasureCache.class, | |||
@@ -206,10 +198,6 @@ public class ProjectScanContainer extends ComponentContainer { | |||
ScanTaskObservers.class); | |||
} | |||
private void addDataBaseComponents() { | |||
add(PastMeasuresLoader.class); | |||
} | |||
private void addBatchExtensions() { | |||
getComponentByType(ExtensionInstaller.class).install(this, new BatchExtensionFilter()); | |||
} |
@@ -18,14 +18,6 @@ | |||
</encoder> | |||
</appender> | |||
<logger name="org.hibernate.cache.ReadWriteCache"> | |||
<!-- removing "An item was expired by the cache while it was locked (increase your cache timeout)" msg --> | |||
<level value="ERROR"/> | |||
</logger> | |||
<logger name="org.hibernate"> | |||
<level value="WARN"/> | |||
</logger> | |||
<!-- BeanUtils generate to many DEBUG logs when sonar.verbose is set --> | |||
<logger name="org.apache.commons.beanutils.converters"> | |||
<level value="WARN"/> | |||
@@ -33,9 +25,6 @@ | |||
<!-- sonar.showSql --> | |||
<!-- see also org.sonar.core.persistence.MyBatis#configureLogback() --> | |||
<logger name="org.hibernate.SQL"> | |||
<level value="${SQL_LOGGER_LEVEL:-ERROR}"/> | |||
</logger> | |||
<logger name="org.mybatis"> | |||
<level value="${SQL_LOGGER_LEVEL:-WARN}"/> | |||
</logger> |
@@ -14,14 +14,6 @@ | |||
</encoder> | |||
</appender> | |||
<logger name="org.hibernate.cache.ReadWriteCache"> | |||
<!-- removing "An item was expired by the cache while it was locked (increase your cache timeout)" msg --> | |||
<level value="ERROR"/> | |||
</logger> | |||
<logger name="org.hibernate"> | |||
<level value="WARN"/> | |||
</logger> | |||
<!-- BeanUtils generate to many DEBUG logs when sonar.verbose is set --> | |||
<logger name="org.apache.commons.beanutils.converters"> | |||
<level value="WARN"/> | |||
@@ -29,9 +21,6 @@ | |||
<!-- sonar.showSql --> | |||
<!-- see also org.sonar.core.persistence.MyBatis#configureLogback() --> | |||
<logger name="org.hibernate.SQL"> | |||
<level value="ERROR"/> | |||
</logger> | |||
<logger name="org.apache.ibatis"> | |||
<level value="WARN"/> | |||
</logger> |
@@ -1,36 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import org.junit.Test; | |||
import org.sonar.api.database.DatabaseSession; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
public class BatchDatabaseSessionFactoryTest { | |||
@Test | |||
public void getSession() { | |||
DatabaseSession session = mock(DatabaseSession.class); | |||
BatchDatabaseSessionFactory factory = new BatchDatabaseSessionFactory(session); | |||
assertThat(factory.getSession()).isSameAs(session); | |||
} | |||
} |
@@ -1,42 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import org.junit.Test; | |||
import org.sonar.api.config.Settings; | |||
import java.util.Properties; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
public class BatchDatabaseTest { | |||
@Test | |||
public void should_init_at_least_two_connections() { | |||
BatchDatabase db = new BatchDatabase(new Settings(), mock(JdbcDriverHolder.class)); | |||
Properties props = new Properties(); | |||
db.doCompleteProperties(props); | |||
assertThat(Integer.parseInt(props.getProperty("sonar.jdbc.initialSize"))).isGreaterThanOrEqualTo(2); | |||
assertThat(Integer.parseInt(props.getProperty("sonar.jdbc.maxActive"))).isGreaterThanOrEqualTo(2); | |||
} | |||
} |
@@ -1,136 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import org.sonar.api.utils.MessageException; | |||
import org.sonar.core.persistence.DatabaseVersion; | |||
import org.sonar.core.properties.PropertiesDao; | |||
import org.sonar.core.properties.PropertyDto; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class DatabaseCompatibilityTest { | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
DatabaseVersion databaseVersion; | |||
ServerClient server; | |||
Settings settings; | |||
PropertiesDao propertiesDao; | |||
private DefaultAnalysisMode mode; | |||
@Before | |||
public void init() { | |||
server = mock(ServerClient.class); | |||
when(server.getURL()).thenReturn("http://localhost:9000"); | |||
when(server.request("/api/server")).thenReturn("{\"id\":\"123456\",\"version\":\"3.1\",\"status\":\"UP\"}"); | |||
settings = new Settings(); | |||
settings.setProperty(DatabaseProperties.PROP_URL, "jdbc:postgresql://localhost/foo"); | |||
settings.setProperty(DatabaseProperties.PROP_USER, "bar"); | |||
propertiesDao = mock(PropertiesDao.class); | |||
when(propertiesDao.selectGlobalProperty(CoreProperties.SERVER_ID)).thenReturn(new PropertyDto().setValue("123456")); | |||
mode = mock(DefaultAnalysisMode.class); | |||
databaseVersion = mock(DatabaseVersion.class); | |||
} | |||
@Test | |||
public void shouldFailIfRequiresDowngrade() { | |||
when(databaseVersion.getStatus()).thenReturn(DatabaseVersion.Status.REQUIRES_DOWNGRADE); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("Database relates to a more recent version of SonarQube. Please check your settings (JDBC settings, version of Maven plugin)"); | |||
new DatabaseCompatibility(databaseVersion, server, settings, propertiesDao, mode).start(); | |||
} | |||
@Test | |||
public void shouldFailIfRequiresUpgrade() { | |||
when(databaseVersion.getStatus()).thenReturn(DatabaseVersion.Status.REQUIRES_UPGRADE); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("Database must be upgraded."); | |||
new DatabaseCompatibility(databaseVersion, server, settings, propertiesDao, mode).start(); | |||
} | |||
@Test | |||
public void shouldFailIfNotSameServerId() { | |||
when(propertiesDao.selectGlobalProperty(CoreProperties.SERVER_ID)).thenReturn(new PropertyDto().setValue("11111111")); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("The current batch process and the configured remote server do not share the same DB configuration."); | |||
thrown.expectMessage("- Batch side: jdbc:postgresql://localhost/foo (bar / *****)"); | |||
thrown.expectMessage("- Server side: check the configuration at http://localhost:9000/system"); | |||
new DatabaseCompatibility(databaseVersion, server, settings, propertiesDao, mode).start(); | |||
} | |||
@Test | |||
public void shouldUseDefaultUserNameWhenFaillingIfNotSameServerIdAndNoUserNameFound() { | |||
when(propertiesDao.selectGlobalProperty(CoreProperties.SERVER_ID)).thenReturn(new PropertyDto().setValue("11111111")); | |||
settings.removeProperty(DatabaseProperties.PROP_USER); | |||
thrown.expect(MessageException.class); | |||
thrown.expectMessage("- Batch side: jdbc:postgresql://localhost/foo (sonar / *****)"); | |||
new DatabaseCompatibility(databaseVersion, server, settings, propertiesDao, mode).start(); | |||
} | |||
@Test | |||
public void shouldFailIfCantGetServerId() { | |||
when(server.request("/api/server")).thenThrow(new IllegalStateException()); | |||
thrown.expect(IllegalStateException.class); | |||
new DatabaseCompatibility(mock(DatabaseVersion.class), server, settings, propertiesDao, mode).start(); | |||
} | |||
@Test | |||
public void shouldDoNothingIfUpToDate() { | |||
when(databaseVersion.getStatus()).thenReturn(DatabaseVersion.Status.UP_TO_DATE); | |||
new DatabaseCompatibility(databaseVersion, server, settings, propertiesDao, mode).start(); | |||
// no error | |||
} | |||
@Test | |||
public void should_not_verify_compatibility_if_preview() { | |||
settings.setProperty(CoreProperties.SERVER_ID, "11111111"); | |||
when(mode.isPreview()).thenReturn(true); | |||
new DatabaseCompatibility(databaseVersion, server, settings, propertiesDao, mode).start(); | |||
// no failure | |||
} | |||
} |
@@ -22,10 +22,9 @@ package org.sonar.batch.bootstrap; | |||
import org.junit.Test; | |||
import org.sonar.api.BatchComponent; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.batch.RequiresDB; | |||
import org.sonar.api.batch.SupportedEnvironment; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.batch.bootstrapper.EnvironmentInformation; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -81,14 +80,6 @@ public class ExtensionUtilsTest { | |||
assertThat(ExtensionUtils.isMavenExtensionOnly(new BuildToolService())).isFalse(); | |||
} | |||
@Test | |||
public void shouldRequiresDB() { | |||
assertThat(ExtensionUtils.requiresDB(BatchService.class)).isFalse(); | |||
assertThat(ExtensionUtils.requiresDB(new BatchService())).isFalse(); | |||
assertThat(ExtensionUtils.requiresDB(PersistentService.class)).isTrue(); | |||
assertThat(ExtensionUtils.requiresDB(new PersistentService())).isTrue(); | |||
} | |||
@BatchSide | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
public static class BatchService { | |||
@@ -126,10 +117,4 @@ public class ExtensionUtilsTest { | |||
public static class BuildToolService { | |||
} | |||
@BatchSide | |||
@RequiresDB | |||
public static class PersistentService { | |||
} | |||
} |
@@ -1,121 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import com.google.common.io.Resources; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.home.cache.FileCache; | |||
import java.io.File; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Matchers.anyString; | |||
import static org.mockito.Matchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.never; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.verifyZeroInteractions; | |||
import static org.mockito.Mockito.when; | |||
public class JdbcDriverHolderTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
ClassLoader initialThreadClassloader; | |||
private DefaultAnalysisMode mode; | |||
@Before | |||
public void before() { | |||
initialThreadClassloader = Thread.currentThread().getContextClassLoader(); | |||
mode = mock(DefaultAnalysisMode.class); | |||
} | |||
@After | |||
public void after() { | |||
Thread.currentThread().setContextClassLoader(initialThreadClassloader); | |||
} | |||
@Test | |||
public void extend_classloader_with_jdbc_driver() { | |||
FileCache cache = mock(FileCache.class); | |||
File fakeDriver = new File(Resources.getResource(JdbcDriverHolderTest.class, "JdbcDriverHolderTest/jdbc-driver.jar").getFile()); | |||
when(cache.get(eq("ojdbc14.jar"), eq("fakemd5"), any(FileCache.Downloader.class))).thenReturn(fakeDriver); | |||
/* jdbc-driver.jar has just one file /foo/foo.txt */ | |||
assertThat(Thread.currentThread().getContextClassLoader().getResource("foo/foo.txt")).isNull(); | |||
ServerClient server = mock(ServerClient.class); | |||
when(server.request("/deploy/jdbc-driver.txt")).thenReturn("ojdbc14.jar|fakemd5"); | |||
when(server.request("/deploy/ojdbc14.jar")).thenReturn("fakecontent"); | |||
JdbcDriverHolder holder = new JdbcDriverHolder(cache, mode, server); | |||
holder.start(); | |||
assertThat(holder.getClassLoader().getResource("foo/foo.txt")).isNotNull(); | |||
assertThat(Thread.currentThread().getContextClassLoader()).isSameAs(holder.getClassLoader()); | |||
assertThat(holder.getClassLoader().getParent()).isSameAs(getClass().getClassLoader()); | |||
holder.stop(); | |||
assertThat(Thread.currentThread().getContextClassLoader()).isSameAs(getClass().getClassLoader()); | |||
assertThat(holder.getClassLoader()).isNull(); | |||
} | |||
@Test | |||
public void do_nothing_when_jdbc_driver_file_is_empty() { | |||
FileCache cache = mock(FileCache.class); | |||
ServerClient server = mock(ServerClient.class); | |||
when(server.request("/deploy/jdbc-driver.txt")).thenReturn(""); | |||
JdbcDriverHolder holder = new JdbcDriverHolder(cache, mode, server); | |||
holder.start(); | |||
verify(server, never()).download(anyString(), any(File.class)); | |||
verifyZeroInteractions(cache); | |||
assertThat(holder.getClassLoader()).isNull(); | |||
} | |||
@Test | |||
public void be_disabled_if_preview() { | |||
FileCache cache = mock(FileCache.class); | |||
when(mode.isPreview()).thenReturn(true); | |||
ServerClient server = mock(ServerClient.class); | |||
JdbcDriverHolder holder = new JdbcDriverHolder(cache, mode, server); | |||
holder.start(); | |||
assertThat(holder.getClassLoader()).isNull(); | |||
verifyZeroInteractions(server); | |||
// no error during stop | |||
holder.stop(); | |||
} | |||
} |
@@ -1,108 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.components; | |||
import org.junit.Test; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.measures.Metric; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import static org.hamcrest.MatcherAssert.assertThat; | |||
import static org.hamcrest.Matchers.hasItems; | |||
import static org.hamcrest.Matchers.is; | |||
import static org.hamcrest.Matchers.nullValue; | |||
public class PastMeasuresLoaderTest extends AbstractDbUnitTestCase { | |||
private static final int PROJECT_SNAPSHOT_ID = 1000; | |||
private static final String PROJECT_KEY = "project"; | |||
private static final String FILE_KEY = "project:org.foo.Bar"; | |||
@Test | |||
public void shouldGetPastResourceMeasures() { | |||
setupData("shared"); | |||
List<Metric> metrics = selectMetrics(); | |||
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); | |||
PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); | |||
List<Object[]> measures = loader.getPastMeasures(FILE_KEY, projectSnapshot); | |||
assertThat(measures.size(), is(2)); | |||
Object[] pastMeasure = measures.get(0); | |||
assertThat(PastMeasuresLoader.getMetricId(pastMeasure), is(1)); | |||
assertThat(PastMeasuresLoader.getCharacteristicId(pastMeasure), nullValue()); | |||
assertThat(PastMeasuresLoader.getPersonId(pastMeasure), nullValue()); | |||
assertThat(PastMeasuresLoader.getValue(pastMeasure), is(5.0)); | |||
pastMeasure = measures.get(1); | |||
assertThat(PastMeasuresLoader.getMetricId(pastMeasure), is(2)); | |||
assertThat(PastMeasuresLoader.getCharacteristicId(pastMeasure), nullValue()); | |||
assertThat(PastMeasuresLoader.getPersonId(pastMeasure), nullValue()); | |||
assertThat(PastMeasuresLoader.getValue(pastMeasure), is(60.0)); | |||
} | |||
@Test | |||
public void shouldGetPastProjectMeasures() { | |||
setupData("shared"); | |||
List<Metric> metrics = selectMetrics(); | |||
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", PROJECT_SNAPSHOT_ID); | |||
PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); | |||
List<Object[]> measures = loader.getPastMeasures(PROJECT_KEY, projectSnapshot); | |||
assertThat(measures.size(), is(2)); | |||
Object[] pastMeasure = measures.get(0); | |||
assertThat(PastMeasuresLoader.getMetricId(pastMeasure), is(1)); | |||
assertThat(PastMeasuresLoader.getCharacteristicId(pastMeasure), nullValue()); | |||
assertThat(PastMeasuresLoader.getPersonId(pastMeasure), nullValue()); | |||
assertThat(PastMeasuresLoader.getValue(pastMeasure), is(60.0)); | |||
pastMeasure = measures.get(1); | |||
assertThat(PastMeasuresLoader.getMetricId(pastMeasure), is(2)); | |||
assertThat(PastMeasuresLoader.getCharacteristicId(pastMeasure), nullValue()); | |||
assertThat(PastMeasuresLoader.getPersonId(pastMeasure), nullValue()); | |||
assertThat(PastMeasuresLoader.getValue(pastMeasure), is(80.0)); | |||
} | |||
@Test | |||
public void shouldKeepOnlyNumericalMetrics() { | |||
Metric ncloc = new Metric("ncloc", Metric.ValueType.INT); | |||
ncloc.setId(1); | |||
Metric complexity = new Metric("complexity", Metric.ValueType.INT); | |||
complexity.setId(2); | |||
Metric data = new Metric("data", Metric.ValueType.DATA); | |||
data.setId(3); | |||
List<Metric> metrics = Arrays.asList(ncloc, complexity, data); | |||
PastMeasuresLoader loader = new PastMeasuresLoader(getSession(), metrics); | |||
assertThat(loader.getMetrics().size(), is(2)); | |||
assertThat(loader.getMetrics(), hasItems(ncloc, complexity)); | |||
} | |||
private List<Metric> selectMetrics() { | |||
return getSession().getResults(Metric.class); | |||
} | |||
} |
@@ -1,231 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.components; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.mockito.ArgumentMatcher; | |||
import org.mockito.Mock; | |||
import org.mockito.MockitoAnnotations; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByDate; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByDays; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousAnalysis; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousVersion; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByVersion; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import static junit.framework.Assert.assertNull; | |||
import static org.hamcrest.Matchers.nullValue; | |||
import static org.hamcrest.core.Is.is; | |||
import static org.hamcrest.core.IsNot.not; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Matchers.argThat; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
public class PastSnapshotFinderTest { | |||
@Mock | |||
private PastSnapshotFinderByDays finderByDays; | |||
@Mock | |||
private PastSnapshotFinderByDate finderByDate; | |||
@Mock | |||
private PastSnapshotFinderByVersion finderByVersion; | |||
@Mock | |||
private PastSnapshotFinderByPreviousAnalysis finderByPreviousAnalysis; | |||
@Mock | |||
private PastSnapshotFinderByPreviousVersion finderByPreviousVersion; | |||
private PastSnapshotFinder finder; | |||
@Before | |||
public void initFinders() { | |||
MockitoAnnotations.initMocks(this); | |||
finder = new PastSnapshotFinder(finderByDays, finderByVersion, finderByDate, finderByPreviousAnalysis, finderByPreviousVersion); | |||
} | |||
@Test | |||
public void should_find() { | |||
Settings settings = new Settings().setProperty("sonar.timemachine.period5", "1.2"); | |||
when(finderByVersion.findByVersion(null, "1.2")).thenReturn(new PastSnapshot("version", new Date(), new Snapshot())); | |||
PastSnapshot variationSnapshot = finder.find(null, null, settings, 5); | |||
verify(finderByVersion).findByVersion(null, "1.2"); | |||
assertThat(variationSnapshot.getIndex(), is(5)); | |||
assertThat(variationSnapshot.getMode(), is("version")); | |||
assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); | |||
} | |||
@Test | |||
public void should_find_with_qualifier_suffix() { | |||
Settings settings = new Settings().setProperty("sonar.timemachine.period5.TRK", "1.2"); | |||
when(finderByVersion.findByVersion(null, "1.2")).thenReturn(new PastSnapshot("version", new Date(), new Snapshot())); | |||
PastSnapshot variationSnapshot = finder.find(null, "TRK", settings, 5); | |||
verify(finderByVersion).findByVersion(null, "1.2"); | |||
assertThat(variationSnapshot.getIndex(), is(5)); | |||
assertThat(variationSnapshot.getMode(), is("version")); | |||
assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); | |||
} | |||
@Test | |||
public void should_find_by_number_of_days() { | |||
when(finderByDays.findFromDays(null, 30)).thenReturn(new PastSnapshot("days", null).setModeParameter("30")); | |||
PastSnapshot variationSnapshot = finder.find(null, 1, "30"); | |||
verify(finderByDays).findFromDays(null, 30); | |||
assertNotNull(variationSnapshot); | |||
assertThat(variationSnapshot.getIndex(), is(1)); | |||
assertThat(variationSnapshot.getMode(), is("days")); | |||
assertThat(variationSnapshot.getModeParameter(), is("30")); | |||
} | |||
@Test | |||
public void should_not_find_by_number_of_days() { | |||
PastSnapshot variationSnapshot = finder.find(null, 1, "30"); | |||
verify(finderByDays).findFromDays(null, 30); | |||
assertNull(variationSnapshot); | |||
} | |||
@Test | |||
public void should_find_by_date() throws ParseException { | |||
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); | |||
final Date date = format.parse("2010-05-18"); | |||
when(finderByDate.findByDate((Snapshot) null, date)).thenReturn(new PastSnapshot("date", date, new Snapshot())); | |||
PastSnapshot variationSnapshot = finder.find(null, 2, "2010-05-18"); | |||
verify(finderByDate).findByDate(any(Snapshot.class), argThat(new ArgumentMatcher<Date>() { | |||
@Override | |||
public boolean matches(Object o) { | |||
return o.equals(date); | |||
} | |||
})); | |||
assertThat(variationSnapshot.getIndex(), is(2)); | |||
assertThat(variationSnapshot.getMode(), is("date")); | |||
assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); | |||
} | |||
@Test | |||
public void should_not_find_by_date() { | |||
when(finderByDate.findByDate(any(Snapshot.class), any(Date.class))).thenReturn(null); | |||
PastSnapshot variationSnapshot = finder.find(null, 2, "2010-05-18"); | |||
verify(finderByDate).findByDate(any(Snapshot.class), any(Date.class)); | |||
assertNull(variationSnapshot); | |||
} | |||
@Test | |||
public void should_find_by_previous_analysis() { | |||
final Date date = DateUtils.parseDate("2010-05-18"); | |||
Snapshot snapshot = new Snapshot(); | |||
snapshot.setCreatedAtMs(date.getTime()); | |||
when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, date, snapshot)); | |||
PastSnapshot variationSnapshot = finder.find(null, 2, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS); | |||
verify(finderByPreviousAnalysis).findByPreviousAnalysis(null); | |||
assertThat(variationSnapshot.getIndex(), is(2)); | |||
assertThat(variationSnapshot.getMode(), is(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS)); | |||
assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); | |||
} | |||
@Test | |||
public void should_not_find_previous_analysis() { | |||
when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(null); | |||
PastSnapshot variationSnapshot = finder.find(null, 2, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS); | |||
verify(finderByPreviousAnalysis).findByPreviousAnalysis(null); | |||
assertNull(variationSnapshot); | |||
} | |||
@Test | |||
public void should_find_by_previous_version() throws ParseException { | |||
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); | |||
final Date date = format.parse("2010-05-18"); | |||
Snapshot snapshot = new Snapshot(); | |||
snapshot.setCreatedAtMs(date.getTime()); | |||
when(finderByPreviousVersion.findByPreviousVersion(null)).thenReturn(new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION, date, snapshot)); | |||
PastSnapshot variationSnapshot = finder.find(null, 2, CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION); | |||
verify(finderByPreviousVersion).findByPreviousVersion(null); | |||
assertThat(variationSnapshot.getIndex(), is(2)); | |||
assertThat(variationSnapshot.getMode(), is(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION)); | |||
assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); | |||
} | |||
@Test | |||
public void should_find_by_version() { | |||
when(finderByVersion.findByVersion(null, "1.2")).thenReturn(new PastSnapshot("version", new Date(), new Snapshot())); | |||
PastSnapshot variationSnapshot = finder.find(null, 2, "1.2"); | |||
verify(finderByVersion).findByVersion(null, "1.2"); | |||
assertThat(variationSnapshot.getIndex(), is(2)); | |||
assertThat(variationSnapshot.getMode(), is("version")); | |||
assertThat(variationSnapshot.getProjectSnapshot(), not(nullValue())); | |||
} | |||
@Test | |||
public void should_not_find_version() { | |||
when(finderByVersion.findByVersion(null, "1.2")).thenReturn(null); | |||
PastSnapshot variationSnapshot = finder.find(null, 2, "1.2"); | |||
verify(finderByVersion).findByVersion(null, "1.2"); | |||
assertNull(variationSnapshot); | |||
} | |||
@Test | |||
public void should_not_fail_if_unknown_format() { | |||
// should not be called | |||
when(finderByPreviousAnalysis.findByPreviousAnalysis(null)).thenReturn(new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new Date(), new Snapshot())); | |||
assertNull(finder.find(null, 2, "foooo")); | |||
} | |||
@Test | |||
public void should_get_property_value() { | |||
Settings settings = new Settings().setProperty("sonar.timemachine.period1", "5"); | |||
assertThat(PastSnapshotFinder.getPropertyValue("FIL", settings, 1), is("5")); | |||
assertThat(PastSnapshotFinder.getPropertyValue("FIL", settings, 999), nullValue()); | |||
} | |||
} |
@@ -1,105 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.components; | |||
import org.junit.Test; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.resources.Qualifiers; | |||
import java.util.Date; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class PastSnapshotTest { | |||
@Test | |||
public void test_some_setters_and_getters() { | |||
Snapshot snapshot = new Snapshot().setQualifier(Qualifiers.FILE).setCreatedAtMs(System.currentTimeMillis()); | |||
snapshot.setId(10); | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION, new Date(), | |||
snapshot) | |||
.setModeParameter("2.3") | |||
.setIndex(1); | |||
assertThat(pastSnapshot.getModeParameter()).isEqualTo("2.3"); | |||
assertThat(pastSnapshot.getIndex()).isEqualTo(1); | |||
assertThat(pastSnapshot.getQualifier()).isEqualTo(Qualifiers.FILE); | |||
assertThat(pastSnapshot.getDate()).isNotNull(); | |||
assertThat(pastSnapshot.getProjectSnapshotId()).isEqualTo(10); | |||
} | |||
@Test | |||
public void test_some_setters_and_getters_with_empty_snapshot() { | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION); | |||
assertThat(pastSnapshot.getQualifier()).isNull(); | |||
assertThat(pastSnapshot.getDate()).isNull(); | |||
assertThat(pastSnapshot.getProjectSnapshotId()).isNull(); | |||
} | |||
@Test | |||
public void testToStringForVersion() { | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION, new Date(), new Snapshot().setCreatedAtMs(System.currentTimeMillis())).setModeParameter("2.3"); | |||
assertThat(pastSnapshot.toString()).startsWith("Compare to version 2.3"); | |||
} | |||
@Test | |||
public void testToStringForVersionWithoutDate() { | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_VERSION).setModeParameter("2.3"); | |||
assertThat(pastSnapshot.toString()).isEqualTo("Compare to version 2.3"); | |||
} | |||
@Test | |||
public void testToStringForNumberOfDays() { | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DAYS, new Date()).setModeParameter("30"); | |||
assertThat(pastSnapshot.toString()).startsWith("Compare over 30 days ("); | |||
} | |||
@Test | |||
public void testToStringForNumberOfDaysWithSnapshot() { | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DAYS, new Date(), new Snapshot().setCreatedAtMs(System.currentTimeMillis())).setModeParameter("30"); | |||
assertThat(pastSnapshot.toString()).startsWith("Compare over 30 days ("); | |||
} | |||
@Test | |||
public void testToStringForDate() { | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DATE, new Date()); | |||
assertThat(pastSnapshot.toString()).startsWith("Compare to date "); | |||
} | |||
@Test | |||
public void testToStringForDateWithSnapshot() { | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_DATE, new Date(), new Snapshot().setCreatedAtMs(System.currentTimeMillis())); | |||
assertThat(pastSnapshot.toString()).startsWith("Compare to date "); | |||
} | |||
@Test | |||
public void testToStringForPreviousAnalysis() { | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS, new Date(), new Snapshot().setCreatedAtMs(System.currentTimeMillis())); | |||
assertThat(pastSnapshot.toString()).startsWith("Compare to previous analysis "); | |||
} | |||
@Test | |||
public void testToStringForPreviousAnalysisWithoutDate() { | |||
PastSnapshot pastSnapshot = new PastSnapshot(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_ANALYSIS); | |||
assertThat(pastSnapshot.toString()).isEqualTo("Compare to previous analysis"); | |||
} | |||
} |
@@ -1,111 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.components; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.deprecated.components.PeriodsDefinition; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import java.util.Date; | |||
import static com.google.common.collect.Lists.newArrayList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class TimeMachineConfigurationTest extends AbstractDbUnitTestCase { | |||
private PeriodsDefinition periodsDefinition; | |||
@Before | |||
public void before() { | |||
setupData("shared"); | |||
periodsDefinition = mock(PeriodsDefinition.class); | |||
} | |||
@Test | |||
public void get_project_past_snapshot() { | |||
Snapshot projectSnapshot = new Snapshot(); | |||
projectSnapshot.setId(1010); | |||
projectSnapshot.setResourceId(1); | |||
PastSnapshot projectPastSnapshot = new PastSnapshot("mode", new Date(), projectSnapshot); | |||
when(periodsDefinition.getRootProjectPastSnapshots()).thenReturn(newArrayList(projectPastSnapshot)); | |||
TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), periodsDefinition); | |||
assertThat(timeMachineConfiguration.periods()).hasSize(1); | |||
assertThat(timeMachineConfiguration.periods().get(0).getDate()).isNotNull(); | |||
assertThat(timeMachineConfiguration.getProjectPastSnapshots()).hasSize(1); | |||
assertThat(timeMachineConfiguration.getProjectPastSnapshots().get(0).getProjectSnapshot().getId()).isEqualTo(1010); | |||
} | |||
@Test | |||
public void get_module_past_snapshot() { | |||
Snapshot projectSnapshot = new Snapshot(); | |||
projectSnapshot.setId(1010); | |||
projectSnapshot.setResourceId(2); | |||
PastSnapshot projectPastSnapshot = new PastSnapshot("mode", new Date(), projectSnapshot); | |||
when(periodsDefinition.getRootProjectPastSnapshots()).thenReturn(newArrayList(projectPastSnapshot)); | |||
TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), periodsDefinition); | |||
assertThat(timeMachineConfiguration.periods()).hasSize(1); | |||
assertThat(timeMachineConfiguration.periods().get(0).getDate()).isNotNull(); | |||
assertThat(timeMachineConfiguration.getProjectPastSnapshots()).hasSize(1); | |||
assertThat(timeMachineConfiguration.getProjectPastSnapshots().get(0).getProjectSnapshot().getId()).isEqualTo(1010); | |||
} | |||
@Test | |||
public void complete_past_snapshot_from_project_past_snapshot() { | |||
Snapshot projectSnapshot = new Snapshot(); | |||
projectSnapshot.setId(1010); | |||
PastSnapshot projectPastSnapshot = new PastSnapshot("mode", new Date(), projectSnapshot); | |||
projectPastSnapshot.setIndex(1); | |||
projectPastSnapshot.setMode("mode"); | |||
projectPastSnapshot.setModeParameter("modeParam"); | |||
when(periodsDefinition.getRootProjectPastSnapshots()).thenReturn(newArrayList(projectPastSnapshot)); | |||
TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), periodsDefinition); | |||
assertThat(timeMachineConfiguration.getProjectPastSnapshots()).hasSize(1); | |||
assertThat(timeMachineConfiguration.getProjectPastSnapshots().get(0).getProjectSnapshot().getId()).isEqualTo(1010); | |||
assertThat(timeMachineConfiguration.getProjectPastSnapshots().get(0).getIndex()).isEqualTo(1); | |||
assertThat(timeMachineConfiguration.getProjectPastSnapshots().get(0).getMode()).isEqualTo("mode"); | |||
assertThat(timeMachineConfiguration.getProjectPastSnapshots().get(0).getModeParameter()).isEqualTo("modeParam"); | |||
} | |||
@Test | |||
public void get_no_date_on_new_project() { | |||
Snapshot projectSnapshot = new Snapshot(); | |||
projectSnapshot.setId(1010); | |||
PastSnapshot projectPastSnapshot = new PastSnapshot("mode", new Date(), projectSnapshot); | |||
when(periodsDefinition.getRootProjectPastSnapshots()).thenReturn(newArrayList(projectPastSnapshot)); | |||
TimeMachineConfiguration timeMachineConfiguration = new TimeMachineConfiguration(getSession(), periodsDefinition); | |||
assertThat(timeMachineConfiguration.periods()).hasSize(1); | |||
assertThat(timeMachineConfiguration.periods().get(0).getDate()).isNull(); | |||
} | |||
} |
@@ -1,62 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import org.junit.Test; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Date; | |||
import static org.hamcrest.Matchers.is; | |||
import static org.junit.Assert.assertThat; | |||
public class PastSnapshotFinderByDateTest extends AbstractDbUnitTestCase { | |||
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); | |||
@Test | |||
public void shouldFindDate() throws ParseException { | |||
setupData("shared"); | |||
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); | |||
PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(getSession()); | |||
Date date = DATE_FORMAT.parse("2008-11-22"); | |||
PastSnapshot pastSnapshot = finder.findByDate(projectSnapshot, date); | |||
assertThat(pastSnapshot.getProjectSnapshotId(), is(1006)); | |||
} | |||
@Test | |||
public void shouldFindNearestLaterDate() throws ParseException { | |||
setupData("shared"); | |||
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); | |||
PastSnapshotFinderByDate finder = new PastSnapshotFinderByDate(getSession()); | |||
Date date = DATE_FORMAT.parse("2008-11-24"); | |||
PastSnapshot pastSnapshot = finder.findByDate(projectSnapshot, date); | |||
assertThat(pastSnapshot.getProjectSnapshotId(), is(1009)); | |||
} | |||
} |
@@ -1,113 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import org.hamcrest.core.IsNull; | |||
import org.junit.Test; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import java.text.ParseException; | |||
import java.text.SimpleDateFormat; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.Date; | |||
import java.util.List; | |||
import static org.hamcrest.Matchers.is; | |||
import static org.hamcrest.Matchers.nullValue; | |||
import static org.junit.Assert.assertThat; | |||
public class PastSnapshotFinderByDaysTest extends AbstractDbUnitTestCase { | |||
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); | |||
@Test | |||
public void shouldGetNextSnapshot() { | |||
setupData("shared"); | |||
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16 | |||
PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession()); | |||
assertThat(finder.findFromDays(projectSnapshot, 50).getProjectSnapshotId(), is(1000)); | |||
} | |||
@Test | |||
public void shouldIgnoreUnprocessedSnapshots() { | |||
setupData("shared"); | |||
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16 | |||
PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession()); | |||
assertThat(finder.findFromDays(projectSnapshot, 7).getProjectSnapshotId(), is(1006)); | |||
} | |||
@Test | |||
public void shouldNotFindSelf() { | |||
setupData("shouldNotFindSelf"); | |||
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1009); // 2008-11-16 | |||
PastSnapshotFinderByDays finder = new PastSnapshotFinderByDays(getSession()); | |||
assertThat(finder.findFromDays(projectSnapshot, 1).getProjectSnapshot(), nullValue()); | |||
} | |||
@Test | |||
public void shouldLocateNearestSnapshotBefore() throws ParseException { | |||
Date current = dateFormat.parse("2010-10-20"); | |||
// distance: 15 => target is 2010-10-05 | |||
List<Snapshot> snapshots = Arrays.asList( | |||
newSnapshot(1, "2010-09-30"), | |||
newSnapshot(2, "2010-10-03"),// -2 days | |||
newSnapshot(3, "2010-10-08"),// +3 days | |||
newSnapshot(4, "2010-10-12") // + 7 days | |||
); | |||
assertThat(PastSnapshotFinderByDays.getNearestToTarget(snapshots, current, 15).getId(), is(2)); | |||
} | |||
@Test | |||
public void shouldLocateNearestSnapshotAfter() throws ParseException { | |||
Date current = dateFormat.parse("2010-10-20"); | |||
// distance: 15 => target is 2010-10-05 | |||
List<Snapshot> snapshots = Arrays.asList( | |||
newSnapshot(1, "2010-09-30"), | |||
newSnapshot(2, "2010-10-01"),// -4 days | |||
newSnapshot(3, "2010-10-08"),// +3 days | |||
newSnapshot(4, "2010-10-12") // + 7 days | |||
); | |||
assertThat(PastSnapshotFinderByDays.getNearestToTarget(snapshots, current, 15).getId(), is(3)); | |||
} | |||
@Test | |||
public void shouldReturnNullIfNoSnapshots() throws ParseException { | |||
Date current = dateFormat.parse("2010-10-20"); | |||
List<Snapshot> snapshots = Collections.emptyList(); | |||
assertThat(PastSnapshotFinderByDays.getNearestToTarget(snapshots, current, 15), IsNull.nullValue()); | |||
} | |||
private Snapshot newSnapshot(int id, String date) throws ParseException { | |||
Snapshot snapshot = new Snapshot(); | |||
snapshot.setId(id); | |||
snapshot.setCreatedAtMs(dateFormat.parse(date).getTime()); | |||
return snapshot; | |||
} | |||
} |
@@ -1,56 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import org.junit.Test; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import static org.hamcrest.Matchers.is; | |||
import static org.hamcrest.core.IsNull.nullValue; | |||
import static org.junit.Assert.assertThat; | |||
public class PastSnapshotFinderByPreviousAnalysisTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void shouldFindPreviousAnalysis() { | |||
setupData("shouldFindPreviousAnalysis"); | |||
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); | |||
PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(getSession()); | |||
PastSnapshot pastSnapshot = finder.findByPreviousAnalysis(projectSnapshot); | |||
assertThat(pastSnapshot.getProjectSnapshotId(), is(1009)); | |||
} | |||
@Test | |||
public void shouldReturnPastSnapshotEvenWhenNoPreviousAnalysis() { | |||
setupData("shouldNotFindPreviousAnalysis"); | |||
Snapshot projectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); | |||
PastSnapshotFinderByPreviousAnalysis finder = new PastSnapshotFinderByPreviousAnalysis(getSession()); | |||
PastSnapshot pastSnapshot = finder.findByPreviousAnalysis(projectSnapshot); | |||
assertThat(pastSnapshot.isRelatedToSnapshot(), is(false)); | |||
assertThat(pastSnapshot.getProjectSnapshot(), nullValue()); | |||
assertThat(pastSnapshot.getDate(), nullValue()); | |||
} | |||
} |
@@ -1,73 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class PastSnapshotFinderByPreviousVersionTest extends AbstractDbUnitTestCase { | |||
private PastSnapshotFinderByPreviousVersion finder; | |||
@Before | |||
public void before() { | |||
finder = new PastSnapshotFinderByPreviousVersion(getSession(), getMyBatis()); | |||
} | |||
@Test | |||
public void shouldFindByPreviousVersion() { | |||
setupData("with-previous-version"); | |||
Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1003); | |||
PastSnapshot foundSnapshot = finder.findByPreviousVersion(currentProjectSnapshot); | |||
assertThat(foundSnapshot.getProjectSnapshotId()).isEqualTo(1001); | |||
assertThat(foundSnapshot.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION); | |||
assertThat(foundSnapshot.getModeParameter()).isEqualTo("1.1"); | |||
} | |||
@Test | |||
public void shouldFindByPreviousVersionWhenPreviousVersionDeleted() { | |||
setupData("with-previous-version-deleted"); | |||
Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1003); | |||
PastSnapshot foundSnapshot = finder.findByPreviousVersion(currentProjectSnapshot); | |||
assertThat(foundSnapshot.getProjectSnapshotId()).isEqualTo(1000); | |||
assertThat(foundSnapshot.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION); | |||
assertThat(foundSnapshot.getModeParameter()).isEqualTo("1.0"); | |||
} | |||
@Test | |||
public void testWithNoPreviousVersion() { | |||
setupData("no-previous-version"); | |||
Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1003); | |||
PastSnapshot foundSnapshot = finder.findByPreviousVersion(currentProjectSnapshot); | |||
assertThat(foundSnapshot.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_PREVIOUS_VERSION); | |||
assertThat(foundSnapshot.getProjectSnapshot()).isNull(); | |||
assertThat(foundSnapshot.getModeParameter()).isNull(); | |||
} | |||
} |
@@ -1,57 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import org.junit.Test; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.batch.components.PastSnapshot; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class PastSnapshotFinderByVersionTest extends AbstractDbUnitTestCase { | |||
@Test | |||
public void shouldFindByVersion() { | |||
setupData("shared"); | |||
Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); | |||
PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(getSession()); | |||
PastSnapshot foundSnapshot = finder.findByVersion(currentProjectSnapshot, "1.1"); | |||
assertThat(foundSnapshot.getProjectSnapshotId()).isEqualTo(1009); | |||
assertThat(foundSnapshot.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_VERSION); | |||
} | |||
@Test | |||
public void testIfNoVersionFound() { | |||
setupData("shared"); | |||
Snapshot currentProjectSnapshot = getSession().getSingleResult(Snapshot.class, "id", 1010); | |||
PastSnapshotFinderByVersion finder = new PastSnapshotFinderByVersion(getSession()); | |||
PastSnapshot foundSnapshot = finder.findByVersion(currentProjectSnapshot, "2.1"); | |||
assertThat(foundSnapshot.getMode()).isEqualTo(CoreProperties.TIMEMACHINE_MODE_VERSION); | |||
assertThat(foundSnapshot.getProjectSnapshot()).isNull(); | |||
assertThat(foundSnapshot.getModeParameter()).isNull(); | |||
} | |||
} |
@@ -1,76 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.deprecated.components; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.mockito.ArgumentMatcher; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.batch.DefaultProjectTree; | |||
import org.sonar.batch.components.PastSnapshotFinder; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import static org.mockito.Matchers.anyString; | |||
import static org.mockito.Matchers.argThat; | |||
import static org.mockito.Matchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.verifyZeroInteractions; | |||
import static org.mockito.Mockito.when; | |||
public class PeriodsDefinitionTest extends AbstractDbUnitTestCase { | |||
private Settings settings; | |||
private PastSnapshotFinder pastSnapshotFinder; | |||
@Before | |||
public void before() { | |||
setupData("shared"); | |||
settings = new Settings(); | |||
pastSnapshotFinder = mock(PastSnapshotFinder.class); | |||
} | |||
@Test | |||
public void should_init_past_snapshots() { | |||
DefaultProjectTree projectTree = mock(DefaultProjectTree.class); | |||
when(projectTree.getRootProject()).thenReturn(new Project("my:project")); | |||
new PeriodsDefinition(getSession(), projectTree, settings, pastSnapshotFinder); | |||
verify(pastSnapshotFinder).find(argThat(new ArgumentMatcher<Snapshot>() { | |||
@Override | |||
public boolean matches(Object o) { | |||
return ((Snapshot) o).getResourceId() == 1 /* see database in shared.xml */; | |||
} | |||
}), anyString(), eq(settings), eq(1)); | |||
} | |||
@Test | |||
public void should_not_init_past_snapshots_if_first_analysis() { | |||
DefaultProjectTree projectTree = mock(DefaultProjectTree.class); | |||
when(projectTree.getRootProject()).thenReturn(new Project("new:project")); | |||
new PeriodsDefinition(getSession(), projectTree, settings, pastSnapshotFinder); | |||
verifyZeroInteractions(pastSnapshotFinder); | |||
} | |||
} |
@@ -26,7 +26,6 @@ import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.resources.Directory; | |||
import org.sonar.api.resources.Java; | |||
import org.sonar.api.resources.Project; | |||
@@ -56,33 +55,33 @@ public class ComponentsPublisherTest { | |||
Project root = new Project("foo").setName("Root project").setDescription("Root description") | |||
.setAnalysisDate(DateUtils.parseDate(("2012-12-12"))); | |||
root.setId(1).setUuid("PROJECT_UUID"); | |||
resourceCache.add(root, null).setSnapshot(new Snapshot().setId(11)); | |||
resourceCache.add(root, null); | |||
Project module1 = new Project("module1").setName("Module1").setDescription("Module description"); | |||
module1.setParent(root); | |||
module1.setId(2).setUuid("MODULE_UUID"); | |||
resourceCache.add(module1, root).setSnapshot(new Snapshot().setId(12)); | |||
resourceCache.add(module1, root); | |||
rootDef.addSubProject(ProjectDefinition.create().setKey("module1")); | |||
Directory dir = Directory.create("src"); | |||
dir.setEffectiveKey("module1:src"); | |||
dir.setId(3).setUuid("DIR_UUID"); | |||
resourceCache.add(dir, module1).setSnapshot(new Snapshot().setId(13)); | |||
resourceCache.add(dir, module1); | |||
org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", Java.INSTANCE, false); | |||
file.setEffectiveKey("module1:src/Foo.java"); | |||
file.setId(4).setUuid("FILE_UUID"); | |||
resourceCache.add(file, dir).setSnapshot(new Snapshot().setId(14)).setInputPath(new DefaultInputFile("module1", "src/Foo.java").setLines(2)); | |||
resourceCache.add(file, dir).setInputPath(new DefaultInputFile("module1", "src/Foo.java").setLines(2)); | |||
org.sonar.api.resources.File fileWithoutLang = org.sonar.api.resources.File.create("src/make", null, false); | |||
fileWithoutLang.setEffectiveKey("module1:src/make"); | |||
fileWithoutLang.setId(5).setUuid("FILE_WITHOUT_LANG_UUID"); | |||
resourceCache.add(fileWithoutLang, dir).setSnapshot(new Snapshot().setId(15)).setInputPath(new DefaultInputFile("module1", "src/make").setLines(10)); | |||
resourceCache.add(fileWithoutLang, dir).setInputPath(new DefaultInputFile("module1", "src/make").setLines(10)); | |||
org.sonar.api.resources.File testFile = org.sonar.api.resources.File.create("test/FooTest.java", Java.INSTANCE, true); | |||
testFile.setEffectiveKey("module1:test/FooTest.java"); | |||
testFile.setId(6).setUuid("TEST_FILE_UUID"); | |||
resourceCache.add(testFile, dir).setSnapshot(new Snapshot().setId(16)).setInputPath(new DefaultInputFile("module1", "test/FooTest.java").setLines(4)); | |||
resourceCache.add(testFile, dir).setInputPath(new DefaultInputFile("module1", "test/FooTest.java").setLines(4)); | |||
ImmutableProjectReactor reactor = new ImmutableProjectReactor(rootDef); | |||
@@ -123,14 +122,14 @@ public class ComponentsPublisherTest { | |||
Project root = new Project("foo:my_branch").setName("Root project") | |||
.setAnalysisDate(DateUtils.parseDate(("2012-12-12"))); | |||
root.setId(1).setUuid("PROJECT_UUID"); | |||
resourceCache.add(root, null).setSnapshot(new Snapshot().setId(11)); | |||
resourceCache.add(root, null); | |||
rootDef.properties().put(CoreProperties.LINKS_HOME_PAGE, "http://home"); | |||
rootDef.properties().put(CoreProperties.PROJECT_BRANCH_PROPERTY, "my_branch"); | |||
Project module1 = new Project("module1:my_branch").setName("Module1"); | |||
module1.setParent(root); | |||
module1.setId(2).setUuid("MODULE_UUID"); | |||
resourceCache.add(module1, root).setSnapshot(new Snapshot().setId(12)); | |||
resourceCache.add(module1, root); | |||
ProjectDefinition moduleDef = ProjectDefinition.create().setKey("module1"); | |||
moduleDef.properties().put(CoreProperties.LINKS_CI, "http://ci"); | |||
rootDef.addSubProject(moduleDef); | |||
@@ -138,12 +137,12 @@ public class ComponentsPublisherTest { | |||
Directory dir = Directory.create("src"); | |||
dir.setEffectiveKey("module1:my_branch:my_branch:src"); | |||
dir.setId(3).setUuid("DIR_UUID"); | |||
resourceCache.add(dir, module1).setSnapshot(new Snapshot().setId(13)); | |||
resourceCache.add(dir, module1); | |||
org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", Java.INSTANCE, false); | |||
file.setEffectiveKey("module1:my_branch:my_branch:src/Foo.java"); | |||
file.setId(4).setUuid("FILE_UUID"); | |||
resourceCache.add(file, dir).setSnapshot(new Snapshot().setId(14)).setInputPath(new DefaultInputFile("module1", "src/Foo.java").setLines(2)); | |||
resourceCache.add(file, dir).setInputPath(new DefaultInputFile("module1", "src/Foo.java").setLines(2)); | |||
ImmutableProjectReactor reactor = new ImmutableProjectReactor(rootDef); | |||
@@ -19,13 +19,17 @@ | |||
*/ | |||
package org.sonar.batch.report; | |||
import java.io.File; | |||
import java.io.InputStream; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.Date; | |||
import org.apache.commons.io.FileUtils; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.api.measures.Measure; | |||
import org.sonar.api.resources.Project; | |||
@@ -36,12 +40,6 @@ import org.sonar.batch.protocol.output.BatchReportReader; | |||
import org.sonar.batch.protocol.output.BatchReportWriter; | |||
import org.sonar.batch.scan.measure.MeasureCache; | |||
import java.io.File; | |||
import java.io.InputStream; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.Date; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Matchers.anyString; | |||
import static org.mockito.Mockito.mock; | |||
@@ -62,7 +60,7 @@ public class CoveragePublisherTest { | |||
Project p = new Project("foo").setAnalysisDate(new Date(1234567L)); | |||
BatchComponentCache resourceCache = new BatchComponentCache(); | |||
sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php"); | |||
resourceCache.add(p, null).setSnapshot(new Snapshot().setId(2)); | |||
resourceCache.add(p, null); | |||
resourceCache.add(sampleFile, null).setInputPath(new DefaultInputFile("foo", "src/Foo.php").setLines(5)); | |||
measureCache = mock(MeasureCache.class); | |||
when(measureCache.byMetric(anyString(), anyString())).thenReturn(Collections.<Measure>emptyList()); |
@@ -28,7 +28,6 @@ import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.batch.index.BatchComponentCache; | |||
@@ -60,7 +59,7 @@ public class IssuesPublisherTest { | |||
project = new Project("foo").setAnalysisDate(new Date(1234567L)); | |||
BatchComponentCache componentCache = new BatchComponentCache(); | |||
org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php"); | |||
componentCache.add(project, null).setSnapshot(new Snapshot().setId(2)); | |||
componentCache.add(project, null); | |||
componentCache.add(sampleFile, project); | |||
issueCache = mock(IssueCache.class); | |||
when(issueCache.byComponent(anyString())).thenReturn(Collections.<DefaultIssue>emptyList()); |
@@ -20,7 +20,6 @@ | |||
package org.sonar.batch.report; | |||
import java.io.File; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.Date; | |||
import java.util.List; | |||
@@ -28,11 +27,9 @@ import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.measures.CoreMetrics; | |||
import org.sonar.api.measures.Measure; | |||
import org.sonar.api.measures.Metric; | |||
import org.sonar.api.measures.Metric.Level; | |||
import org.sonar.api.measures.Metric.ValueType; | |||
import org.sonar.api.measures.MetricFinder; | |||
import org.sonar.api.resources.Project; | |||
@@ -64,7 +61,7 @@ public class MeasuresPublisherTest { | |||
Project p = new Project("foo").setAnalysisDate(new Date(1234567L)); | |||
BatchComponentCache resourceCache = new BatchComponentCache(); | |||
sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php"); | |||
resourceCache.add(p, null).setSnapshot(new Snapshot().setId(2)); | |||
resourceCache.add(p, null); | |||
resourceCache.add(sampleFile, null); | |||
measureCache = mock(MeasureCache.class); | |||
when(measureCache.byResource(any(Resource.class))).thenReturn(Collections.<Measure>emptyList()); |
@@ -31,7 +31,6 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.rule.ActiveRules; | |||
import org.sonar.api.batch.rule.internal.DefaultActiveRules; | |||
import org.sonar.api.batch.rule.internal.NewActiveRule; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.batch.index.BatchComponentCache; | |||
import org.sonar.batch.protocol.output.BatchReport; | |||
@@ -58,7 +57,7 @@ public class MetadataPublisherTest { | |||
project = new Project("foo").setAnalysisDate(new Date(1234567L)); | |||
BatchComponentCache componentCache = new BatchComponentCache(); | |||
org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php"); | |||
componentCache.add(project, null).setSnapshot(new Snapshot().setId(2)); | |||
componentCache.add(project, null); | |||
componentCache.add(sampleFile, project); | |||
underTest = new MetadataPublisher(componentCache, new ImmutableProjectReactor(projectDef), activeRules); | |||
} |
@@ -19,23 +19,21 @@ | |||
*/ | |||
package org.sonar.batch.report; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.nio.charset.StandardCharsets; | |||
import java.util.Date; | |||
import org.apache.commons.io.FileUtils; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.TemporaryFolder; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.batch.index.BatchComponentCache; | |||
import org.sonar.batch.protocol.output.BatchReportWriter; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.nio.charset.StandardCharsets; | |||
import java.util.Date; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class SourcePublisherTest { | |||
@@ -57,7 +55,7 @@ public class SourcePublisherTest { | |||
BatchComponentCache resourceCache = new BatchComponentCache(); | |||
sampleFile = org.sonar.api.resources.File.create("src/Foo.php"); | |||
sampleFile.setEffectiveKey("foo:src/Foo.php"); | |||
resourceCache.add(p, null).setSnapshot(new Snapshot().setId(2)); | |||
resourceCache.add(p, null); | |||
File baseDir = temp.newFolder(); | |||
sourceFile = new File(baseDir, "src/Foo.php"); | |||
resourceCache.add(sampleFile, null).setInputPath( |
@@ -58,36 +58,6 @@ | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-home</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-core</artifactId> | |||
<!-- provided only by batch --> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-annotations</artifactId> | |||
<!-- provided only by batch --> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-commons-annotations</artifactId> | |||
<!-- provided only by batch --> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-entitymanager</artifactId> | |||
<!-- provided only by batch --> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>geronimo-spec</groupId> | |||
<artifactId>geronimo-spec-jta</artifactId> | |||
<!-- provided only by batch --> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>commons-dbcp</groupId> | |||
<artifactId>commons-dbcp</artifactId> |
@@ -19,12 +19,10 @@ | |||
*/ | |||
package org.sonar.core.persistence; | |||
import javax.sql.DataSource; | |||
import org.picocontainer.Startable; | |||
import org.sonar.core.persistence.dialect.Dialect; | |||
import javax.sql.DataSource; | |||
import java.util.Properties; | |||
/** | |||
* @since 2.12 | |||
*/ | |||
@@ -38,6 +36,4 @@ public interface Database extends Startable { | |||
* @return the dialect or null if start() has not been executed | |||
*/ | |||
Dialect getDialect(); | |||
Properties getHibernateProperties(); | |||
} |
@@ -20,11 +20,16 @@ | |||
package org.sonar.core.persistence; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
import javax.sql.DataSource; | |||
import org.apache.commons.dbcp.BasicDataSource; | |||
import org.apache.commons.dbcp.BasicDataSourceFactory; | |||
import org.apache.commons.dbutils.DbUtils; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.hibernate.cfg.Environment; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.config.Settings; | |||
@@ -32,15 +37,6 @@ import org.sonar.api.database.DatabaseProperties; | |||
import org.sonar.core.persistence.dialect.Dialect; | |||
import org.sonar.core.persistence.dialect.DialectUtils; | |||
import org.sonar.core.persistence.profiling.ProfiledDataSource; | |||
import org.sonar.jpa.session.CustomHibernateConnectionProvider; | |||
import javax.sql.DataSource; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
/** | |||
* @since 2.12 | |||
@@ -51,7 +47,6 @@ public class DefaultDatabase implements Database { | |||
private static final String DEFAULT_URL = "jdbc:h2:tcp://localhost/sonar"; | |||
private static final String SONAR_JDBC = "sonar.jdbc."; | |||
private static final String SONAR_HIBERNATE = "sonar.hibernate."; | |||
private static final String SONAR_JDBC_DIALECT = "sonar.jdbc.dialect"; | |||
private static final String SONAR_JDBC_URL = "sonar.jdbc.url"; | |||
private static final String VALIDATE = "validate"; | |||
@@ -89,7 +84,6 @@ public class DefaultDatabase implements Database { | |||
void initSettings() { | |||
properties = new Properties(); | |||
completeProperties(settings, properties, SONAR_JDBC); | |||
completeProperties(settings, properties, SONAR_HIBERNATE); | |||
completeDefaultProperties(properties); | |||
doCompleteProperties(properties); | |||
@@ -136,21 +130,6 @@ public class DefaultDatabase implements Database { | |||
return dialect; | |||
} | |||
@Override | |||
public Properties getHibernateProperties() { | |||
Properties props = new Properties(); | |||
List<String> hibernateKeys = settings.getKeysStartingWith(SONAR_HIBERNATE); | |||
for (String hibernateKey : hibernateKeys) { | |||
props.put(StringUtils.removeStart(hibernateKey, "sonar."), settings.getString(hibernateKey)); | |||
} | |||
props.put(Environment.DIALECT, getDialect().getHibernateDialectClass().getName()); | |||
props.put("hibernate.generate_statistics", "false"); | |||
props.put(Environment.CONNECTION_PROVIDER, CustomHibernateConnectionProvider.class.getName()); | |||
return props; | |||
} | |||
@Override | |||
public final DataSource getDataSource() { | |||
return datasource; | |||
@@ -195,7 +174,6 @@ public class DefaultDatabase implements Database { | |||
completeDefaultProperty(props, DatabaseProperties.PROP_URL, DEFAULT_URL); | |||
completeDefaultProperty(props, DatabaseProperties.PROP_USER, props.getProperty(DatabaseProperties.PROP_USER_DEPRECATED, DatabaseProperties.PROP_USER_DEFAULT_VALUE)); | |||
completeDefaultProperty(props, DatabaseProperties.PROP_PASSWORD, DatabaseProperties.PROP_PASSWORD_DEFAULT_VALUE); | |||
completeDefaultProperty(props, "sonar.jdbc.hibernate.hbm2ddl", VALIDATE); | |||
} | |||
private static void completeDefaultProperty(Properties props, String key, String defaultValue) { |
@@ -31,11 +31,6 @@ public interface Dialect { | |||
*/ | |||
String getId(); | |||
/** | |||
* @return the hibernate dialect class to be used | |||
*/ | |||
Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass(); | |||
/** | |||
* @return the activerecord dialect to be used | |||
*/ |
@@ -20,7 +20,6 @@ | |||
package org.sonar.core.persistence.dialect; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.hibernate.dialect.H2Dialect; | |||
/** | |||
* @since 1.12 | |||
@@ -33,11 +32,6 @@ public class H2 extends AbstractDialect { | |||
super(ID, ".h2.", "org.h2.Driver", "true", "false", "SELECT 1"); | |||
} | |||
@Override | |||
public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { | |||
return H2Dialect.class; | |||
} | |||
@Override | |||
public boolean matchesJdbcURL(String jdbcConnectionURL) { | |||
return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:h2:"); |
@@ -20,10 +20,6 @@ | |||
package org.sonar.core.persistence.dialect; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.hibernate.dialect.SQLServerDialect; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import java.sql.Types; | |||
public class MsSql extends AbstractDialect { | |||
@@ -33,11 +29,6 @@ public class MsSql extends AbstractDialect { | |||
super(ID, "sqlserver", "net.sourceforge.jtds.jdbc.Driver", "1", "0", "SELECT 1"); | |||
} | |||
@Override | |||
public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { | |||
return MsSqlDialect.class; | |||
} | |||
@Override | |||
public boolean matchesJdbcURL(String jdbcConnectionURL) { | |||
return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:microsoft:sqlserver:") | |||
@@ -48,25 +39,4 @@ public class MsSql extends AbstractDialect { | |||
public boolean supportsMigration() { | |||
return true; | |||
} | |||
public static class MsSqlDialect extends SQLServerDialect { | |||
public MsSqlDialect() { | |||
super(); | |||
registerColumnType(Types.DOUBLE, "decimal"); | |||
registerColumnType(Types.VARCHAR, 255, "nvarchar($l)"); | |||
registerColumnType(Types.VARCHAR, DatabaseProperties.MAX_TEXT_SIZE, "nvarchar(max)"); | |||
registerColumnType(Types.CHAR, "nchar(1)"); | |||
registerColumnType(Types.CLOB, "nvarchar(max)"); | |||
} | |||
@Override | |||
public String getTypeName(int code, int length, int precision, int scale) { | |||
if (code != 2005) { | |||
return super.getTypeName(code, length, precision, scale); | |||
} else { | |||
return "ntext"; | |||
} | |||
} | |||
} | |||
} | |||
@@ -20,10 +20,6 @@ | |||
package org.sonar.core.persistence.dialect; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.hibernate.dialect.MySQLDialect; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import java.sql.Types; | |||
/** | |||
* @since 1.12 | |||
@@ -36,26 +32,11 @@ public class MySql extends AbstractDialect { | |||
super(ID, "mysql", "com.mysql.jdbc.Driver", "true", "false", "SELECT 1"); | |||
} | |||
@Override | |||
public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { | |||
return MySqlWithDecimalDialect.class; | |||
} | |||
@Override | |||
public boolean matchesJdbcURL(String jdbcConnectionURL) { | |||
return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:mysql:"); | |||
} | |||
public static class MySqlWithDecimalDialect extends MySQLDialect { | |||
public MySqlWithDecimalDialect() { | |||
super(); | |||
registerColumnType(Types.DOUBLE, "decimal precision"); | |||
registerColumnType(Types.VARCHAR, DatabaseProperties.MAX_TEXT_SIZE, "longtext"); | |||
registerColumnType(Types.CLOB, "longtext"); | |||
registerColumnType(Types.BLOB, "blob"); | |||
} | |||
} | |||
@Override | |||
public int getScrollDefaultFetchSize() { | |||
return Integer.MIN_VALUE; |
@@ -20,10 +20,6 @@ | |||
package org.sonar.core.persistence.dialect; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.hibernate.dialect.Oracle10gDialect; | |||
import org.sonar.api.database.DatabaseProperties; | |||
import java.sql.Types; | |||
/** | |||
* @since 1.12 | |||
@@ -36,11 +32,6 @@ public class Oracle extends AbstractDialect { | |||
super(ID, "oracle", "oracle.jdbc.OracleDriver", "1", "0", "SELECT 1 FROM DUAL"); | |||
} | |||
@Override | |||
public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { | |||
return Oracle10gWithDecimalDialect.class; | |||
} | |||
@Override | |||
public boolean matchesJdbcURL(String jdbcConnectionURL) { | |||
return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:oracle:"); | |||
@@ -50,18 +41,4 @@ public class Oracle extends AbstractDialect { | |||
public boolean supportsMigration() { | |||
return true; | |||
} | |||
public static class Oracle10gWithDecimalDialect extends Oracle10gDialect { | |||
public Oracle10gWithDecimalDialect() { | |||
super(); | |||
registerColumnType(Types.DOUBLE, "number($p,$s)"); | |||
registerColumnType(Types.VARCHAR, DatabaseProperties.MAX_TEXT_SIZE, "clob"); | |||
registerColumnType(Types.VARBINARY, "blob"); | |||
} | |||
@Override | |||
public Class getNativeIdentifierGeneratorClass() { | |||
return OracleSequenceGenerator.class; | |||
} | |||
} | |||
} |
@@ -1,49 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.persistence.dialect; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.hibernate.dialect.Dialect; | |||
import org.hibernate.id.PersistentIdentifierGenerator; | |||
import org.hibernate.id.SequenceGenerator; | |||
import org.hibernate.type.Type; | |||
import java.util.Properties; | |||
/** | |||
* @since 1.10 | |||
*/ | |||
public class OracleSequenceGenerator extends SequenceGenerator { | |||
public static final String SEQUENCE_NAME_SUFFIX = "_SEQ"; | |||
@Override | |||
public void configure(Type type, Properties params, Dialect dialect) { | |||
String tableName = params.getProperty(PersistentIdentifierGenerator.TABLE); | |||
if (tableName != null) { | |||
StringBuilder sequenceNameBuilder = new StringBuilder(); | |||
sequenceNameBuilder.append(tableName); | |||
sequenceNameBuilder.append(SEQUENCE_NAME_SUFFIX); | |||
params.setProperty(SEQUENCE, StringUtils.upperCase(sequenceNameBuilder.toString())); | |||
} | |||
super.configure(type, params, dialect); | |||
} | |||
} |
@@ -1,62 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.persistence.dialect; | |||
import org.hibernate.dialect.Dialect; | |||
import org.hibernate.id.PersistentIdentifierGenerator; | |||
import org.hibernate.id.SequenceGenerator; | |||
import org.hibernate.type.Type; | |||
import java.util.Properties; | |||
/** | |||
* if the underlying database is PostgreSQL, the sequence | |||
* naming convention is different and includes the primary key | |||
* column name | |||
* | |||
* @since 1.10 | |||
*/ | |||
public class PostgreSQLSequenceGenerator extends SequenceGenerator { | |||
public static final String SEQUENCE_NAME_SEPARATOR = "_"; | |||
public static final String SEQUENCE_NAME_SUFFIX = "seq"; | |||
@Override | |||
public void configure(Type type, Properties params, Dialect dialect) { | |||
String tableName = params.getProperty(PersistentIdentifierGenerator.TABLE); | |||
String columnName = params.getProperty(PersistentIdentifierGenerator.PK); | |||
if (tableName != null && columnName != null) { | |||
StringBuilder sequenceNameBuilder = new StringBuilder(); | |||
sequenceNameBuilder.append(tableName); | |||
sequenceNameBuilder.append(SEQUENCE_NAME_SEPARATOR); | |||
sequenceNameBuilder.append(columnName); | |||
sequenceNameBuilder.append(SEQUENCE_NAME_SEPARATOR); | |||
sequenceNameBuilder.append(SEQUENCE_NAME_SUFFIX); | |||
params.setProperty(SEQUENCE, sequenceNameBuilder.toString()); | |||
} | |||
super.configure(type, params, dialect); | |||
} | |||
} |
@@ -20,11 +20,8 @@ | |||
package org.sonar.core.persistence.dialect; | |||
import com.google.common.collect.ImmutableList; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.hibernate.dialect.PostgreSQLDialect; | |||
import java.sql.Types; | |||
import java.util.List; | |||
import org.apache.commons.lang.StringUtils; | |||
/** | |||
* @since 1.12 | |||
@@ -38,11 +35,6 @@ public class PostgreSql extends AbstractDialect { | |||
super(ID, "postgre", "org.postgresql.Driver", "true", "false", "SELECT 1"); | |||
} | |||
@Override | |||
public Class<? extends org.hibernate.dialect.Dialect> getHibernateDialectClass() { | |||
return PostgreSQLWithDecimalDialect.class; | |||
} | |||
@Override | |||
public boolean matchesJdbcURL(String jdbcConnectionURL) { | |||
return StringUtils.startsWithIgnoreCase(jdbcConnectionURL, "jdbc:postgresql:"); | |||
@@ -57,17 +49,4 @@ public class PostgreSql extends AbstractDialect { | |||
public boolean supportsMigration() { | |||
return true; | |||
} | |||
public static class PostgreSQLWithDecimalDialect extends PostgreSQLDialect { | |||
public PostgreSQLWithDecimalDialect() { | |||
super(); | |||
registerColumnType(Types.DOUBLE, "numeric($p,$s)"); | |||
} | |||
@Override | |||
public Class getNativeIdentifierGeneratorClass() { | |||
return PostgreSQLSequenceGenerator.class; | |||
} | |||
} | |||
} |
@@ -21,6 +21,8 @@ | |||
package org.sonar.core.qualityprofile.db; | |||
import com.google.common.base.Preconditions; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.apache.commons.lang.builder.ReflectionToStringBuilder; | |||
import org.apache.commons.lang.builder.ToStringStyle; | |||
@@ -30,10 +32,6 @@ import org.sonar.core.persistence.Dto; | |||
import org.sonar.core.rule.RuleDto; | |||
import org.sonar.core.rule.SeverityUtil; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import javax.persistence.Transient; | |||
public class ActiveRuleDto extends Dto<ActiveRuleKey> { | |||
public static final String INHERITED = ActiveRule.INHERITED; | |||
@@ -66,7 +64,6 @@ public class ActiveRuleDto extends Dto<ActiveRuleKey> { | |||
} | |||
// This field do not exists in db, it's only retrieve by joins | |||
@Transient | |||
private Integer parentId; | |||
public Integer getId() { |
@@ -27,8 +27,6 @@ import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.batch.RequiresDB; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.i18n.I18n; | |||
@@ -36,8 +34,6 @@ import org.sonar.api.server.ServerSide; | |||
import static org.sonar.api.utils.DateUtils.longToDate; | |||
@RequiresDB | |||
@BatchSide | |||
@ServerSide | |||
public class Periods { | |||
@@ -1,80 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.jpa.session; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
import javax.persistence.EntityManager; | |||
import javax.persistence.EntityManagerFactory; | |||
import javax.persistence.Persistence; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.core.persistence.Database; | |||
import org.sonar.core.persistence.dialect.Dialect; | |||
public abstract class AbstractDatabaseConnector implements DatabaseConnector { | |||
protected static final Logger LOG = LoggerFactory.getLogger(AbstractDatabaseConnector.class); | |||
protected Database database; | |||
private EntityManagerFactory factory = null; | |||
protected AbstractDatabaseConnector(Database database) { | |||
this.database = database; | |||
} | |||
public void start() { | |||
LOG.info("Initializing Hibernate"); | |||
factory = createEntityManagerFactory(); | |||
} | |||
public void stop() { | |||
if (factory != null && factory.isOpen()) { | |||
factory.close(); | |||
factory = null; | |||
} | |||
database = null; | |||
} | |||
protected EntityManagerFactory createEntityManagerFactory() { | |||
// other settings are stored into /META-INF/persistence.xml | |||
Properties props = database.getHibernateProperties(); | |||
logHibernateSettings(props); | |||
return Persistence.createEntityManagerFactory("sonar", props); | |||
} | |||
private void logHibernateSettings(Properties props) { | |||
if (LOG.isDebugEnabled()) { | |||
for (Map.Entry<Object, Object> entry : props.entrySet()) { | |||
LOG.debug(entry.getKey() + ": " + entry.getValue()); | |||
} | |||
} | |||
} | |||
@Override | |||
public EntityManager createEntityManager() { | |||
return factory.createEntityManager(); | |||
} | |||
@Override | |||
public final Dialect getDialect() { | |||
return database.getDialect(); | |||
} | |||
} |
@@ -1,40 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.jpa.session; | |||
import org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider; | |||
import javax.sql.DataSource; | |||
import java.util.Properties; | |||
public class CustomHibernateConnectionProvider extends InjectedDataSourceConnectionProvider { | |||
private static DataSource datasourceForConfig; | |||
static void setDatasourceForConfig(DataSource ds) { | |||
CustomHibernateConnectionProvider.datasourceForConfig = ds; | |||
} | |||
@Override | |||
public void configure(Properties props) { | |||
setDataSource(datasourceForConfig); | |||
super.configure(props); | |||
} | |||
} |
@@ -1,35 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.jpa.session; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import javax.persistence.EntityManager; | |||
import org.sonar.core.persistence.dialect.Dialect; | |||
public interface DatabaseConnector { | |||
Dialect getDialect(); | |||
Connection getConnection() throws SQLException; | |||
EntityManager createEntityManager(); | |||
} |
@@ -1,33 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.jpa.session; | |||
import org.sonar.api.database.DatabaseSession; | |||
/** | |||
* @deprecated replaced by mybatis | |||
*/ | |||
@Deprecated | |||
public interface DatabaseSessionFactory { | |||
DatabaseSession getSession(); | |||
void clear(); | |||
} |
@@ -1,52 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.jpa.session; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.core.persistence.Database; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
public class DefaultDatabaseConnector extends AbstractDatabaseConnector { | |||
public DefaultDatabaseConnector(Database database) { | |||
super(database); | |||
} | |||
@Override | |||
public void start() { | |||
createDatasource(); | |||
super.start(); | |||
} | |||
private void createDatasource() { | |||
try { | |||
CustomHibernateConnectionProvider.setDatasourceForConfig(database.getDataSource()); | |||
} catch (Exception e) { | |||
throw new SonarException("Fail to connect to database", e); | |||
} | |||
} | |||
@Override | |||
public Connection getConnection() throws SQLException { | |||
return database != null && database.getDataSource() != null ? database.getDataSource().getConnection() : null; | |||
} | |||
} |
@@ -1,301 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.jpa.session; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.collect.Maps; | |||
import java.util.HashSet; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import javax.persistence.EntityManager; | |||
import javax.persistence.NonUniqueResultException; | |||
import javax.persistence.PersistenceException; | |||
import javax.persistence.Query; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.database.DatabaseSession; | |||
public class JpaDatabaseSession extends DatabaseSession { | |||
private final DatabaseConnector connector; | |||
private EntityManager entityManager = null; | |||
private int index = 0; | |||
private boolean inTransaction = false; | |||
public JpaDatabaseSession(DatabaseConnector connector) { | |||
this.connector = connector; | |||
} | |||
/** | |||
* Note that usage of this method is discouraged, because it allows to construct and execute queries without additional exception handling, | |||
* which done in methods of this class. | |||
*/ | |||
@Override | |||
public EntityManager getEntityManager() { | |||
if (entityManager == null) { | |||
entityManager = connector.createEntityManager(); | |||
} | |||
return entityManager; | |||
} | |||
@Override | |||
public void start() { | |||
getEntityManager(); | |||
index = 0; | |||
} | |||
@Override | |||
public void stop() { | |||
commitAndClose(); | |||
} | |||
@Override | |||
public void commitAndClose() { | |||
commit(); | |||
if (entityManager != null && entityManager.isOpen()) { | |||
entityManager.close(); | |||
entityManager = null; | |||
} | |||
} | |||
@Override | |||
public void commit() { | |||
if (inTransaction) { | |||
if (getEntityManager().isOpen()) { | |||
if (getEntityManager().getTransaction().getRollbackOnly()) { | |||
getEntityManager().getTransaction().rollback(); | |||
} else { | |||
getEntityManager().getTransaction().commit(); | |||
} | |||
getEntityManager().clear(); | |||
index = 0; | |||
} | |||
inTransaction = false; | |||
} | |||
} | |||
@Override | |||
public void rollback() { | |||
if (inTransaction) { | |||
getEntityManager().getTransaction().rollback(); | |||
inTransaction = false; | |||
} | |||
} | |||
@Override | |||
public <T> T save(T model) { | |||
startTransaction(); | |||
internalSave(model, true); | |||
return model; | |||
} | |||
@Override | |||
public Object saveWithoutFlush(Object model) { | |||
startTransaction(); | |||
internalSave(model, false); | |||
return model; | |||
} | |||
@Override | |||
public boolean contains(Object model) { | |||
startTransaction(); | |||
return getEntityManager().contains(model); | |||
} | |||
@Override | |||
public void save(Object... models) { | |||
startTransaction(); | |||
for (Object model : models) { | |||
save(model); | |||
} | |||
} | |||
private void internalSave(Object model, boolean flushIfNeeded) { | |||
try { | |||
getEntityManager().persist(model); | |||
} catch (PersistenceException e) { | |||
/* | |||
* See http://jira.sonarsource.com/browse/SONAR-2234 | |||
* In some cases Hibernate can throw exceptions without meaningful information about context, so we improve them here. | |||
*/ | |||
throw new PersistenceException("Unable to persist : " + model, e); | |||
} | |||
if (flushIfNeeded && (++index % BATCH_SIZE == 0)) { | |||
commit(); | |||
} | |||
} | |||
@Override | |||
public Object merge(Object model) { | |||
startTransaction(); | |||
return getEntityManager().merge(model); | |||
} | |||
@Override | |||
public void remove(Object model) { | |||
startTransaction(); | |||
getEntityManager().remove(model); | |||
if (++index % BATCH_SIZE == 0) { | |||
commit(); | |||
} | |||
} | |||
@Override | |||
public void removeWithoutFlush(Object model) { | |||
startTransaction(); | |||
getEntityManager().remove(model); | |||
} | |||
@Override | |||
public <T> T reattach(Class<T> entityClass, Object primaryKey) { | |||
startTransaction(); | |||
return getEntityManager().getReference(entityClass, primaryKey); | |||
} | |||
private void startTransaction() { | |||
if (!inTransaction) { | |||
getEntityManager().getTransaction().begin(); | |||
inTransaction = true; | |||
} | |||
} | |||
/** | |||
* Note that not recommended to directly execute {@link Query#getSingleResult()}, because it will bypass exception handling, | |||
* which done in {@link #getSingleResult(Query, Object)}. | |||
*/ | |||
@Override | |||
public Query createQuery(String hql) { | |||
startTransaction(); | |||
return getEntityManager().createQuery(hql); | |||
} | |||
@Override | |||
public Query createNativeQuery(String sql) { | |||
startTransaction(); | |||
return getEntityManager().createNativeQuery(sql); | |||
} | |||
/** | |||
* @return the result or <code>defaultValue</code>, if not found | |||
* @throws NonUniqueResultException if more than one result | |||
*/ | |||
@Override | |||
public <T> T getSingleResult(Query query, T defaultValue) { | |||
/* | |||
* See http://jira.sonarsource.com/browse/SONAR-2225 | |||
* By default Hibernate throws NonUniqueResultException without meaningful information about context, | |||
* so we improve it here by adding all results in error message. | |||
* Note that in some rare situations we can receive too many results, which may lead to OOME, | |||
* but actually it will mean that database is corrupted as we don't expect more than one result | |||
* and in fact org.hibernate.ejb.QueryImpl#getSingleResult() anyway does loading of several results under the hood. | |||
*/ | |||
List<T> result = query.getResultList(); | |||
if (result.size() == 1) { | |||
return result.get(0); | |||
} else if (result.isEmpty()) { | |||
return defaultValue; | |||
} else { | |||
Set<T> uniqueResult = new HashSet<>(result); | |||
if (uniqueResult.size() > 1) { | |||
throw new NonUniqueResultException("Expected single result, but got : " + result.toString()); | |||
} else { | |||
return uniqueResult.iterator().next(); | |||
} | |||
} | |||
} | |||
@Override | |||
public <T> T getEntity(Class<T> entityClass, Object id) { | |||
startTransaction(); | |||
return getEntityManager().find(entityClass, id); | |||
} | |||
/** | |||
* @return the result or <code>null</code>, if not found | |||
* @throws NonUniqueResultException if more than one result | |||
*/ | |||
@Override | |||
public <T> T getSingleResult(Class<T> entityClass, Object... criterias) { | |||
try { | |||
return getSingleResult(getQueryForCriterias(entityClass, true, criterias), (T) null); | |||
} catch (NonUniqueResultException ex) { | |||
NonUniqueResultException e = new NonUniqueResultException("Expected single result for entitiy " + entityClass.getSimpleName() | |||
+ " with criterias : " + StringUtils.join(criterias, ",")); | |||
throw (NonUniqueResultException) e.initCause(ex); | |||
} | |||
} | |||
@Override | |||
public <T> List<T> getResults(Class<T> entityClass, Object... criterias) { | |||
return getQueryForCriterias(entityClass, true, criterias).getResultList(); | |||
} | |||
@Override | |||
public <T> List<T> getResults(Class<T> entityClass) { | |||
return getQueryForCriterias(entityClass, false, (Object[]) null).getResultList(); | |||
} | |||
private Query getQueryForCriterias(Class<?> entityClass, boolean raiseError, Object... criterias) { | |||
if (criterias == null && raiseError) { | |||
throw new IllegalStateException("criterias parameter must be provided"); | |||
} | |||
startTransaction(); | |||
StringBuilder hql = new StringBuilder("SELECT o FROM ").append(entityClass.getSimpleName()).append(" o"); | |||
if (criterias != null) { | |||
hql.append(" WHERE "); | |||
Map<String, Object> mappedCriterias = Maps.newHashMap(); | |||
for (int i = 0; i < criterias.length; i += 2) { | |||
mappedCriterias.put((String) criterias[i], criterias[i + 1]); | |||
} | |||
buildCriteriasHQL(hql, mappedCriterias); | |||
Query query = getEntityManager().createQuery(hql.toString()); | |||
for (Map.Entry<String, Object> entry : mappedCriterias.entrySet()) { | |||
if (entry.getValue() != null) { | |||
query.setParameter(entry.getKey(), entry.getValue()); | |||
} | |||
} | |||
return query; | |||
} | |||
return getEntityManager().createQuery(hql.toString()); | |||
} | |||
@VisibleForTesting | |||
void buildCriteriasHQL(StringBuilder hql, Map<String, Object> mappedCriterias) { | |||
for (Iterator<Map.Entry<String, Object>> i = mappedCriterias.entrySet().iterator(); i.hasNext();) { | |||
Map.Entry<String, Object> entry = i.next(); | |||
hql.append("o.").append(entry.getKey()); | |||
if (entry.getValue() == null) { | |||
hql.append(" IS NULL"); | |||
} else { | |||
hql.append("=:").append(entry.getKey()); | |||
} | |||
if (i.hasNext()) { | |||
hql.append(" AND "); | |||
} | |||
} | |||
} | |||
} |
@@ -1,28 +0,0 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<persistence xmlns="http://java.sun.com/xml/ns/persistence" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" | |||
version="1.0"> | |||
<persistence-unit name="sonar" transaction-type="RESOURCE_LOCAL"> | |||
<provider>org.hibernate.ejb.HibernatePersistence</provider> | |||
<class>org.sonar.api.database.model.Snapshot</class> | |||
<class>org.sonar.api.measures.Metric</class> | |||
<class>org.sonar.api.database.model.ResourceModel</class> | |||
<exclude-unlisted-classes>true</exclude-unlisted-classes> | |||
<properties> | |||
<property name="hibernate.current_session_context_class" value="thread"/> | |||
<property name="hibernate.connection.release_mode" value="after_transaction"/> | |||
<property name="hibernate.bytecode.use_reflection_optimizer" value="true"/> | |||
<property name="hibernate.query.factory_class" value="org.hibernate.hql.ast.ASTQueryTranslatorFactory"/> | |||
<property name="hibernate.jdbc.batch_size" value="30"/> | |||
<property name="hibernate.connection.useUnicode" value="true"/> | |||
<property name="hibernate.connection.charSet" value="UTF-8"/> | |||
<property name="hibernate.connection.characterEncoding" value="UTF-8"/> | |||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/> | |||
<property name="hibernate.cache.use_second_level_cache" value="false"/> | |||
<property name="hibernate.cache.use_query_cache" value="false"/> | |||
</properties> | |||
</persistence-unit> | |||
</persistence> |
@@ -125,16 +125,4 @@ public class DefaultDatabaseTest { | |||
assertThat(database.getProperties().getProperty("sonar.jdbc.driverClassName")).isEqualTo("org.postgresql.Driver"); | |||
} | |||
@Test | |||
public void shouldSetHibernateProperties() { | |||
Settings settings = new Settings(); | |||
settings.setProperty("sonar.jdbc.url", "jdbc:postgresql://localhost/sonar"); | |||
DefaultDatabase database = new DefaultDatabase(settings); | |||
database.initSettings(); | |||
Properties hibernateProps = database.getHibernateProperties(); | |||
assertThat(hibernateProps.getProperty("hibernate.generate_statistics")).isEqualTo("false"); | |||
} | |||
} |
@@ -19,18 +19,13 @@ | |||
*/ | |||
package org.sonar.core.persistence; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import javax.sql.DataSource; | |||
import org.apache.commons.dbcp.BasicDataSource; | |||
import org.apache.commons.dbutils.DbUtils; | |||
import org.hibernate.cfg.Environment; | |||
import org.sonar.core.persistence.dialect.Dialect; | |||
import org.sonar.core.persistence.dialect.H2; | |||
import org.sonar.jpa.session.CustomHibernateConnectionProvider; | |||
import javax.sql.DataSource; | |||
import java.sql.Connection; | |||
import java.sql.SQLException; | |||
import java.util.Properties; | |||
/** | |||
* H2 in-memory database, used for unit tests only. | |||
@@ -113,13 +108,6 @@ public class H2Database implements Database { | |||
return new H2(); | |||
} | |||
public Properties getHibernateProperties() { | |||
Properties properties = new Properties(); | |||
properties.put("hibernate.hbm2ddl.auto", "validate"); | |||
properties.put(Environment.CONNECTION_PROVIDER, CustomHibernateConnectionProvider.class.getName()); | |||
return properties; | |||
} | |||
@Override | |||
public String toString() { | |||
return "H2 Database[" + name + "]"; |
@@ -1,49 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.persistence.dialect; | |||
import org.hibernate.id.PersistentIdentifierGenerator; | |||
import org.junit.Test; | |||
import java.util.Properties; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class OracleSequenceGeneratorTest { | |||
@Test | |||
public void sequenceNameShouldFollowRailsConventions() { | |||
Properties props = new Properties(); | |||
props.setProperty(PersistentIdentifierGenerator.TABLE, "my_table"); | |||
props.setProperty(PersistentIdentifierGenerator.PK, "id"); | |||
OracleSequenceGenerator generator = new OracleSequenceGenerator(); | |||
generator.configure(null, props, new Oracle.Oracle10gWithDecimalDialect()); | |||
assertThat(generator.getSequenceName()).isEqualTo("MY_TABLE_SEQ"); | |||
} | |||
@Test | |||
public void should_not_fail_if_table_name_can_not_be_loaded() { | |||
Properties props = new Properties(); | |||
OracleSequenceGenerator generator = new OracleSequenceGenerator(); | |||
generator.configure(null, props, new Oracle.Oracle10gWithDecimalDialect()); | |||
assertThat(generator.getSequenceName()).isNotEmpty(); | |||
} | |||
} |
@@ -1,49 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.persistence.dialect; | |||
import org.hibernate.id.PersistentIdentifierGenerator; | |||
import org.junit.Test; | |||
import java.util.Properties; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class PostgreSQLSequenceGeneratorTest { | |||
@Test | |||
public void sequenceNameShouldFollowRailsConventions() { | |||
Properties props = new Properties(); | |||
props.setProperty(PersistentIdentifierGenerator.TABLE, "my_table"); | |||
props.setProperty(PersistentIdentifierGenerator.PK, "id"); | |||
PostgreSQLSequenceGenerator generator = new PostgreSQLSequenceGenerator(); | |||
generator.configure(null, props, new PostgreSql.PostgreSQLWithDecimalDialect()); | |||
assertThat(generator.getSequenceName()).isEqualTo("my_table_id_seq"); | |||
} | |||
@Test | |||
public void should_not_fail_if_table_name_can_not_be_loaded() { | |||
Properties props = new Properties(); | |||
PostgreSQLSequenceGenerator generator = new PostgreSQLSequenceGenerator(); | |||
generator.configure(null, props, new PostgreSql.PostgreSQLWithDecimalDialect()); | |||
assertThat(generator.getSequenceName()).isNotEmpty(); | |||
} | |||
} |
@@ -1,90 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.jpa.session; | |||
import java.util.List; | |||
import javax.persistence.NonUniqueResultException; | |||
import org.hamcrest.Matchers; | |||
import org.hamcrest.core.IsCollectionContaining; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.api.database.model.ResourceModel; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertNull; | |||
import static org.junit.Assert.assertThat; | |||
import static org.junit.Assert.assertTrue; | |||
public class DatabaseSessionTest extends AbstractDbUnitTestCase { | |||
private ResourceModel project1; | |||
private ResourceModel project2; | |||
@Before | |||
public void setup() { | |||
project1 = new ResourceModel(ResourceModel.SCOPE_PROJECT, "mygroup:myartifact", "JAV", null, "my name"); | |||
project2 = new ResourceModel(ResourceModel.SCOPE_PROJECT, "mygroup:myartifact1", "JAV", null, "my name 2"); | |||
} | |||
@Test | |||
public void testGetSingleResultWithNoResults() { | |||
assertNull(getSession().getSingleResult(ResourceModel.class, "name", "test")); | |||
} | |||
@Test(expected = IllegalStateException.class) | |||
public void testGetSingleResultWithNoCriterias() { | |||
assertNull(getSession().getSingleResult(ResourceModel.class, (Object[]) null)); | |||
} | |||
@Test | |||
public void testGetSingleResultWithOneResult() { | |||
getSession().save(project1); | |||
ResourceModel hit = getSession().getSingleResult(ResourceModel.class, "name", "my name"); | |||
assertNotNull(hit); | |||
assertEquals(project1, hit); | |||
} | |||
@Test(expected = NonUniqueResultException.class) | |||
public void testGetSingleResultWithTwoResults() { | |||
getSession().save(project1, project2); | |||
getSession().getSingleResult(ResourceModel.class, "qualifier", "JAV"); | |||
} | |||
@Test | |||
public void testGetResultsWithNoResults() { | |||
List<ResourceModel> hits = getSession().getResults(ResourceModel.class, "name", "foo"); | |||
assertTrue(hits.isEmpty()); | |||
} | |||
@Test | |||
public void testGetResultsWithMultipleResults() { | |||
ResourceModel project3 = new ResourceModel(ResourceModel.SCOPE_PROJECT, "mygroup:myartifact3", "BRC", null, "my name 3"); | |||
getSession().save(project1, project2, project3); | |||
List<ResourceModel> hits = getSession().getResults(ResourceModel.class, "qualifier", "JAV"); | |||
assertFalse(hits.isEmpty()); | |||
assertThat(hits, IsCollectionContaining.hasItems(project1, project2)); | |||
assertThat(hits, Matchers.not(IsCollectionContaining.hasItem(project3))); | |||
} | |||
} |
@@ -1,79 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.jpa.session; | |||
import com.google.common.collect.Maps; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import javax.persistence.NonUniqueResultException; | |||
import javax.persistence.Query; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.Map; | |||
import static org.hamcrest.Matchers.is; | |||
import static org.junit.Assert.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class JpaDatabaseSessionTest { | |||
private JpaDatabaseSession session; | |||
@Before | |||
public void setUp() { | |||
session = new JpaDatabaseSession(null); | |||
} | |||
@Test(expected = NonUniqueResultException.class) | |||
public void shouldThrowNonUniqueResultException() { | |||
Query query = mock(Query.class); | |||
when(query.getResultList()).thenReturn(Arrays.asList("foo", "bar")); | |||
session.getSingleResult(query, null); | |||
} | |||
@Test | |||
public void shouldReturnSingleResult() { | |||
Query query = mock(Query.class); | |||
when(query.getResultList()).thenReturn(Arrays.asList("foo", "foo"), Arrays.asList("bar")); | |||
assertThat(session.getSingleResult(query, "default"), is("foo")); | |||
assertThat(session.getSingleResult(query, "default"), is("bar")); | |||
} | |||
@Test | |||
public void shouldReturnDefaultValue() { | |||
Query query = mock(Query.class); | |||
when(query.getResultList()).thenReturn(Collections.emptyList()); | |||
assertThat(session.getSingleResult(query, "default"), is("default")); | |||
} | |||
@Test | |||
public void shouldBuildCriteriasHQL() { | |||
StringBuilder hql = new StringBuilder(); | |||
Map<String, Object> mappedCriterias = Maps.newLinkedHashMap(); | |||
mappedCriterias.put("foo", "value"); | |||
mappedCriterias.put("bar", null); | |||
session.buildCriteriasHQL(hql, mappedCriterias); | |||
assertThat(hql.toString(), is("o.foo=:foo AND o.bar IS NULL")); | |||
} | |||
} |
@@ -37,10 +37,8 @@ import org.dbunit.dataset.filter.DefaultColumnFilter; | |||
import org.dbunit.dataset.xml.FlatXmlDataSet; | |||
import org.dbunit.ext.mssql.InsertIdentityOperation; | |||
import org.dbunit.operation.DatabaseOperation; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.BeforeClass; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.core.cluster.NullQueue; | |||
import org.sonar.core.config.Logback; | |||
import org.sonar.core.persistence.Database; | |||
@@ -49,14 +47,10 @@ import org.sonar.core.persistence.DatabaseVersion; | |||
import org.sonar.core.persistence.H2Database; | |||
import org.sonar.core.persistence.MyBatis; | |||
import org.sonar.core.persistence.SchemaMigrationMapper; | |||
import org.sonar.jpa.session.DatabaseSessionFactory; | |||
import org.sonar.jpa.session.DefaultDatabaseConnector; | |||
import org.sonar.jpa.session.JpaDatabaseSession; | |||
import static org.junit.Assert.fail; | |||
/** | |||
* Heavily duplicates AbstractDaoTestCase as long as Hibernate is in use. | |||
* @deprecated this class does not support non-H2 databases | |||
*/ | |||
@Deprecated | |||
@@ -64,9 +58,7 @@ public abstract class AbstractDbUnitTestCase { | |||
private static Database database; | |||
private static MyBatis myBatis; | |||
private static DatabaseCommands databaseCommands; | |||
private static DefaultDatabaseConnector dbConnector; | |||
private IDatabaseTester databaseTester; | |||
private JpaDatabaseSession session; | |||
@BeforeClass | |||
public static void startDatabase() throws SQLException { | |||
@@ -82,9 +74,6 @@ public abstract class AbstractDbUnitTestCase { | |||
session.getMapper(SchemaMigrationMapper.class).insert(String.valueOf(DatabaseVersion.LAST_VERSION)); | |||
session.commit(); | |||
} | |||
dbConnector = new DefaultDatabaseConnector(database); | |||
dbConnector.start(); | |||
} | |||
} | |||
@@ -92,19 +81,6 @@ public abstract class AbstractDbUnitTestCase { | |||
public void startDbUnit() throws Exception { | |||
databaseCommands.truncateDatabase(database.getDataSource()); | |||
databaseTester = new DataSourceDatabaseTester(database.getDataSource()); | |||
session = new JpaDatabaseSession(dbConnector); | |||
session.start(); | |||
} | |||
@After | |||
public void stopDbUnit() throws Exception { | |||
if (session != null) { | |||
session.rollback(); | |||
} | |||
} | |||
protected DatabaseSession getSession() { | |||
return session; | |||
} | |||
protected MyBatis getMyBatis() { | |||
@@ -115,17 +91,6 @@ public abstract class AbstractDbUnitTestCase { | |||
return database; | |||
} | |||
protected DatabaseSessionFactory getSessionFactory() { | |||
return new DatabaseSessionFactory() { | |||
public DatabaseSession getSession() { | |||
return session; | |||
} | |||
public void clear() { | |||
} | |||
}; | |||
} | |||
protected void setupData(String... testNames) { | |||
InputStream[] streams = new InputStream[testNames.length]; | |||
try { | |||
@@ -262,9 +227,4 @@ public abstract class AbstractDbUnitTestCase { | |||
runtimeException.setStackTrace(cause.getStackTrace()); | |||
return runtimeException; | |||
} | |||
protected Long getHQLCount(Class<?> hqlClass) { | |||
String hqlCount = "SELECT count(o) from " + hqlClass.getSimpleName() + " o"; | |||
return (Long) getSession().createQuery(hqlCount).getSingleResult(); | |||
} | |||
} |
@@ -11,10 +11,6 @@ | |||
</encoder> | |||
</appender> | |||
<logger name="org.hibernate"> | |||
<level value="WARN"/> | |||
</logger> | |||
<logger name="org.dbunit"> | |||
<level value="WARN"/> | |||
</logger> | |||
@@ -39,4 +35,4 @@ | |||
<appender-ref ref="STDOUT"/> | |||
</root> | |||
</configuration> | |||
</configuration> |
@@ -124,28 +124,6 @@ | |||
<artifactId>jsr305</artifactId> | |||
<scope>provided</scope> | |||
</dependency> | |||
<!-- TODO we can't remove hibernate-annotations, because currently it's used | |||
moreover it contains transitive dependency on dom4j, which is used in some plugins | |||
--> | |||
<dependency> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-annotations</artifactId> | |||
<scope>provided</scope> | |||
<exclusions> | |||
<exclusion> | |||
<groupId>org.hibernate</groupId> | |||
<artifactId>hibernate-core</artifactId> | |||
</exclusion> | |||
<exclusion> | |||
<groupId>org.slf4j</groupId> | |||
<artifactId>slf4j-api</artifactId> | |||
</exclusion> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.slf4j</groupId> | |||
<artifactId>slf4j-api</artifactId> |
@@ -1,37 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.api.batch; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
/** | |||
* The presence of this annotation on an extension class indicates that the extension | |||
* requires database access. As a result such extension will be disabled in preview mode. | |||
* | |||
* | |||
* @since 5.1 | |||
*/ | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@Target(ElementType.TYPE) | |||
public @interface RequiresDB { | |||
} |
@@ -19,17 +19,8 @@ | |||
*/ | |||
package org.sonar.api.database; | |||
import javax.persistence.Column; | |||
import javax.persistence.GeneratedValue; | |||
import javax.persistence.Id; | |||
import javax.persistence.MappedSuperclass; | |||
@MappedSuperclass | |||
public class BaseIdentifiable<G> { | |||
@Id | |||
@Column(name = "id") | |||
@GeneratedValue | |||
private Integer id; | |||
public Integer getId() { |
@@ -1,87 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.api.database; | |||
import org.sonar.api.batch.BatchSide; | |||
import javax.persistence.EntityManager; | |||
import javax.persistence.Query; | |||
import java.util.List; | |||
/** | |||
* This component should not be accessed by plugins. Database is not an API. | |||
* | |||
* @since 1.10 | |||
*/ | |||
@BatchSide | |||
public abstract class DatabaseSession { | |||
// IMPORTANT : this value must be the same than the property | |||
// hibernate.jdbc.batch_size from /META-INF/persistence.xml (module sonar-database) | |||
public static final int BATCH_SIZE = 30; | |||
public abstract EntityManager getEntityManager(); | |||
public abstract void start(); | |||
public abstract void stop(); | |||
public abstract void commit(); | |||
/** | |||
* This method should be called before a long period were database will not be accessed | |||
* in order to close database connection and avoid timeout. Next use of the | |||
* database will automatically open a new connection. | |||
*/ | |||
public abstract void commitAndClose(); | |||
public abstract void rollback(); | |||
public abstract <T> T save(T entity); | |||
public abstract Object saveWithoutFlush(Object entity); | |||
public abstract boolean contains(Object entity); | |||
public abstract void save(Object... entities); | |||
public abstract Object merge(Object entity); | |||
public abstract void remove(Object entity); | |||
public abstract void removeWithoutFlush(Object entity); | |||
public abstract <T> T reattach(Class<T> entityClass, Object primaryKey); | |||
public abstract Query createQuery(String hql); | |||
public abstract Query createNativeQuery(String sql); | |||
public abstract <T> T getSingleResult(Query query, T defaultValue); | |||
public abstract <T> T getEntity(Class<T> entityClass, Object id); | |||
public abstract <T> T getSingleResult(Class<T> entityClass, Object... criterias); | |||
public abstract <T> List<T> getResults(Class<T> entityClass, Object... criterias); | |||
public abstract <T> List<T> getResults(Class<T> entityClass); | |||
} |
@@ -22,22 +22,12 @@ package org.sonar.api.database.model; | |||
import java.io.Serializable; | |||
import java.util.Date; | |||
import javax.annotation.Nullable; | |||
import javax.persistence.Column; | |||
import javax.persistence.Entity; | |||
import javax.persistence.Table; | |||
import javax.persistence.Temporal; | |||
import javax.persistence.TemporalType; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.apache.commons.lang.builder.EqualsBuilder; | |||
import org.apache.commons.lang.builder.HashCodeBuilder; | |||
import org.apache.commons.lang.builder.ToStringBuilder; | |||
import org.sonar.api.database.BaseIdentifiable; | |||
/** | |||
* Class to map resource with hibernate model | |||
*/ | |||
@Entity | |||
@Table(name = "projects") | |||
public class ResourceModel extends BaseIdentifiable implements Cloneable, Serializable { | |||
public static final String SCOPE_PROJECT = "PRJ"; | |||
@@ -48,59 +38,23 @@ public class ResourceModel extends BaseIdentifiable implements Cloneable, Serial | |||
public static final int KEY_SIZE = 400; | |||
public static final int PATH_SIZE = 2000; | |||
@Column(name = "name", updatable = true, nullable = true, length = NAME_COLUMN_SIZE) | |||
private String name; | |||
@Column(name = "long_name", updatable = true, nullable = true, length = NAME_COLUMN_SIZE) | |||
private String longName; | |||
@Column(name = "description", updatable = true, nullable = true, length = DESCRIPTION_COLUMN_SIZE) | |||
private String description; | |||
@Column(name = "enabled", updatable = true, nullable = false) | |||
private Boolean enabled = Boolean.TRUE; | |||
@Column(name = "scope", updatable = true, nullable = false, length = 3) | |||
private String scope; | |||
@Column(name = "qualifier", updatable = true, nullable = false, length = 10) | |||
private String qualifier; | |||
@Column(name = "kee", updatable = true, nullable = false, length = KEY_SIZE) | |||
private String key; | |||
@Column(name = "deprecated_kee", updatable = true, nullable = true, length = KEY_SIZE) | |||
private String deprecatedKey; | |||
@Column(name = "language", updatable = true, nullable = true, length = 20) | |||
private String languageKey; | |||
@Column(name = "root_id", updatable = true, nullable = true) | |||
private Integer rootId; | |||
@Column(name = "path", updatable = true, nullable = true, length = PATH_SIZE) | |||
private String path; | |||
@Column(name = "copy_resource_id", updatable = true, nullable = true) | |||
private Integer copyResourceId; | |||
@Column(name = "person_id", updatable = true, nullable = true) | |||
private Integer personId; | |||
@Temporal(TemporalType.TIMESTAMP) | |||
@Column(name = "created_at", updatable = true, nullable = true) | |||
private Date createdAt; | |||
@Column(name = "uuid", updatable = false, nullable = true, length = 50) | |||
private String uuid; | |||
@Column(name = "project_uuid", updatable = true, nullable = true, length = 50) | |||
private String projectUuid; | |||
@Column(name = "module_uuid", updatable = true, nullable = true, length = 50) | |||
private String moduleUuid; | |||
@Column(name = "module_uuid_path", updatable = true, nullable = true, length = 4000) | |||
private String moduleUuidPath; | |||
/** |
@@ -21,9 +21,6 @@ package org.sonar.api.database.model; | |||
import java.io.Serializable; | |||
import java.util.Date; | |||
import javax.persistence.Column; | |||
import javax.persistence.Entity; | |||
import javax.persistence.Table; | |||
import org.apache.commons.lang.builder.EqualsBuilder; | |||
import org.apache.commons.lang.builder.HashCodeBuilder; | |||
import org.apache.commons.lang.builder.ReflectionToStringBuilder; | |||
@@ -33,11 +30,6 @@ import org.sonar.api.database.BaseIdentifiable; | |||
import static org.sonar.api.utils.DateUtils.dateToLong; | |||
import static org.sonar.api.utils.DateUtils.longToDate; | |||
/** | |||
* A class to map a snapshot with its hibernate model | |||
*/ | |||
@Entity | |||
@Table(name = "snapshots") | |||
public class Snapshot extends BaseIdentifiable<Snapshot> implements Serializable { | |||
/** | |||
@@ -50,91 +42,34 @@ public class Snapshot extends BaseIdentifiable<Snapshot> implements Serializable | |||
*/ | |||
public static final String STATUS_PROCESSED = "P"; | |||
@Column(name = "project_id", updatable = true, nullable = true) | |||
private Integer resourceId; | |||
@Column(name = "build_date", updatable = true, nullable = true) | |||
private Long buildDate; | |||
@Column(name = "created_at", updatable = true, nullable = true) | |||
private Long createdAt; | |||
@Column(name = "version", updatable = true, nullable = true, length = 500) | |||
private String version; | |||
@Column(name = "islast") | |||
private Boolean last = Boolean.FALSE; | |||
@Column(name = "status") | |||
private String status = STATUS_UNPROCESSED; | |||
@Column(name = "purge_status", updatable = true, nullable = true) | |||
private Integer purgeStatus; | |||
@Column(name = "scope", updatable = true, nullable = true, length = 3) | |||
private String scope; | |||
@Column(name = "path", updatable = true, nullable = true, length = 500) | |||
private String path; | |||
@Column(name = "depth", updatable = true, nullable = true) | |||
private Integer depth; | |||
@Column(name = "qualifier", updatable = true, nullable = true, length = 10) | |||
private String qualifier; | |||
@Column(name = "root_snapshot_id", updatable = true, nullable = true) | |||
private Integer rootId; | |||
@Column(name = "parent_snapshot_id", updatable = true, nullable = true) | |||
private Integer parentId; | |||
@Column(name = "root_project_id", updatable = true, nullable = true) | |||
private Integer rootProjectId; | |||
@Column(name = "period1_mode", updatable = true, nullable = true, length = 100) | |||
private String period1Mode; | |||
@Column(name = "period2_mode", updatable = true, nullable = true, length = 100) | |||
private String period2Mode; | |||
@Column(name = "period3_mode", updatable = true, nullable = true, length = 100) | |||
private String period3Mode; | |||
@Column(name = "period4_mode", updatable = true, nullable = true, length = 100) | |||
private String period4Mode; | |||
@Column(name = "period5_mode", updatable = true, nullable = true, length = 100) | |||
private String period5Mode; | |||
@Column(name = "period1_param", updatable = true, nullable = true, length = 100) | |||
private String period1Param; | |||
@Column(name = "period2_param", updatable = true, nullable = true, length = 100) | |||
private String period2Param; | |||
@Column(name = "period3_param", updatable = true, nullable = true, length = 100) | |||
private String period3Param; | |||
@Column(name = "period4_param", updatable = true, nullable = true, length = 100) | |||
private String period4Param; | |||
@Column(name = "period5_param", updatable = true, nullable = true, length = 100) | |||
private String period5Param; | |||
@Column(name = "period1_date", updatable = true, nullable = true) | |||
private Long period1Date; | |||
@Column(name = "period2_date", updatable = true, nullable = true) | |||
private Long period2Date; | |||
@Column(name = "period3_date", updatable = true, nullable = true) | |||
private Long period3Date; | |||
@Column(name = "period4_date", updatable = true, nullable = true) | |||
private Long period4Date; | |||
@Column(name = "period5_date", updatable = true, nullable = true) | |||
private Long period5Date; | |||
public Snapshot() { |
@@ -27,14 +27,6 @@ import java.util.List; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nonnull; | |||
import javax.annotation.Nullable; | |||
import javax.persistence.Column; | |||
import javax.persistence.Entity; | |||
import javax.persistence.EnumType; | |||
import javax.persistence.Enumerated; | |||
import javax.persistence.GeneratedValue; | |||
import javax.persistence.Id; | |||
import javax.persistence.Table; | |||
import javax.persistence.Transient; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.apache.commons.lang.builder.ReflectionToStringBuilder; | |||
import org.apache.commons.lang.builder.ToStringStyle; | |||
@@ -42,13 +34,6 @@ import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
import org.sonar.api.server.ServerSide; | |||
/** | |||
* This class represents the definition of a metric in Sonar. | |||
* | |||
* @since 1.10 | |||
*/ | |||
@Table(name = "metrics") | |||
@Entity(name = "Metric") | |||
@BatchSide | |||
@InstantiationStrategy(InstantiationStrategy.PER_BATCH) | |||
@ServerSide | |||
@@ -125,55 +110,21 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a | |||
} | |||
} | |||
@Id | |||
@Column(name = "id") | |||
@GeneratedValue | |||
private Integer id; | |||
@Transient | |||
private transient Formula formula; | |||
@Column(name = "name", updatable = false, nullable = false, length = 64) | |||
private String key; | |||
@Column(name = "description", updatable = true, nullable = true, length = 255) | |||
private String description; | |||
@Column(name = "val_type", updatable = true, nullable = true) | |||
@Enumerated(EnumType.STRING) | |||
private ValueType type; | |||
@Column(name = "direction", updatable = true, nullable = true) | |||
private Integer direction; | |||
@Column(name = "domain", updatable = true, nullable = true, length = 60) | |||
private String domain; | |||
@Column(name = "short_name", updatable = true, nullable = true, length = 64) | |||
private String name; | |||
@Column(name = "qualitative", updatable = true, nullable = true) | |||
private Boolean qualitative = Boolean.FALSE; | |||
@Column(name = "user_managed", updatable = true, nullable = true) | |||
private Boolean userManaged = Boolean.FALSE; | |||
@Column(name = "enabled", updatable = true, nullable = true) | |||
private Boolean enabled = Boolean.TRUE; | |||
@Column(name = "worst_value", updatable = true, nullable = true, precision = 30, scale = 20) | |||
private Double worstValue; | |||
@Column(name = "best_value", updatable = true, nullable = true, precision = 30, scale = 20) | |||
private Double bestValue; | |||
@Column(name = "optimized_best_value", updatable = true, nullable = true) | |||
private Boolean optimizedBestValue; | |||
@Column(name = "hidden", updatable = true, nullable = true) | |||
private Boolean hidden = Boolean.FALSE; | |||
@Column(name = "delete_historical_data", updatable = true, nullable = true) | |||
private Boolean deleteHistoricalData; | |||
private Metric(Builder builder) { | |||
@@ -195,7 +146,7 @@ public class Metric<G extends Serializable> implements Serializable, org.sonar.a | |||
} | |||
/** | |||
* Creates an empty metric. Required for Hibernate. | |||
* Creates an empty metric | |||
* | |||
* @deprecated in 1.12. Use the {@link Builder} factory. | |||
*/ |