diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-21 21:25:29 +0000 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-21 21:25:29 +0000 |
commit | d46e081eacea3680bae90faa5df1ae43157d1e87 (patch) | |
tree | 3e7bea37e9b306f335cd6a52910b6ffb4068bec2 /sonar-server | |
parent | d4963b41c34bc8a0d94ad80fe098cd088bb4a5a0 (diff) | |
download | sonarqube-d46e081eacea3680bae90faa5df1ae43157d1e87.tar.gz sonarqube-d46e081eacea3680bae90faa5df1ae43157d1e87.zip |
quality models: limit the methods of org.sonar.api.qualitymodel.ModelFinder to read methods. Management methods are restricted to core => extracted to org.sonar.server.qualitymodel.ModelManager
Diffstat (limited to 'sonar-server')
12 files changed, 357 insertions, 12 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index 5bbb113f777..bd154a4f770 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -49,6 +49,7 @@ import org.sonar.server.database.JndiDatabaseConnector; import org.sonar.server.filters.FilterExecutor; import org.sonar.server.mavendeployer.MavenRepository; import org.sonar.server.plugins.*; +import org.sonar.server.qualitymodel.DefaultModelManager; import org.sonar.server.rules.*; import org.sonar.server.startup.*; import org.sonar.server.ui.AuthenticatorFactory; @@ -155,6 +156,7 @@ public final class Platform { pluginRepository.registerPlugins(servicesContainer); servicesContainer.as(Characteristics.CACHE).addComponent(DefaultModelFinder.class); // depends on plugins + servicesContainer.as(Characteristics.CACHE).addComponent(DefaultModelManager.class); servicesContainer.as(Characteristics.CACHE).addComponent(Plugins.class); servicesContainer.as(Characteristics.CACHE).addComponent(ChartFactory.class); servicesContainer.as(Characteristics.CACHE).addComponent(Languages.class); diff --git a/sonar-server/src/main/java/org/sonar/server/qualitymodel/DefaultModelManager.java b/sonar-server/src/main/java/org/sonar/server/qualitymodel/DefaultModelManager.java new file mode 100644 index 00000000000..84ccb3999bb --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitymodel/DefaultModelManager.java @@ -0,0 +1,124 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.server.qualitymodel; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.LoggerFactory; +import org.sonar.api.ServerComponent; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.qualitymodel.Model; +import org.sonar.api.qualitymodel.ModelDefinition; +import org.sonar.api.utils.Logs; +import org.sonar.api.utils.SonarException; +import org.sonar.jpa.session.DatabaseSessionFactory; + +import javax.persistence.Query; + +public final class DefaultModelManager implements ServerComponent, ModelManager { + + private ModelDefinition[] definitions; + private DatabaseSessionFactory sessionFactory; + + public DefaultModelManager(DatabaseSessionFactory sessionFactory, ModelDefinition[] definitions) { + this.sessionFactory = sessionFactory; + this.definitions = definitions; + } + + /** + * This constructor is used when there are no templates + */ + public DefaultModelManager(DatabaseSessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + this.definitions = new ModelDefinition[0]; + } + + /** + * Executed when the server starts + */ + public ModelManager registerDefinitions() { + DatabaseSession session = sessionFactory.getSession(); + for (ModelDefinition definition : definitions) { + if (StringUtils.isNotBlank(definition.getName()) && !exists(session, definition.getName())) { + Logs.INFO.info("Register quality model: " + definition.getName()); + Model model = definition.create(); + if (StringUtils.isBlank(model.getName())) { + model.setName(definition.getName()); + } + insert(session, model); + session.commit(); + } + } + return this; + } + + public Model reset(String name) { + ModelDefinition definition = findDefinitionByName(name); + if (definition == null) { + throw new SonarException("Can not reset quality model. Definition not found: " + name); + } + + LoggerFactory.getLogger(getClass()).info("Reset quality model: " + name); + Model model = definition.create(); + return reset(model); + } + + + Model reset(Model model) { + DatabaseSession session = sessionFactory.getSession(); + try { + delete(session, model.getName()); + model = insert(session, model); + session.commit(); + return model; + + } catch (RuntimeException e) { + session.rollback(); + throw e; + } + } + + public ModelDefinition findDefinitionByName(String name) { + for (ModelDefinition definition : definitions) { + if (StringUtils.equals(name, definition.getName())) { + return definition; + } + } + return null; + } + + public static void delete(DatabaseSession session, String name) { + Model model = session.getSingleResult(Model.class, "name", name); + if (model != null) { + session.removeWithoutFlush(model); + session.commit(); + } + } + + public static Model insert(DatabaseSession session, Model model) { + return (Model) session.saveWithoutFlush(model); + } + + public static boolean exists(DatabaseSession session, String name) { + Query query = session.getEntityManager().createQuery("SELECT COUNT(qm) FROM " + Model.class.getSimpleName() + " qm WHERE qm.name=:name"); + query.setParameter("name", name); + Number count = (Number) query.getSingleResult(); + return count.intValue() > 0; + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/qualitymodel/ModelManager.java b/sonar-server/src/main/java/org/sonar/server/qualitymodel/ModelManager.java new file mode 100644 index 00000000000..8bd0f005e9e --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/qualitymodel/ModelManager.java @@ -0,0 +1,33 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.server.qualitymodel; + +import org.sonar.api.qualitymodel.Model; +import org.sonar.api.qualitymodel.ModelDefinition; + +public interface ModelManager { + + ModelManager registerDefinitions(); + + Model reset(String name); + + ModelDefinition findDefinitionByName(String name); +} diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterQualityModels.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterQualityModels.java index b364bcbadff..424bd7378bc 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/RegisterQualityModels.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterQualityModels.java @@ -20,25 +20,23 @@ package org.sonar.server.startup; import org.sonar.api.utils.TimeProfiler; -import org.sonar.core.qualitymodel.DefaultModelFinder; +import org.sonar.server.qualitymodel.ModelManager; public final class RegisterQualityModels { - private DefaultModelFinder provider; + private ModelManager manager; /** - * - * @param provider * @param registerRulesBeforeModels used only to be started after the creation of check templates */ // NOSONAR the parameter registerRulesBeforeModels is only used to provide the execution order by picocontainer - public RegisterQualityModels(DefaultModelFinder provider, RegisterRules registerRulesBeforeModels) { - this.provider = provider; + public RegisterQualityModels(ModelManager manager, RegisterRules registerRulesBeforeModels) { + this.manager = manager; } public void start() { TimeProfiler profiler = new TimeProfiler().start("Register quality models"); - provider.registerDefinitions(); + manager.registerDefinitions(); profiler.stop(); } } diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index 880fec3b984..73180166d1a 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.Plugin; import org.sonar.api.Plugins; import org.sonar.api.Property; +import org.sonar.api.ServerComponent; import org.sonar.api.profiles.ProfileExporter; import org.sonar.api.profiles.ProfileImporter; import org.sonar.api.resources.Language; @@ -52,7 +53,7 @@ import org.sonar.updatecenter.common.Version; import java.util.Collection; import java.util.List; -public class JRubyFacade { +public final class JRubyFacade implements ServerComponent { public FilterResult executeFilter(Filter filter) { return getContainer().getComponent(FilterExecutor.class).execute(filter); diff --git a/sonar-server/src/test/java/org/sonar/server/qualitymodel/DefaultModelManagerTest.java b/sonar-server/src/test/java/org/sonar/server/qualitymodel/DefaultModelManagerTest.java new file mode 100644 index 00000000000..058e649d5bc --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/qualitymodel/DefaultModelManagerTest.java @@ -0,0 +1,121 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.server.qualitymodel; + +import org.junit.Test; +import org.sonar.api.qualitymodel.Characteristic; +import org.sonar.api.qualitymodel.Model; +import org.sonar.api.qualitymodel.ModelDefinition; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; + +public class DefaultModelManagerTest extends AbstractDbUnitTestCase { + + @Test + public void reset() { + setupData("shared"); + DefaultModelManager manager = new DefaultModelManager(getSessionFactory()); + + Model model = Model.createByName("M1"); + Characteristic c1 = model.createCharacteristicByName("NEWM1C1"); + Characteristic c1a = model.createCharacteristicByName("NEWM1C1A"); + c1.addChild(c1a); + + model.createCharacteristicByName("NEWM1C2"); + manager.reset(model); + + model = getSession().getSingleResult(Model.class, "name", "M1"); + assertNotNull(model); + assertThat(model.getCharacteristics().size(), is(3)); + assertThat(model.getCharacteristicByName("NEWM1C1A").getParents().size(), is(1)); + assertNotNull(model.getCharacteristicByName("NEWM1C1A").getParent("NEWM1C1")); + } + + @Test + public void noDefinitionsToRegister() { + setupData("shared"); + ModelManager provider = new DefaultModelManager(getSessionFactory()); + provider.registerDefinitions(); + + // same state + List<Model> models = getSession().getResults(Model.class); + assertThat(models.size(), is(2)); + } + + @Test + public void registerOnlyNewDefinitions() { + setupData("shared"); + + ModelDefinition existingDefinition = new FakeDefinition("M1", Model.create()); + ModelDefinition newDefinition = new FakeDefinition("NEWMODEL", Model.create()); + + ModelDefinition[] definitions = new ModelDefinition[]{existingDefinition, newDefinition}; + ModelManager manager = new DefaultModelManager(getSessionFactory(), definitions); + manager.registerDefinitions(); + + List<Model> models = getSession().getResults(Model.class); + assertThat(models.size(), is(3)); // 2 existing + one new + } + + @Test + public void registerModelProperties() { + Model model = Model.create(); + Characteristic characteristic = model.createCharacteristicByName("Usability"); + characteristic.setProperty("factor", 2.0); + characteristic.setProperty("severity", "BLOCKER"); + + setupData("shared"); + ModelDefinition def = new FakeDefinition("with-properties", model); + ModelManager manager = new DefaultModelManager(getSessionFactory(), new ModelDefinition[]{def}); + manager.registerDefinitions(); + checkTables("registerModelProperties", "quality_models", "characteristics", "characteristic_properties"); + } + + @Test + public void exists() { + setupData("shared"); + assertTrue(DefaultModelManager.exists(getSession(), "M1")); + } + + @Test + public void notExists() { + setupData("shared"); + assertFalse(DefaultModelManager.exists(getSession(), "UNKNOWN")); + } +} + +class FakeDefinition extends ModelDefinition { + private final Model model; + + public FakeDefinition(String name, Model model) { + super(name); + this.model = model; + } + + @Override + public Model create() { + return model; + } + +}
\ No newline at end of file diff --git a/sonar-server/src/test/java/org/sonar/server/startup/RegisterQualityModelsTest.java b/sonar-server/src/test/java/org/sonar/server/startup/RegisterQualityModelsTest.java index fda03fc2077..002b2abff9a 100644 --- a/sonar-server/src/test/java/org/sonar/server/startup/RegisterQualityModelsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/startup/RegisterQualityModelsTest.java @@ -20,7 +20,7 @@ package org.sonar.server.startup; import org.junit.Test; -import org.sonar.core.qualitymodel.DefaultModelFinder; +import org.sonar.server.qualitymodel.ModelManager; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -29,9 +29,9 @@ public class RegisterQualityModelsTest { @Test public void isASimpleBridgeOverProvider() { - DefaultModelFinder provider = mock(DefaultModelFinder.class); - RegisterQualityModels startup = new RegisterQualityModels(provider, null); + ModelManager manager = mock(ModelManager.class); + RegisterQualityModels startup = new RegisterQualityModels(manager, null); startup.start(); - verify(provider).registerDefinitions(); + verify(manager).registerDefinitions(); } } diff --git a/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/noDefinitionsToRegister-result.xml b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/noDefinitionsToRegister-result.xml new file mode 100644 index 00000000000..c26de5371bb --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/noDefinitionsToRegister-result.xml @@ -0,0 +1,10 @@ +<dataset> + <quality_models id="1" name="M1" /> + <quality_models id="2" name="M2" /> + + <characteristics id="1" kee="M1C1" name="M1C1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" /> + <characteristics id="2" kee="M1C2" name="M1C2" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2" description="[null]" enabled="true" /> + <characteristics id="3" kee="M2C1" name="M2C1" quality_model_id="2" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true"/> + + <characteristic_edges child_id="2" parent_id="1"/> +</dataset>
\ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/registerModelProperties-result.xml b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/registerModelProperties-result.xml new file mode 100644 index 00000000000..6deb78039ac --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/registerModelProperties-result.xml @@ -0,0 +1,16 @@ +<dataset> + <quality_models id="1" name="M1" /> + <quality_models id="2" name="M2" /> + <quality_models id="3" name="with-properties" /> + + <characteristics id="1" kee="M1C1" name="M1C1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" /> + <characteristics id="2" kee="M1C2" name="M1C2" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2" description="[null]" enabled="true" /> + <characteristics id="3" kee="M2C1" name="M2C1" quality_model_id="2" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true"/> + <characteristics id="4" kee="USABILITY" name="Usability" quality_model_id="3" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true"/> + + <characteristic_edges child_id="2" parent_id="1"/> + + <characteristic_properties id="1" characteristic_id="1" kee="foo" value="[null]" text_value="bar" /> + <characteristic_properties id="2" characteristic_id="4" kee="factor" value="2.0" text_value="[null]" /> + <characteristic_properties id="3" characteristic_id="4" kee="severity" value="[null]" text_value="BLOCKER" /> +</dataset>
\ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/registerOnlyNewDefinitions-result.xml b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/registerOnlyNewDefinitions-result.xml new file mode 100644 index 00000000000..455cfb41cde --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/registerOnlyNewDefinitions-result.xml @@ -0,0 +1,13 @@ +<dataset> + <quality_models id="1" name="M1" /> + <quality_models id="2" name="M2" /> + + <!-- NEW MODEL --> + <quality_models id="3" name="NEWMODEL" /> + + <characteristics id="1" kee="M1C1" name="M1C1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" /> + <characteristics id="2" kee="M1C2" name="M1C2" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2" description="[null]" enabled="true" /> + <characteristics id="3" kee="M2C1" name="M2C1" quality_model_id="2" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true"/> + + <characteristic_edges child_id="2" parent_id="1"/> +</dataset>
\ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/reset-result.xml b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/reset-result.xml new file mode 100644 index 00000000000..bbffd8e4a77 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/reset-result.xml @@ -0,0 +1,15 @@ +<dataset> + <!--<quality_models id="1" name="M1" />--> + <quality_models id="2" name="M2" /> + <quality_models id="3" name="M1" /> + + <!--<characteristics id="1" kee="M1C1" name="M1C1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" />--> + <!--<characteristics id="2" kee="M1C2" name="M1C2" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2" description="[null]" enabled="true"/>--> + <characteristics id="3" kee="M2C1" name="M2C1" quality_model_id="2" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" /> + <characteristics id="4" kee="NEWM1C1A" name="NEWM1C1A" quality_model_id="3" rule_id="[null]" characteristic_order="1" depth="2" description="[null]" enabled="true"/> + <characteristics id="5" kee="NEWM1C1" name="NEWM1C1" quality_model_id="3" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true"/> + <characteristics id="6" kee="NEWM1C2" name="NEWM1C2" quality_model_id="3" rule_id="[null]" characteristic_order="2" depth="1" description="[null]" enabled="true"/> + + <!--<characteristic_edges child_id="2" parent_id="1"/>--> + <characteristic_edges child_id="4" parent_id="5"/> +</dataset>
\ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/shared.xml b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/shared.xml new file mode 100644 index 00000000000..c509eb3f937 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/qualitymodel/DefaultModelManagerTest/shared.xml @@ -0,0 +1,12 @@ +<dataset> + <quality_models id="1" name="M1" /> + <quality_models id="2" name="M2" /> + + <characteristics id="1" kee="M1C1" name="M1C1" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true" /> + <characteristics id="2" kee="M1C2" name="M1C2" quality_model_id="1" rule_id="[null]" characteristic_order="1" depth="2" description="[null]" enabled="true" /> + <characteristics id="3" kee="M2C1" name="M2C1" quality_model_id="2" rule_id="[null]" characteristic_order="1" depth="1" description="[null]" enabled="true"/> + + <characteristic_edges child_id="2" parent_id="1"/> + + <characteristic_properties id="1" characteristic_id="1" kee="foo" value="[null]" text_value="bar" /> +</dataset>
\ No newline at end of file |