Browse Source

SONAR-4087 first draft of test api

tags/3.5
Simon Brandhof 11 years ago
parent
commit
6200a323e1
46 changed files with 1579 additions and 18 deletions
  1. 10
    0
      pom.xml
  2. 2
    1
      sonar-application/pom.xml
  3. 13
    2
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskModule.java
  4. 15
    6
      sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
  5. 8
    3
      sonar-batch/src/main/java/org/sonar/batch/phases/Phases.java
  6. 2
    1
      sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
  7. 10
    1
      sonar-core/pom.xml
  8. 96
    0
      sonar-core/src/main/java/org/sonar/core/component/ComponentGraph.java
  9. 65
    0
      sonar-core/src/main/java/org/sonar/core/component/ComponentWrapper.java
  10. 47
    0
      sonar-core/src/main/java/org/sonar/core/component/ElementWrapper.java
  11. 95
    0
      sonar-core/src/main/java/org/sonar/core/component/ElementWrappers.java
  12. 43
    0
      sonar-core/src/main/java/org/sonar/core/component/GraphReader.java
  13. 63
    0
      sonar-core/src/main/java/org/sonar/core/component/GraphStorage.java
  14. 40
    0
      sonar-core/src/main/java/org/sonar/core/component/PerspectiveBuilder.java
  15. 86
    0
      sonar-core/src/main/java/org/sonar/core/component/PerspectiveBuilders.java
  16. 63
    0
      sonar-core/src/main/java/org/sonar/core/component/PerspectiveLoaders.java
  17. 26
    0
      sonar-core/src/main/java/org/sonar/core/component/PerspectiveNotFoundException.java
  18. 62
    0
      sonar-core/src/main/java/org/sonar/core/component/ResourceComponent.java
  19. 41
    0
      sonar-core/src/main/java/org/sonar/core/component/TransientGraph.java
  20. 23
    0
      sonar-core/src/main/java/org/sonar/core/component/package-info.java
  21. 53
    0
      sonar-core/src/main/java/org/sonar/core/graph/GraphDao.java
  22. 83
    0
      sonar-core/src/main/java/org/sonar/core/graph/GraphDto.java
  23. 30
    0
      sonar-core/src/main/java/org/sonar/core/graph/GraphDtoMapper.java
  24. 100
    0
      sonar-core/src/main/java/org/sonar/core/graph/GraphUtil.java
  25. 45
    0
      sonar-core/src/main/java/org/sonar/core/graph/GraphWriter.java
  26. 26
    0
      sonar-core/src/main/java/org/sonar/core/graph/MultipleVerticesException.java
  27. 23
    0
      sonar-core/src/main/java/org/sonar/core/graph/package-info.java
  28. 2
    0
      sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java
  29. 1
    0
      sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java
  30. 1
    1
      sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
  31. 4
    1
      sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java
  32. 40
    0
      sonar-core/src/main/resources/org/sonar/core/graph/GraphDtoMapper.xml
  33. 1
    0
      sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
  34. 15
    1
      sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
  35. 47
    0
      sonar-core/src/test/java/org/sonar/core/component/GraphUtilTest.java
  36. 29
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/CoveredTestable.java
  37. 30
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestCase.java
  38. 28
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestPlan.java
  39. 26
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestable.java
  40. 52
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/TestCase.java
  41. 28
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/TestPlan.java
  42. 32
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/Testable.java
  43. 23
    0
      sonar-plugin-api/src/main/java/org/sonar/api/test/package-info.java
  44. 11
    0
      sonar-server/src/main/java/org/sonar/server/platform/Platform.java
  45. 38
    0
      sonar-server/src/main/webapp/WEB-INF/db/migrate/370_create_graphs.rb
  46. 1
    1
      sonar-server/src/main/webapp/WEB-INF/db/migrate/README.txt

+ 10
- 0
pom.xml View File

@@ -640,6 +640,16 @@
<artifactId>asm-all</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>com.tinkerpop.blueprints</groupId>
<artifactId>blueprints-core</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>com.tinkerpop.gremlin</groupId>
<artifactId>gremlin-java</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-classworlds</artifactId>

+ 2
- 1
sonar-application/pom.xml View File

@@ -210,7 +210,8 @@
<configuration>
<rules>
<requireFilesSize>
<maxsize>54000000</maxsize>
<!-- TODO decrease after exclusion of Blueprints -> jackson/jettison -->
<maxsize>55000000</maxsize>
<minsize>52000000</minsize>
<files>
<file>${project.build.directory}/sonar-${project.version}.zip</file>

+ 13
- 2
sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskModule.java View File

@@ -48,6 +48,9 @@ import org.sonar.batch.index.MemoryOptimizer;
import org.sonar.batch.index.SourcePersister;
import org.sonar.batch.tasks.InspectionTask;
import org.sonar.batch.tasks.ListTasksTask;
import org.sonar.core.component.ComponentGraph;
import org.sonar.core.component.GraphStorage;
import org.sonar.core.component.PerspectiveBuilders;
import org.sonar.core.i18n.I18nManager;
import org.sonar.core.i18n.RuleI18nManager;
import org.sonar.core.metric.CacheMetricFinder;
@@ -58,6 +61,8 @@ import org.sonar.core.persistence.MyBatis;
import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.rule.CacheRuleFinder;
import org.sonar.core.test.TestPlanBuilder;
import org.sonar.core.test.TestableBuilder;
import org.sonar.core.user.DefaultUserFinder;
import org.sonar.jpa.dao.MeasuresDao;
import org.sonar.jpa.session.DefaultDatabaseConnector;
@@ -158,6 +163,13 @@ public class TaskModule extends Module {
container.addSingleton(DefaultFileLinesContextFactory.class);
container.addSingleton(ProjectLock.class);
container.addSingleton(DryRunDatabase.class);

// graphs
container.addSingleton(ComponentGraph.class);
container.addSingleton(TestPlanBuilder.class);
container.addSingleton(TestableBuilder.class);
container.addSingleton(PerspectiveBuilders.class);
container.addSingleton(GraphStorage.class);
}

private void logSettings() {
@@ -172,8 +184,7 @@ public class TaskModule extends Module {
Task task = container.getComponentByType(taskDefinition.getTask());
if (task != null) {
task.execute();
}
else {
} else {
throw new SonarException("Extension " + taskDefinition.getTask() + " was not found in declared extensions.");
}
}

+ 15
- 6
sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java View File

@@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.batch.Event;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.database.model.ResourceModel;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
@@ -38,6 +39,7 @@ import org.sonar.api.measures.MetricFinder;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.ProjectLink;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.api.resources.Scopes;
@@ -49,6 +51,7 @@ import org.sonar.batch.DefaultResourceCreationLock;
import org.sonar.batch.ProjectTree;
import org.sonar.batch.ResourceFilters;
import org.sonar.batch.ViolationFilters;
import org.sonar.core.component.ComponentGraph;

import java.util.Collection;
import java.util.Collections;
@@ -67,6 +70,7 @@ public class DefaultIndex extends SonarIndex {
private PersistenceManager persistence;
private DefaultResourceCreationLock lock;
private MetricFinder metricFinder;
private ComponentGraph graph;

// filters
private ViolationFilters violationFilters;
@@ -80,11 +84,12 @@ public class DefaultIndex extends SonarIndex {
private Map<Resource, Map<Resource, Dependency>> incomingDependenciesByResource = Maps.newHashMap();
private ProjectTree projectTree;

public DefaultIndex(PersistenceManager persistence, DefaultResourceCreationLock lock, ProjectTree projectTree, MetricFinder metricFinder) {
public DefaultIndex(PersistenceManager persistence, DefaultResourceCreationLock lock, ProjectTree projectTree, MetricFinder metricFinder, ComponentGraph graph) {
this.persistence = persistence;
this.lock = lock;
this.projectTree = projectTree;
this.metricFinder = metricFinder;
this.graph = graph;
}

public void start() {
@@ -465,10 +470,10 @@ public class DefaultIndex extends SonarIndex {
if (!StringUtils.equals(Scopes.PROJECT, resource.getScope())) {
// not a project nor a library
uid = new StringBuilder(ResourceModel.KEY_SIZE)
.append(project.getKey())
.append(':')
.append(resource.getKey())
.toString();
.append(project.getKey())
.append(':')
.append(resource.getKey())
.toString();
}
return uid;
}
@@ -551,8 +556,12 @@ public class DefaultIndex extends SonarIndex {

boolean excluded = checkExclusion(resource, parentBucket);
if (!excluded) {
persistence.saveResource(currentProject, resource, (parentBucket != null ? parentBucket.getResource() : null));
Snapshot snapshot = persistence.saveResource(currentProject, resource, (parentBucket != null ? parentBucket.getResource() : null));
if (ResourceUtils.isPersistable(resource) && !Qualifiers.LIBRARY.equals(resource.getQualifier())) {
graph.createComponent(resource, snapshot);
}
}

return bucket;
}


+ 8
- 3
sonar-batch/src/main/java/org/sonar/batch/phases/Phases.java View File

@@ -25,6 +25,7 @@ import org.sonar.api.resources.Project;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.index.PersistenceManager;
import org.sonar.core.component.GraphStorage;

import java.util.Collection;

@@ -48,12 +49,14 @@ public final class Phases {
private SensorContext sensorContext;
private DefaultIndex index;
private ProjectInitializer pi;
private GraphStorage graphStorage;

public Phases(DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor,
MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor,
PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index,
EventBus eventBus, UpdateStatusJob updateStatusJob, ProjectInitializer pi) {
EventBus eventBus, UpdateStatusJob updateStatusJob, ProjectInitializer pi,
GraphStorage graphStorage) {
this.decoratorsExecutor = decoratorsExecutor;
this.mavenPhaseExecutor = mavenPhaseExecutor;
this.mavenPluginsConfigurator = mavenPluginsConfigurator;
@@ -66,15 +69,16 @@ public final class Phases {
this.eventBus = eventBus;
this.updateStatusJob = updateStatusJob;
this.pi = pi;
this.graphStorage = graphStorage;
}

public Phases(DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor,
MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor,
PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index,
EventBus eventBus, ProjectInitializer pi) {
EventBus eventBus, ProjectInitializer pi, GraphStorage graphStorage) {
this(decoratorsExecutor, mavenPhaseExecutor, mavenPluginsConfigurator, initializersExecutor, postJobsExecutor,
sensorsExecutor, persistenceManager, sensorContext, index, eventBus, null, pi);
sensorsExecutor, persistenceManager, sensorContext, index, eventBus, null, pi, graphStorage);
}

/**
@@ -94,6 +98,7 @@ public final class Phases {
persistenceManager.setDelayedMode(false);

if (project.isRoot()) {
graphStorage.save();
if (updateStatusJob != null) {
updateStatusJob.execute();
}

+ 2
- 1
sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java View File

@@ -52,6 +52,7 @@ import org.sonar.batch.DefaultResourceCreationLock;
import org.sonar.batch.ProjectTree;
import org.sonar.batch.ResourceFilters;
import org.sonar.batch.ViolationFilters;
import org.sonar.core.component.ComponentGraph;

public class DefaultIndexTest {

@@ -65,7 +66,7 @@ public class DefaultIndexTest {
MetricFinder metricFinder = mock(MetricFinder.class);
when(metricFinder.findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC);

index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder);
index = new DefaultIndex(mock(PersistenceManager.class), lock, mock(ProjectTree.class), metricFinder, mock(ComponentGraph.class));
Project project = new Project("project");

ResourceFilter filter = new ResourceFilter() {

+ 10
- 1
sonar-core/pom.xml View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
@@ -64,6 +65,14 @@
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
</dependency>
<dependency>
<groupId>com.tinkerpop.blueprints</groupId>
<artifactId>blueprints-core</artifactId>
</dependency>
<dependency>
<groupId>com.tinkerpop.gremlin</groupId>
<artifactId>gremlin-java</artifactId>
</dependency>

<!-- logging -->
<dependency>

+ 96
- 0
sonar-core/src/main/java/org/sonar/core/component/ComponentGraph.java View File

@@ -0,0 +1,96 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.KeyIndexableGraph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.blueprints.util.ElementHelper;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.api.component.Component;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Resource;
import org.sonar.core.graph.GraphUtil;

public class ComponentGraph implements BatchComponent, ServerComponent {
private final KeyIndexableGraph graph;
private final ElementWrappers wrapperCache;
private final Vertex rootVertex;

public ComponentGraph() {
graph = new TinkerGraph();
graph.createKeyIndex("key", Vertex.class);
wrapperCache = new ElementWrappers();
rootVertex = graph.addVertex(null);
rootVertex.setProperty("root", "components");
}

public ComponentGraph(KeyIndexableGraph graph, Vertex rootVertex) {
this.graph = graph;
this.rootVertex = rootVertex;
wrapperCache = new ElementWrappers();
}

public <T extends ElementWrapper> T wrap(Element element, Class<T> wrapperClass) {
return wrapperCache.wrap(element, wrapperClass, this);
}

public <T extends ElementWrapper> T wrap(Component component, Class<T> wrapperClass) {
Vertex vertex = GraphUtil.single(graph.getVertices("key", component.getKey()));
T wrapper = wrapperCache.wrap(vertex, wrapperClass, this);
return wrapper;
}

public <T extends ElementWrapper<Vertex>> T createVertex(ElementWrapper<Vertex> from, Class<T> classWrapper, String edgeLabel, String... edgeProperties) {
T to = createVertex(classWrapper);
Edge edge = graph.addEdge(null, from.element(), to.element(), edgeLabel);
ElementHelper.setProperties(edge, edgeProperties);
return to;
}

private <T extends ElementWrapper<Vertex>> T createVertex(Class<T> classWrapper) {
Vertex vertex = graph.addVertex(null);
return wrapperCache.wrap(vertex, classWrapper, this);
}

public <C extends Component<C>> ComponentWrapper<C> createComponent(C component) {
Vertex componentVertex = graph.addVertex(null);
graph.addEdge(null, rootVertex, componentVertex, "component");
ComponentWrapper wrapper = wrapperCache.wrap(componentVertex, ComponentWrapper.class, this);
wrapper.populate(component);
return wrapper;
}

public ComponentWrapper createComponent(Resource resource, Snapshot snapshot) {
return createComponent(new ResourceComponent(resource, snapshot));
}

public Graph getUnderlyingGraph() {
return graph;
}

public Vertex getRootVertex() {
return rootVertex;
}
}

+ 65
- 0
sonar-core/src/main/java/org/sonar/core/component/ComponentWrapper.java View File

@@ -0,0 +1,65 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import com.tinkerpop.blueprints.Vertex;
import org.sonar.api.component.Component;
import org.sonar.core.graph.GraphUtil;

import javax.annotation.Nullable;

public class ComponentWrapper<C extends Component<C>> extends ElementWrapper<Vertex> implements Component<C> {

public String getKey() {
return (String) element().getProperty("key");
}

public String getName() {
return (String) element().getProperty("name");
}

public String getQualifier() {
return (String) element().getProperty("qualifier");
}

public ComponentWrapper setKey(String s) {
element().setProperty("key", s);
return this;
}

public ComponentWrapper setName(@Nullable String s) {
GraphUtil.setNullableProperty(element(), "name", s);
return this;
}

public ComponentWrapper setQualifier(String s) {
element().setProperty("qualifier", s);
return this;
}

public void populate(C component) {
setKey(component.getKey());
setName(component.getName());
setQualifier(component.getQualifier());
if (component instanceof ResourceComponent) {
element().setProperty("sid", ((ResourceComponent) component).getSnapshotId());
}
}
}

+ 47
- 0
sonar-core/src/main/java/org/sonar/core/component/ElementWrapper.java View File

@@ -0,0 +1,47 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import com.tinkerpop.blueprints.Element;

/**
* Wrap a Blueprints vertex or edge.
*/
public abstract class ElementWrapper<T extends Element> {

private T element;
private ComponentGraph graph;

public T element() {
return element;
}

void setElement(T element) {
this.element = element;
}

public ComponentGraph graph() {
return graph;
}

void setGraph(ComponentGraph graph) {
this.graph = graph;
}
}

+ 95
- 0
sonar-core/src/main/java/org/sonar/core/component/ElementWrappers.java View File

@@ -0,0 +1,95 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import com.google.common.collect.MapMaker;
import com.tinkerpop.blueprints.Element;

import java.util.Map;

public class ElementWrappers {


private final Map<ElementKey, ElementWrapper> cache;

public ElementWrappers() {
cache = new MapMaker().weakValues().makeMap();
}

public void clear() {
cache.clear();
}

public <T extends ElementWrapper> T wrap(Element element, Class<T> wrapperClass, ComponentGraph graph) {
ElementKey key = new ElementKey(element, wrapperClass);
T wrapper = (T) cache.get(key);
if (wrapper == null) {
try {
wrapper = (T)key.wrapperClass.newInstance();
wrapper.setElement(key.element);
wrapper.setGraph(graph);
cache.put(key, wrapper);
} catch (InstantiationException e) {
throw new IllegalStateException("Class has no default constructor: " + wrapperClass, e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Can not access to default constructor: " + wrapperClass, e);
}
}
return wrapper;
}

public ElementWrappers remove(Element elt, Class wrapperClass) {
cache.remove(new ElementKey(elt, wrapperClass));
return this;
}

private static class ElementKey {
Element element;
Class<? extends ElementWrapper> wrapperClass;

ElementKey(Element element, Class<? extends ElementWrapper> wrapperClass) {
this.element = element;
this.wrapperClass = wrapperClass;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

ElementKey that = (ElementKey) o;
if (!element.equals(that.element)) {
return false;
}
return wrapperClass.equals(that.wrapperClass);
}

@Override
public int hashCode() {
int result = element.hashCode();
result = 31 * result + wrapperClass.hashCode();
return result;
}
}
}

+ 43
- 0
sonar-core/src/main/java/org/sonar/core/component/GraphReader.java View File

@@ -0,0 +1,43 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.blueprints.util.io.graphson.GraphSONReader;
import org.sonar.core.component.ComponentGraph;

import java.io.ByteArrayInputStream;
import java.io.IOException;

public class GraphReader {

public ComponentGraph read(String data, String rootVertexId) {
ByteArrayInputStream input = new ByteArrayInputStream(data.getBytes());
try {
TinkerGraph graph = new TinkerGraph();
GraphSONReader.inputGraph(graph, input);
Vertex root = graph.getVertex(rootVertexId);
return new ComponentGraph(graph, root);
} catch (IOException e) {
throw new IllegalStateException();
}
}
}

+ 63
- 0
sonar-core/src/main/java/org/sonar/core/component/GraphStorage.java View File

@@ -0,0 +1,63 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import org.slf4j.LoggerFactory;
import org.sonar.core.graph.GraphDto;
import org.sonar.core.graph.GraphDtoMapper;
import org.sonar.core.graph.GraphWriter;
import org.sonar.core.persistence.BatchSession;
import org.sonar.core.persistence.MyBatis;

public class GraphStorage {
private final MyBatis myBatis;
private final ComponentGraph componentGraph;

public GraphStorage(MyBatis myBatis, ComponentGraph componentGraph) {
this.myBatis = myBatis;
this.componentGraph = componentGraph;
}

public void save() {
LoggerFactory.getLogger(GraphStorage.class).info("Persisting graphs of components");
BatchSession session = myBatis.openBatchSession();
GraphDtoMapper mapper = session.getMapper(GraphDtoMapper.class);
try {
TinkerGraph subGraph = new TinkerGraph();
GraphWriter writer = new GraphWriter();
for (Vertex component : componentGraph.getRootVertex().getVertices(Direction.OUT, "component")) {
Long snapshotId = (Long) component.getProperty("sid");
if (snapshotId != null) {
String data = writer.write(componentGraph.getUnderlyingGraph());
mapper.insert(new GraphDto()
.setData(data).setFormat("graphson").setPerspective("testplan").setVersion(1)
.setSnapshotId(snapshotId).setRootVertexId(component.getId().toString()));
subGraph.clear();
}
}
session.commit();
} finally {
session.close();
}
}
}

+ 40
- 0
sonar-core/src/main/java/org/sonar/core/component/PerspectiveBuilder.java View File

@@ -0,0 +1,40 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.api.component.Perspective;

public abstract class PerspectiveBuilder<T extends Perspective> implements BatchComponent, ServerComponent {

private final Class<T> perspectiveClass;

protected PerspectiveBuilder(Class<T> perspectiveClass) {
this.perspectiveClass = perspectiveClass;
}

protected Class<T> getPerspectiveClass() {
return perspectiveClass;
}

public abstract T build(ComponentWrapper<?> componentWrapper);

}

+ 86
- 0
sonar-core/src/main/java/org/sonar/core/component/PerspectiveBuilders.java View File

@@ -0,0 +1,86 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.component.Component;
import org.sonar.api.component.Perspective;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Resource;

import javax.annotation.CheckForNull;

import java.util.Map;

public class PerspectiveBuilders implements ResourcePerspectives, BatchComponent, ServerComponent {
private final ComponentGraph graph;
private Map<Class<?>, PerspectiveBuilder<?>> builders = Maps.newHashMap();
private final Map<Component, Map<Class<Perspective>, Perspective>> components = new MapMaker().weakValues().makeMap();
private final SonarIndex resourceIndex;

public PerspectiveBuilders(ComponentGraph graph, PerspectiveBuilder[] builders, SonarIndex resourceIndex) {
this.graph = graph;
this.resourceIndex = resourceIndex;
for (PerspectiveBuilder builder : builders) {
// TODO check duplications
this.builders.put(builder.getPerspectiveClass(), builder);
}
}

@CheckForNull
public <P extends Perspective> P as(Component component, Class<P> toClass) {
if (component.getKey() == null) {
return null;
}
Map<Class<Perspective>, Perspective> perspectives = components.get(component);
if (perspectives == null) {
perspectives = Maps.newHashMap();
components.put(component, perspectives);
}
P perspective = (P) perspectives.get(toClass);
if (perspective == null) {
ComponentWrapper componentWrapper = graph.wrap(component, ComponentWrapper.class);
perspective = builderFor(toClass).build(componentWrapper);
perspectives.put((Class) toClass, perspective);
}
return perspective;
}

public <P extends Perspective> P as(Resource resource, Class<P> toClass) {
Resource indexedResource = resourceIndex.getResource(resource);
if (indexedResource != null) {
return as(new ResourceComponent(indexedResource), toClass);
}
return null;
}

<T extends Perspective> PerspectiveBuilder<T> builderFor(Class<T> clazz) {
PerspectiveBuilder<T> builder = (PerspectiveBuilder<T>) builders.get(clazz);
if (builder == null) {
throw new PerspectiveNotFoundException("Perspective class is not registered: " + clazz);
}
return builder;
}
}

+ 63
- 0
sonar-core/src/main/java/org/sonar/core/component/PerspectiveLoaders.java View File

@@ -0,0 +1,63 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import org.sonar.api.ServerComponent;
import org.sonar.api.component.Perspective;
import org.sonar.core.graph.GraphDao;
import org.sonar.core.graph.GraphDto;
import org.sonar.core.test.DefaultTestPlan;
import org.sonar.core.test.DefaultTestable;

import javax.annotation.CheckForNull;

public class PerspectiveLoaders implements ServerComponent {

private final GraphDao dao;

public PerspectiveLoaders(GraphDao dao) {
this.dao = dao;
}

@CheckForNull
<T extends Perspective> T as(String componentKey, String perspectiveKey) {
GraphDto graphDto = dao.selectByComponent(perspectiveKey, componentKey);
return doAs(perspectiveKey, graphDto);
}

@CheckForNull
<T extends Perspective> T as(long snapshotId, String perspectiveKey) {
GraphDto graphDto = dao.selectBySnapshot(perspectiveKey, snapshotId);
return doAs(perspectiveKey, graphDto);
}

private <T extends Perspective> T doAs(String perspectiveKey, GraphDto graphDto) {
T result = null;
if (graphDto != null) {
ComponentGraph graph = new GraphReader().read(graphDto.getData(), graphDto.getRootVertexId());
if (perspectiveKey.equals("testplan")) {
result = (T) graph.wrap(graph.getRootVertex(), DefaultTestPlan.class);
} else if (perspectiveKey.equals("testable")) {
result = (T) graph.wrap(graph.getRootVertex(), DefaultTestable.class);
}
}
return result;
}
}

+ 26
- 0
sonar-core/src/main/java/org/sonar/core/component/PerspectiveNotFoundException.java View File

@@ -0,0 +1,26 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

public class PerspectiveNotFoundException extends RuntimeException {
public PerspectiveNotFoundException(String message) {
super(message);
}
}

+ 62
- 0
sonar-core/src/main/java/org/sonar/core/component/ResourceComponent.java View File

@@ -0,0 +1,62 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import org.sonar.api.component.Component;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Resource;

import javax.annotation.Nullable;

class ResourceComponent implements Component {
private String key;
private String name;
private String qualifier;
private Long snapshotId;

ResourceComponent(Resource resource, @Nullable Snapshot snapshot) {
this.key = resource.getEffectiveKey();
this.name = resource.getName();
this.qualifier = resource.getQualifier();
if (snapshot!=null && snapshot.getId()!=null) {
this.snapshotId = snapshot.getId().longValue();
}
}

ResourceComponent(Resource resource) {
this(resource, null);
}

public String getKey() {
return key;
}

public String getName() {
return name;
}

public String getQualifier() {
return qualifier;
}

public Long getSnapshotId() {
return snapshotId;
}
}

+ 41
- 0
sonar-core/src/main/java/org/sonar/core/component/TransientGraph.java View File

@@ -0,0 +1,41 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;

public class TransientGraph {
private Graph graph;
private Vertex root;

public TransientGraph() {
this.graph = new TinkerGraph();
}

public Vertex getRootVertex() {
return root;
}

public Graph getUnderlyingGraph() {
return graph;
}
}

+ 23
- 0
sonar-core/src/main/java/org/sonar/core/component/package-info.java View File

@@ -0,0 +1,23 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
@ParametersAreNonnullByDefault
package org.sonar.core.component;

import javax.annotation.ParametersAreNonnullByDefault;

+ 53
- 0
sonar-core/src/main/java/org/sonar/core/graph/GraphDao.java View File

@@ -0,0 +1,53 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.graph;

import org.apache.ibatis.session.SqlSession;
import org.sonar.core.persistence.MyBatis;

public class GraphDao {
private final MyBatis mybatis;

public GraphDao(MyBatis mybatis) {
this.mybatis = mybatis;
}

public GraphDto selectBySnapshot(String perspectiveKey, long snapshotId) {
SqlSession session = mybatis.openBatchSession();
try {
GraphDtoMapper mapper = session.getMapper(GraphDtoMapper.class);
return mapper.selectBySnapshot(perspectiveKey, snapshotId);

} finally {
MyBatis.closeQuietly(session);
}
}

public GraphDto selectByComponent(String perspectiveKey, String componentKey) {
SqlSession session = mybatis.openBatchSession();
try {
GraphDtoMapper mapper = session.getMapper(GraphDtoMapper.class);
return mapper.selectByComponent(perspectiveKey, componentKey);

} finally {
MyBatis.closeQuietly(session);
}
}
}

+ 83
- 0
sonar-core/src/main/java/org/sonar/core/graph/GraphDto.java View File

@@ -0,0 +1,83 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.graph;

public class GraphDto {
private long snapshotId;
private String format;
private String perspective;
private int version;
private String rootVertexId;
private String data;

public long getSnapshotId() {
return snapshotId;
}

public GraphDto setSnapshotId(long snapshotId) {
this.snapshotId = snapshotId;
return this;
}

public String getPerspective() {
return perspective;
}

public GraphDto setPerspective(String perspective) {
this.perspective = perspective;
return this;
}

public String getFormat() {
return format;
}

public GraphDto setFormat(String format) {
this.format = format;
return this;
}

public int getVersion() {
return version;
}

public GraphDto setVersion(int version) {
this.version = version;
return this;
}

public String getRootVertexId() {
return rootVertexId;
}

public GraphDto setRootVertexId(String rootVertexId) {
this.rootVertexId = rootVertexId;
return this;
}

public String getData() {
return data;
}

public GraphDto setData(String data) {
this.data = data;
return this;
}
}

+ 30
- 0
sonar-core/src/main/java/org/sonar/core/graph/GraphDtoMapper.java View File

@@ -0,0 +1,30 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.graph;

import org.apache.ibatis.annotations.Param;

public interface GraphDtoMapper {
void insert(GraphDto graph);

GraphDto selectBySnapshot(@Param("perspective") String perspectiveKey, @Param("sid") long snapshotId);

GraphDto selectByComponent(@Param("perspective") String perspectiveKey, @Param("key") String componentKey);
}

+ 100
- 0
sonar-core/src/main/java/org/sonar/core/graph/GraphUtil.java View File

@@ -0,0 +1,100 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.graph;

import com.google.common.collect.Lists;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.blueprints.util.ElementHelper;
import com.tinkerpop.gremlin.java.GremlinPipeline;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;

import java.util.Iterator;
import java.util.List;

public class GraphUtil {

private GraphUtil() {
}

/**
* Get adjacent vertex. It assumes that there are only 0 or 1 results.
*
* @throws MultipleVerticesException if there are more than 1 adjacent vertices with the given criteria.
*/
@CheckForNull
public static Vertex adjacent(Vertex from, Direction direction, String... labels) {
Iterator<Vertex> vertices = from.getVertices(direction, labels).iterator();
Vertex result = null;
if (vertices.hasNext()) {
result = vertices.next();
if (vertices.hasNext()) {
throw new MultipleVerticesException(String.format("More than one vertex adjacent to: %s, direction: %s, labels: ", from, direction, labels));
}
}
return result;
}

public static <T extends Element> T single(Iterable<T> iterable) {
Iterator<T> iterator = iterable.iterator();
T result = null;
if (iterator.hasNext()) {
result = iterator.next();
if (iterator.hasNext()) {
throw new MultipleVerticesException("More than one elements");
}
}
return result;
}

public static void setNullableProperty(Element elt, String key, @Nullable Object value) {
if (value == null) {
elt.removeProperty(key);
} else {
elt.setProperty(key, value);
}
}

public static void subGraph(GremlinPipeline path, TinkerGraph toGraph) {
List<Edge> edges = Lists.newArrayList();
if (path.hasNext()) {
for (Object element : (Iterable) path.next()) {
if (element instanceof Vertex) {
Vertex v = (Vertex) element;
Vertex toVertex = toGraph.addVertex(v.getId());
ElementHelper.copyProperties(v, toVertex);
} else if (element instanceof Edge) {
edges.add((Edge) element);
}
}
for (Edge edge : edges) {
Vertex from = edge.getVertex(Direction.IN);
Vertex to = edge.getVertex(Direction.OUT);
Edge copyEdge = toGraph.addEdge(edge.getId(), toGraph.getVertex(from.getId()), toGraph.getVertex(to.getId()), edge.getLabel());
ElementHelper.copyProperties(edge, copyEdge);
}
}
}
}

+ 45
- 0
sonar-core/src/main/java/org/sonar/core/graph/GraphWriter.java View File

@@ -0,0 +1,45 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.graph;

import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.util.io.graphson.GraphSONMode;
import com.tinkerpop.blueprints.util.io.graphson.GraphSONWriter;
import org.apache.commons.io.IOUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class GraphWriter {

public String write(Graph graph) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
GraphSONWriter.outputGraph(graph, output, GraphSONMode.COMPACT);
output.flush();
output.close();
return new String(output.toByteArray());
} catch (IOException e) {
throw new IllegalStateException("Fail to export graph to JSON", e);
} finally {
IOUtils.closeQuietly(output);
}
}
}

+ 26
- 0
sonar-core/src/main/java/org/sonar/core/graph/MultipleVerticesException.java View File

@@ -0,0 +1,26 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.graph;

public class MultipleVerticesException extends RuntimeException {
public MultipleVerticesException(String message) {
super(message);
}
}

+ 23
- 0
sonar-core/src/main/java/org/sonar/core/graph/package-info.java View File

@@ -0,0 +1,23 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
@ParametersAreNonnullByDefault
package org.sonar.core.graph;

import javax.annotation.ParametersAreNonnullByDefault;

+ 2
- 0
sonar-core/src/main/java/org/sonar/core/persistence/DaoUtils.java View File

@@ -20,6 +20,7 @@
package org.sonar.core.persistence;

import com.google.common.collect.ImmutableList;
import org.sonar.core.graph.GraphDao;
import org.sonar.core.dashboard.ActiveDashboardDao;
import org.sonar.core.dashboard.DashboardDao;
import org.sonar.core.duplication.DuplicationDao;
@@ -50,6 +51,7 @@ public final class DaoUtils {
AuthorDao.class,
DashboardDao.class,
DuplicationDao.class,
GraphDao.class,
LoadedTemplateDao.class,
MeasureFilterDao.class,
PropertiesDao.class,

+ 1
- 0
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseUtils.java View File

@@ -57,6 +57,7 @@ public final class DatabaseUtils {
"dependencies",
"duplications_index",
"events",
"graphs",
"groups",
"groups_users",
"group_roles",

+ 1
- 1
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java View File

@@ -32,7 +32,7 @@ import java.util.List;
*/
public class DatabaseVersion implements BatchComponent, ServerComponent {

public static final int LAST_VERSION = 363;
public static final int LAST_VERSION = 370;

public static enum Status {
UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL

+ 4
- 1
sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java View File

@@ -38,6 +38,8 @@ import org.sonar.api.config.Settings;
import org.sonar.api.database.model.MeasureData;
import org.sonar.api.database.model.MeasureMapper;
import org.sonar.api.database.model.MeasureModel;
import org.sonar.core.graph.GraphDto;
import org.sonar.core.graph.GraphDtoMapper;
import org.sonar.core.config.Logback;
import org.sonar.core.dashboard.ActiveDashboardDto;
import org.sonar.core.dashboard.ActiveDashboardMapper;
@@ -114,6 +116,7 @@ public class MyBatis implements BatchComponent, ServerComponent {
loadAlias(conf, "Dashboard", DashboardDto.class);
loadAlias(conf, "Dependency", DependencyDto.class);
loadAlias(conf, "DuplicationUnit", DuplicationUnitDto.class);
loadAlias(conf, "Graph", GraphDto.class);
loadAlias(conf, "Group", GroupDto.class);
loadAlias(conf, "GroupRole", GroupRoleDto.class);
loadAlias(conf, "LoadedTemplate", LoadedTemplateDto.class);
@@ -137,7 +140,7 @@ public class MyBatis implements BatchComponent, ServerComponent {
loadAlias(conf, "MeasureData", MeasureData.class);

Class<?>[] mappers = {ActiveDashboardMapper.class, AuthorMapper.class, DashboardMapper.class,
DependencyMapper.class, DuplicationMapper.class, LoadedTemplateMapper.class, MeasureFilterMapper.class, PropertiesMapper.class, PurgeMapper.class,
DependencyMapper.class, DuplicationMapper.class, GraphDtoMapper.class, LoadedTemplateMapper.class, MeasureFilterMapper.class, PropertiesMapper.class, PurgeMapper.class,
ResourceKeyUpdaterMapper.class, ResourceIndexerMapper.class, ResourceMapper.class, ResourceSnapshotMapper.class, ReviewCommentMapper.class,
ReviewMapper.class, RoleMapper.class, RuleMapper.class, SchemaMigrationMapper.class, SemaphoreMapper.class, UserMapper.class, WidgetMapper.class, WidgetPropertyMapper.class,
MeasureMapper.class};

+ 40
- 0
sonar-core/src/main/resources/org/sonar/core/graph/GraphDtoMapper.xml View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.sonar.core.graph.GraphDtoMapper">

<select id="selectBySnapshot" parameterType="map" resultType="Graph">
SELECT snapshot_id as snapshotId, format, version, perspective, data
FROM graphs
WHERE snapshot_id = #{sid} AND perspective = #{perspective}
</select>

<select id="selectByComponent" parameterType="map" resultType="Graph">
SELECT g.snapshot_id as snapshotId, g.format, g.version, g.perspective, g.data
FROM graphs g, snapshots s
WHERE g.perspective = #{perspective} AND g.snapshot_id=s.id AND s.islast=${_true} and s.project_id=(
select id from projects where enabled=${_true} and kee=#{key} and person_id is null and copy_resource_id is null
)
</select>

<insert id="insert" parameterType="Graph" useGeneratedKeys="false">
insert into graphs
(snapshot_id, format, version, perspective, root_vertex_id, data, created_at, updated_at)
values (
#{snapshotId}, #{format}, #{version}, #{perspective}, #{rootVertexId},
#{data}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
</insert>

<!-- Oracle -->
<insert id="insert" databaseId="oracle" parameterType="Graph" useGeneratedKeys="false" keyProperty="id">
<selectKey order="BEFORE" resultType="Long" keyProperty="id">
select graphs_seq.NEXTVAL from DUAL
</selectKey>
insert into graphs
(id, snapshot_id, format, version, perspective, root_vertex_id, data, created_at, updated_at)
values (
#{id}, #{snapshotId}, #{format}, #{version}, #{perspective}, #{rootVertexId},
#{data}, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
</insert>
</mapper>


+ 1
- 0
sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql View File

@@ -148,6 +148,7 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('360');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('361');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('362');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('363');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('370');

INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;

+ 15
- 1
sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl View File

@@ -499,6 +499,18 @@ CREATE TABLE "MEASURE_FILTER_FAVOURITES" (
"CREATED_AT" TIMESTAMP
);

CREATE TABLE "GRAPHS" (
"ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
"SNAPSHOT_ID" INTEGER NOT NULL,
"FORMAT" VARCHAR(20),
"PERSPECTIVE" VARCHAR(30),
"VERSION" VARCHAR(20),
"ROOT_VERTEX_ID" VARCHAR(30),
"DATA" CLOB(2147483647),
"CREATED_AT" TIMESTAMP,
"UPDATED_AT" TIMESTAMP
);

-- ----------------------------------------------
-- DDL Statements for indexes
-- ----------------------------------------------
@@ -607,4 +619,6 @@ CREATE UNIQUE INDEX "UNIQ_AUTHOR_LOGINS" ON "AUTHORS" ("LOGIN");

CREATE INDEX "MEASURE_FILTERS_NAME" ON "MEASURE_FILTERS" ("NAME");

CREATE INDEX "MEASURE_FILTER_FAVS_USERID" ON "MEASURE_FILTER_FAVOURITES" ("USER_ID");
CREATE INDEX "MEASURE_FILTER_FAVS_USERID" ON "MEASURE_FILTER_FAVOURITES" ("USER_ID");

CREATE UNIQUE INDEX "GRAPHS_PERSPECTIVES" ON "GRAPHS" ("SNAPSHOT_ID", "PERSPECTIVE");

+ 47
- 0
sonar-core/src/test/java/org/sonar/core/component/GraphUtilTest.java View File

@@ -0,0 +1,47 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.core.component;

import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.tg.TinkerGraph;
import com.tinkerpop.gremlin.java.GremlinPipeline;
import org.junit.Test;
import org.sonar.core.graph.GraphUtil;

import static org.fest.assertions.Assertions.assertThat;

public class GraphUtilTest {
@Test
public void subGraph() {
TinkerGraph graph = new TinkerGraph();
Vertex a = graph.addVertex("1");
Vertex b = graph.addVertex("2");
Vertex c = graph.addVertex("3");
graph.addEdge("4", a, b, "likes");
graph.addEdge("5", b, c, "has");

TinkerGraph subGraph = new TinkerGraph();
GremlinPipeline pipeline = new GremlinPipeline(a).outE("likes").inV().path();
GraphUtil.subGraph(pipeline, subGraph);

assertThat(subGraph.getVertices()).hasSize(2);
assertThat(subGraph.getEdges()).hasSize(1);
}
}

+ 29
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/CoveredTestable.java View File

@@ -0,0 +1,29 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.api.test;

import java.util.Collection;

public interface CoveredTestable {

TestCase testCase();
Testable testable();
Collection<Integer> lines();
}

+ 30
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestCase.java View File

@@ -0,0 +1,30 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.api.test;

import javax.annotation.Nullable;

public interface MutableTestCase extends TestCase {
MutableTestCase setStatus(String s);

MutableTestCase setDurationInMs(@Nullable Long l);

MutableTestCase setName(String s);
}

+ 28
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestPlan.java View File

@@ -0,0 +1,28 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.api.test;

import org.sonar.api.component.MutablePerspective;

public interface MutableTestPlan extends TestPlan<MutableTestCase>, MutablePerspective {

MutableTestCase addTestCase(String key);

}

+ 26
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/MutableTestable.java View File

@@ -0,0 +1,26 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.api.test;

import org.sonar.api.component.MutablePerspective;

public interface MutableTestable extends Testable, MutablePerspective {

}

+ 52
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/TestCase.java View File

@@ -0,0 +1,52 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.api.test;

import java.util.Collection;

public interface TestCase {
String TYPE_UNIT = "unit";
String TYPE_INTEGRATION = "integ";

String STATUS_PASS = "pass";
String STATUS_FAIL = "fail";

// unit test/integration test/...
String type();

/**
* Duration in milliseconds
*/
Long durationInMs();

// pass/fail/...
String status();

/**
* The key is not null and unique among the test plan.
*/
String key();

String name();

TestPlan testPlan();

Collection<CoveredTestable> coveredBlocks();
}

+ 28
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/TestPlan.java View File

@@ -0,0 +1,28 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.api.test;

import org.sonar.api.component.Perspective;

import java.util.List;

public interface TestPlan<T extends TestCase> extends Perspective {
List<T> testCases();
}

+ 32
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/Testable.java View File

@@ -0,0 +1,32 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.api.test;

import org.sonar.api.component.Perspective;

import java.util.List;
import java.util.SortedSet;

public interface Testable extends Perspective {
List<TestCase> coveringTestCases();

List<TestCase> testCasesCoveringLine(int line);

}

+ 23
- 0
sonar-plugin-api/src/main/java/org/sonar/api/test/package-info.java View File

@@ -0,0 +1,23 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
@ParametersAreNonnullByDefault
package org.sonar.api.test;

import javax.annotation.ParametersAreNonnullByDefault;

+ 11
- 0
sonar-server/src/main/java/org/sonar/server/platform/Platform.java View File

@@ -36,6 +36,9 @@ import org.sonar.api.utils.TimeProfiler;
import org.sonar.api.utils.UriReader;
import org.sonar.api.workflow.internal.DefaultWorkflow;
import org.sonar.core.PicoUtils;
import org.sonar.core.component.ComponentGraph;
import org.sonar.core.component.PerspectiveBuilders;
import org.sonar.core.component.PerspectiveLoaders;
import org.sonar.core.config.Logback;
import org.sonar.core.i18n.GwtI18n;
import org.sonar.core.i18n.I18nManager;
@@ -55,6 +58,8 @@ import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.qualitymodel.DefaultModelFinder;
import org.sonar.core.resource.DefaultResourcePermissions;
import org.sonar.core.rule.DefaultRuleFinder;
import org.sonar.core.test.TestPlanBuilder;
import org.sonar.core.test.TestableBuilder;
import org.sonar.core.timemachine.Periods;
import org.sonar.core.user.DefaultUserFinder;
import org.sonar.core.workflow.ReviewDatabaseStore;
@@ -256,6 +261,12 @@ public final class Platform {
servicesContainer.addSingleton(DefaultNotificationManager.class);
servicesContainer.addSingleton(ReviewsNotificationManager.class);

servicesContainer.addSingleton(ComponentGraph.class);
servicesContainer.addSingleton(TestPlanBuilder.class);
servicesContainer.addSingleton(TestableBuilder.class);
servicesContainer.addSingleton(PerspectiveBuilders.class);
servicesContainer.addSingleton(PerspectiveLoaders.class);

ServerExtensionInstaller extensionRegistrar = servicesContainer.getComponentByType(ServerExtensionInstaller.class);
extensionRegistrar.registerExtensions(servicesContainer);


+ 38
- 0
sonar-server/src/main/webapp/WEB-INF/db/migrate/370_create_graphs.rb View File

@@ -0,0 +1,38 @@
#
# Sonar, entreprise quality control tool.
# Copyright (C) 2008-2012 SonarSource
# mailto:contact AT sonarsource DOT com
#
# Sonar 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.
#
# Sonar 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 Sonar; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
#

#
# Sonar 3.5
#
class CreateGraphs < ActiveRecord::Migration
def self.up
create_table 'graphs' do |t|
t.column 'snapshot_id', :integer, :null => false
t.column 'format', :string, :null => true, :limit => 20
t.column 'perspective', :string, :null => true, :limit => 30
t.column 'version', :string, :null => true, :limit => 20
t.column 'root_vertex_id', :string, :null => true, :limit => 30
t.column 'data', :text, :null => true
t.timestamps
end
add_index 'graphs', ['snapshot_id', 'perspective'], :name => 'graphs_perspectives', :unique => true
end
end


+ 1
- 1
sonar-server/src/main/webapp/WEB-INF/db/migrate/README.txt View File

@@ -1,7 +1,7 @@
HOW TO ADD A MIGRATION

* Jump some versions when adding the first Ruby on Rails migration of a new sonar version. For example if sonar 2.10 is 193, then sonar 2.11 should start at 200.
* Complete the DDL files for Derby :
* Complete the DDL files for H2 :
+ sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
+ sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql :
- add "INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('<THE MIGRATION ID>')"

Loading…
Cancel
Save