@@ -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> |
@@ -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> |
@@ -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."); | |||
} | |||
} |
@@ -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; | |||
} | |||
@@ -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(); | |||
} |
@@ -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() { |
@@ -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> |
@@ -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; | |||
} | |||
} |
@@ -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()); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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); | |||
} | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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; |
@@ -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, |
@@ -57,6 +57,7 @@ public final class DatabaseUtils { | |||
"dependencies", | |||
"duplications_index", | |||
"events", | |||
"graphs", | |||
"groups", | |||
"groups_users", | |||
"group_roles", |
@@ -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 |
@@ -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}; |
@@ -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> | |||
@@ -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; |
@@ -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"); |
@@ -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); | |||
} | |||
} |
@@ -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(); | |||
} |
@@ -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); | |||
} |
@@ -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); | |||
} |
@@ -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 { | |||
} |
@@ -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(); | |||
} |
@@ -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(); | |||
} |
@@ -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); | |||
} |
@@ -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; |
@@ -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); | |||
@@ -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,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>')" |