aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java2
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/IndexProjectPostJob.java44
-rw-r--r--plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/IndexProjectPostJobTest.java53
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java8
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java14
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java3
-rw-r--r--sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexer.java74
-rw-r--r--sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java181
-rw-r--r--sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerFilter.java26
-rw-r--r--sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerMapper.java4
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/resource/ResourceIndexerMapper.xml44
-rw-r--r--sonar-core/src/test/java/org/sonar/core/resource/ResourceIndexerDaoTest.java20
-rw-r--r--sonar-core/src/test/java/org/sonar/core/resource/ResourceIndexerTest.java65
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexAllResources.xml13
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject-result.xml43
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject.xml15
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexProjects-result.xml (renamed from sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexAllResources-result.xml)42
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexProjects.xml24
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexResource-result.xml (renamed from sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexSingleResource-result.xml)0
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexResource.xml (renamed from sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexSingleResource.xml)0
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming-result.xml1
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming.xml2
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/Platform.java2
-rw-r--r--sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java6
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/db/migrate/241_index_projects.rb (renamed from sonar-server/src/main/webapp/WEB-INF/db/migrate/241_index_resources.rb)4
26 files changed, 389 insertions, 303 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
index c876dd10c87..41e3477bf26 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
@@ -27,6 +27,7 @@ import org.sonar.api.SonarPlugin;
import org.sonar.api.checks.NoSonarFilter;
import org.sonar.api.resources.Java;
import org.sonar.plugins.core.batch.ExcludedResourceFilter;
+import org.sonar.plugins.core.batch.IndexProjectPostJob;
import org.sonar.plugins.core.batch.MavenInitializer;
import org.sonar.plugins.core.batch.ProjectFileSystemLogger;
import org.sonar.plugins.core.charts.DistributionAreaChart;
@@ -289,6 +290,7 @@ public class CorePlugin extends SonarPlugin {
extensions.add(ManualViolationInjector.class);
extensions.add(UpdateReviewsDecorator.class);
extensions.add(ViolationSeverityUpdater.class);
+ extensions.add(IndexProjectPostJob.class);
// time machine
extensions.add(TendencyDecorator.class);
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/IndexProjectPostJob.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/IndexProjectPostJob.java
new file mode 100644
index 00000000000..5beb4ac709a
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/IndexProjectPostJob.java
@@ -0,0 +1,44 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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.plugins.core.batch;
+
+import org.sonar.api.batch.PostJob;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.resources.Project;
+import org.sonar.core.NotDryRun;
+import org.sonar.core.resource.ResourceIndexerDao;
+
+/**
+ * @since 2.13
+ */
+@NotDryRun
+public class IndexProjectPostJob implements PostJob {
+ private ResourceIndexerDao indexer;
+
+ public IndexProjectPostJob(ResourceIndexerDao indexer) {
+ this.indexer = indexer;
+ }
+
+ public void executeOn(Project project, SensorContext context) {
+ if (project.getId() != null) {
+ indexer.indexProject(project.getId());
+ }
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/IndexProjectPostJobTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/IndexProjectPostJobTest.java
new file mode 100644
index 00000000000..cdb23d6fd6e
--- /dev/null
+++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/IndexProjectPostJobTest.java
@@ -0,0 +1,53 @@
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2011 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.plugins.core.batch;
+
+import org.junit.Test;
+import org.sonar.api.resources.Project;
+import org.sonar.core.resource.ResourceIndexerDao;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+public class IndexProjectPostJobTest {
+ @Test
+ public void shouldIndexProject() {
+ ResourceIndexerDao indexer = mock(ResourceIndexerDao.class);
+ IndexProjectPostJob job = new IndexProjectPostJob(indexer);
+ Project project = new Project("foo");
+ project.setId(123);
+
+ job.executeOn(project, null);
+
+ verify(indexer).indexProject(123);
+ }
+
+ @Test
+ public void shouldNotIndexProjectIfMissingId() {
+ ResourceIndexerDao indexer = mock(ResourceIndexerDao.class);
+ IndexProjectPostJob job = new IndexProjectPostJob(indexer);
+
+ job.executeOn(new Project("foo"), null);
+
+ verifyZeroInteractions(indexer);
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
index b40aa67a45a..21f6824c713 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java
@@ -27,7 +27,6 @@ import org.sonar.batch.MavenPluginExecutor;
import org.sonar.batch.ServerMetadata;
import org.sonar.batch.config.BatchSettings;
import org.sonar.batch.config.BatchSettingsEnhancer;
-import org.sonar.core.resource.ResourceIndexer;
import org.sonar.jpa.session.DatabaseSessionProvider;
import org.sonar.jpa.session.DefaultDatabaseConnector;
import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory;
@@ -67,7 +66,6 @@ public class BootstrapModule extends Module {
addCoreSingleton(BatchDatabase.class);
addCoreSingleton(MyBatis.class);
- addCoreSingleton(ResourceIndexer.class);
addCoreSingleton(DefaultDatabaseConnector.class);
addCoreSingleton(ThreadLocalDatabaseSessionFactory.class);
for (Class daoClass : DaoUtils.getDaoClasses()) {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java
index 5386b61414d..57037c987fd 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultResourcePersister.java
@@ -27,8 +27,6 @@ import org.sonar.api.database.model.ResourceModel;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.*;
import org.sonar.api.utils.SonarException;
-import org.sonar.core.resource.ResourceIndexer;
-import org.sonar.core.resource.ResourceIndexerDao;
import javax.persistence.NonUniqueResultException;
import javax.persistence.Query;
@@ -41,11 +39,9 @@ public final class DefaultResourcePersister implements ResourcePersister {
private DatabaseSession session;
private Map<Resource, Snapshot> snapshotsByResource = Maps.newHashMap();
- private ResourceIndexer indexer;
- public DefaultResourcePersister(DatabaseSession session, ResourceIndexer indexer) {
+ public DefaultResourcePersister(DatabaseSession session) {
this.session = session;
- this.indexer = indexer;
}
public Snapshot saveProject(Project project, Project parent) {
@@ -84,7 +80,6 @@ public final class DefaultResourcePersister implements ResourcePersister {
snapshot.setCreatedAt(project.getAnalysisDate());
snapshot = session.save(snapshot);
session.commit();
- indexer.index(project.getName(), snapshot.getQualifier(), snapshot.getResourceId(), snapshot.getRootProjectId());
return snapshot;
}
@@ -134,7 +129,6 @@ public final class DefaultResourcePersister implements ResourcePersister {
} else {
snapshot = persistFileOrDirectory(project, resource, parent);
}
- indexer.index(resource.getName(), snapshot.getQualifier(), snapshot.getResourceId(), snapshot.getRootProjectId());
return snapshot;
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java
index 35277ff3436..3491738c922 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultResourcePersisterTest.java
@@ -26,7 +26,6 @@ import org.sonar.api.resources.JavaPackage;
import org.sonar.api.resources.Library;
import org.sonar.api.resources.Project;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
-import org.sonar.core.resource.ResourceIndexer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -34,7 +33,6 @@ import java.text.SimpleDateFormat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
-import static org.mockito.Mockito.mock;
public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
@@ -67,7 +65,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
public void shouldSaveNewProject() {
setupData("shared");
- ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourceIndexer.class));
+ ResourcePersister persister = new DefaultResourcePersister(getSession());
persister.saveProject(singleProject, null);
checkTables("shouldSaveNewProject", "projects", "snapshots");
@@ -77,7 +75,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
public void shouldSaveNewMultiModulesProject() throws ParseException {
setupData("shared");
- ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourceIndexer.class));
+ ResourcePersister persister = new DefaultResourcePersister(getSession());
persister.saveProject(multiModuleProject, null);
persister.saveProject(moduleA, multiModuleProject);
persister.saveProject(moduleB, multiModuleProject);
@@ -90,7 +88,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
public void shouldSaveNewDirectory() {
setupData("shared");
- ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourceIndexer.class));
+ ResourcePersister persister = new DefaultResourcePersister(getSession());
persister.saveProject(singleProject, null);
persister.saveResource(singleProject, new JavaPackage("org.foo").setEffectiveKey("foo:org.foo"));
@@ -102,7 +100,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
public void shouldSaveNewLibrary() {
setupData("shared");
- ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourceIndexer.class));
+ ResourcePersister persister = new DefaultResourcePersister(getSession());
persister.saveProject(singleProject, null);
persister.saveResource(singleProject, new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"));
persister.saveResource(singleProject, new Library("junit:junit", "4.8.2").setEffectiveKey("junit:junit"));// do nothing, already saved
@@ -115,7 +113,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
public void shouldClearResourcesExceptProjects() {
setupData("shared");
- DefaultResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourceIndexer.class));
+ DefaultResourcePersister persister = new DefaultResourcePersister(getSession());
persister.saveProject(multiModuleProject, null);
persister.saveProject(moduleA, multiModuleProject);
persister.saveResource(moduleA, new JavaPackage("org.foo").setEffectiveKey("a:org.foo"));
@@ -131,7 +129,7 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase {
public void shouldUpdateExistingResource() {
setupData("shouldUpdateExistingResource");
- ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourceIndexer.class));
+ ResourcePersister persister = new DefaultResourcePersister(getSession());
singleProject.setName("new name");
singleProject.setDescription("new description");
persister.saveProject(singleProject, null);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java
index 21b784d1ff3..320db8e9608 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/phases/UpdateStatusJobTest.java
@@ -24,7 +24,6 @@ import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.model.Snapshot;
import org.sonar.batch.ServerMetadata;
import org.sonar.batch.index.DefaultResourcePersister;
-import org.sonar.core.resource.ResourceIndexer;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import javax.persistence.Query;
@@ -51,7 +50,7 @@ public class UpdateStatusJobTest extends AbstractDbUnitTestCase {
private void assertAnalysis(int snapshotId, String fixture) {
setupData("sharedFixture", fixture);
DatabaseSession session = getSession();
- UpdateStatusJob sensor = new UpdateStatusJob(mock(ServerMetadata.class), session, new DefaultResourcePersister(session, mock(ResourceIndexer.class)), loadSnapshot(snapshotId));
+ UpdateStatusJob sensor = new UpdateStatusJob(mock(ServerMetadata.class), session, new DefaultResourcePersister(session), loadSnapshot(snapshotId));
sensor.execute();
getSession().stop();
diff --git a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexer.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexer.java
deleted file mode 100644
index d184792df99..00000000000
--- a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexer.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 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.resource;
-
-import com.google.common.annotations.Beta;
-import org.apache.commons.lang.ArrayUtils;
-import org.sonar.api.BatchComponent;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
-
-/**
- * This component will be automatically called in v3.0 when a resource is created or updated.
- * It means that it will not be exposed to plugin API.
- *
- * @since 2.13
- */
-@Beta
-public class ResourceIndexer implements BatchComponent, ServerComponent {
- private ResourceIndexerDao dao;
-
- /**
- * Hardcoded list of qualifiers to index. Need to be configurable.
- * Directories and packages are explicitly excluded.
- */
- static final String[] INDEXABLE_QUALIFIERS = {
- Qualifiers.VIEW,
- Qualifiers.SUBVIEW,
- Qualifiers.PROJECT,
- Qualifiers.MODULE,
- Qualifiers.FILE,
- Qualifiers.CLASS,
- Qualifiers.UNIT_TEST_FILE
- };
-
- public ResourceIndexer(ResourceIndexerDao dao) {
- this.dao = dao;
- }
-
- public ResourceIndexer index(String resourceName, String qualifier, int resourceId, int rootProjectId) {
- if (ArrayUtils.contains(INDEXABLE_QUALIFIERS, qualifier)) {
- dao.index(resourceName, qualifier, resourceId, rootProjectId);
- }
- return this;
- }
-
- /**
- * Used only for the migration from a version less than 2.13.
- */
- public ResourceIndexer indexAll() {
- ResourceIndexerFilter filter = ResourceIndexerFilter.create()
- .setScopes(new String[]{Scopes.PROJECT, Scopes.FILE})
- .setQualifiers(INDEXABLE_QUALIFIERS);
- dao.index(filter);
- return this;
- }
-}
diff --git a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java
index 0aa11816fd6..8e737501011 100644
--- a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java
+++ b/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerDao.java
@@ -19,123 +19,174 @@
*/
package org.sonar.core.resource;
-import org.apache.commons.lang.ObjectUtils;
+import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.SqlSession;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
import org.sonar.core.persistence.MyBatis;
public class ResourceIndexerDao {
public static final int MINIMUM_KEY_SIZE = 3;
+ // The scopes and qualifiers that are not in the following constants are not indexed at all.
+ // Directories and packages are explicitly excluded.
+ private static final String[] RENAMABLE_QUALIFIERS = {Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.VIEW, Qualifiers.SUBVIEW};
+ private static final String[] RENAMABLE_SCOPES = {Scopes.PROJECT};
+ private static final String[] NOT_RENAMABLE_QUALIFIERS = {Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE, Qualifiers.CLASS};
+ private static final String[] NOT_RENAMABLE_SCOPES = {Scopes.FILE};
+
private final MyBatis mybatis;
public ResourceIndexerDao(MyBatis mybatis) {
this.mybatis = mybatis;
}
- public ResourceIndexerDao index(String resourceName, String qualifier, int resourceId, int rootProjectId) {
- SqlSession sqlSession = mybatis.openSession();
+ /**
+ * This method is reentrant. It can be executed even if the project is already indexed.
+ */
+ public ResourceIndexerDao indexProject(final int rootProjectId) {
+ SqlSession session = mybatis.openSession(ExecutorType.BATCH);
try {
- ResourceDto resource = new ResourceDto()
- .setId(resourceId)
- .setQualifier(qualifier)
- .setName(resourceName)
- .setRootId(rootProjectId);
- index(resource, sqlSession, true);
+ ResourceIndexerMapper mapper = session.getMapper(ResourceIndexerMapper.class);
+ doIndexProject(rootProjectId, session, mapper);
+ session.commit();
+ return this;
} finally {
- sqlSession.close();
+ session.close();
}
- return this;
}
-
- public ResourceIndexerDao index(ResourceIndexerFilter filter) {
- final SqlSession sqlSession = mybatis.openSession(ExecutorType.BATCH);
+ /**
+ * This method is reentrant. It can be executed even if some projects are already indexed.
+ */
+ public ResourceIndexerDao indexProjects() {
+ final SqlSession session = mybatis.openSession(ExecutorType.BATCH);
try {
- sqlSession.select("selectResourcesToIndex", filter, new ResultHandler() {
+ final ResourceIndexerMapper mapper = session.getMapper(ResourceIndexerMapper.class);
+ session.select("selectRootProjectIds", /* workaround to get booleans */ResourceIndexerFilter.create(), new ResultHandler() {
public void handleResult(ResultContext context) {
- ResourceDto resource = (ResourceDto) context.getResultObject();
-
- // The column PROJECTS.ROOT_ID references the module but not the root project in a multi-modules project.
- boolean correctRootProjectId = false;
-
- index(resource, sqlSession, correctRootProjectId);
+ Integer rootProjectId = (Integer) context.getResultObject();
+ doIndexProject(rootProjectId, session, mapper);
+ session.commit();
}
});
+ return this;
+
} finally {
- sqlSession.close();
+ session.close();
}
- return this;
}
- void index(ResourceDto resource, SqlSession session, boolean correctProjectRootId) {
- String name = resource.getName();
- if (StringUtils.isBlank(name) || resource.getId() == null) {
- return;
- }
+ private void doIndexProject(int rootProjectId, SqlSession session, final ResourceIndexerMapper mapper) {
+ // non indexed resources
+ ResourceIndexerFilter filter = ResourceIndexerFilter.create()
+ .setNonIndexedOnly(true)
+ .setQualifiers(NOT_RENAMABLE_QUALIFIERS)
+ .setScopes(NOT_RENAMABLE_SCOPES)
+ .setRootProjectId(rootProjectId);
+
+ session.select("selectResources", filter, new ResultHandler() {
+ public void handleResult(ResultContext context) {
+ ResourceDto resource = (ResourceDto) context.getResultObject();
+ doIndex(resource, mapper);
+ }
+ });
+
+ // some resources can be renamed, so index must be regenerated
+ // -> delete existing rows and create them again
+ filter = ResourceIndexerFilter.create()
+ .setNonIndexedOnly(false)
+ .setQualifiers(RENAMABLE_QUALIFIERS)
+ .setScopes(RENAMABLE_SCOPES)
+ .setRootProjectId(rootProjectId);
+
+ session.select("selectResources", filter, new ResultHandler() {
+ public void handleResult(ResultContext context) {
+ ResourceDto resource = (ResourceDto) context.getResultObject();
+
+ mapper.deleteByResourceId(resource.getId());
+ doIndex(resource, mapper);
+ }
+ });
+ }
- String key = toKey(name);
- if (key.length() >= MINIMUM_KEY_SIZE) {
- ResourceIndexerMapper mapper = session.getMapper(ResourceIndexerMapper.class);
- boolean toBeIndexed = sanitizeIndex(resource, key, mapper);
- if (toBeIndexed) {
-
- ResourceIndexDto dto = new ResourceIndexDto()
- .setResourceId(resource.getId())
- .setQualifier(resource.getQualifier())
- .setRootProjectId(loadRootProjectId(resource, mapper, correctProjectRootId))
- .setNameSize(name.length());
-
- for (int position = 0; position <= key.length() - MINIMUM_KEY_SIZE; position++) {
- dto.setPosition(position);
- dto.setKey(StringUtils.substring(key, position));
- mapper.insert(dto);
- }
- session.commit();
+ void doIndex(ResourceDto resource, ResourceIndexerMapper mapper) {
+ String key = nameToKey(resource.getName());
+ if (key.length() >= MINIMUM_KEY_SIZE) {
+ ResourceIndexDto dto = new ResourceIndexDto()
+ .setResourceId(resource.getId())
+ .setQualifier(resource.getQualifier())
+ .setRootProjectId(resource.getRootId())
+ .setNameSize(resource.getName().length());
+
+ for (int position = 0; position <= key.length() - MINIMUM_KEY_SIZE; position++) {
+ dto.setPosition(position);
+ dto.setKey(StringUtils.substring(key, position));
+ mapper.insert(dto);
}
}
}
- private Integer loadRootProjectId(ResourceDto resource, ResourceIndexerMapper mapper, boolean correctProjectRootId) {
- if (correctProjectRootId) {
- return resource.getRootId();
- }
- Integer rootId;
- if (resource.getRootId() != null) {
- ResourceDto root = mapper.selectRootId(resource.getRootId());
- if (root != null) {
- rootId = (Integer) ObjectUtils.defaultIfNull(root.getRootId(), root.getId());
- } else {
- rootId = resource.getRootId();
+ public boolean indexResource(int id, String name, String qualifier, int rootProjectId) {
+ boolean indexed = false;
+ if (isIndexableQualifier(qualifier)) {
+ SqlSession session = mybatis.openSession();
+ try {
+ String key = nameToKey(name);
+ if (key.length() >= MINIMUM_KEY_SIZE) {
+ indexed = true;
+ ResourceIndexerMapper mapper = session.getMapper(ResourceIndexerMapper.class);
+ boolean toBeIndexed = sanitizeIndex(id, key, mapper);
+ if (toBeIndexed) {
+ ResourceIndexDto dto = new ResourceIndexDto()
+ .setResourceId(id)
+ .setQualifier(qualifier)
+ .setRootProjectId(rootProjectId)
+ .setNameSize(name.length());
+
+ for (int position = 0; position <= key.length() - MINIMUM_KEY_SIZE; position++) {
+ dto.setPosition(position);
+ dto.setKey(StringUtils.substring(key, position));
+ mapper.insert(dto);
+ }
+ session.commit();
+ }
+ }
+ } finally {
+ session.close();
}
- } else {
- rootId = resource.getId();
}
- return rootId;
+ return indexed;
}
+
/**
* Return true if the resource must be indexed, false if the resource is already indexed.
* If the resource is indexed with a different key, then this index is dropped and the
* resource must be indexed again.
*/
- private boolean sanitizeIndex(ResourceDto resource, String key, ResourceIndexerMapper mapper) {
- ResourceIndexDto masterIndex = mapper.selectMasterIndexByResourceId(resource.getId());
+ private boolean sanitizeIndex(int resourceId, String key, ResourceIndexerMapper mapper) {
+ ResourceIndexDto masterIndex = mapper.selectMasterIndexByResourceId(resourceId);
if (masterIndex != null && !StringUtils.equals(key, masterIndex.getKey())) {
// resource has been renamed -> drop existing indexes
- mapper.deleteByResourceId(resource.getId());
+ mapper.deleteByResourceId(resourceId);
masterIndex = null;
}
return masterIndex == null;
}
- static String toKey(String input) {
- return StringUtils.lowerCase(input);
+ static String nameToKey(String input) {
+ return StringUtils.lowerCase(StringUtils.trimToEmpty(input));
+ }
+
+ static boolean isIndexableQualifier(String qualifier) {
+ return ArrayUtils.contains(RENAMABLE_QUALIFIERS, qualifier) || ArrayUtils.contains(NOT_RENAMABLE_QUALIFIERS, qualifier);
}
}
diff --git a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerFilter.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerFilter.java
index 73b2aea748b..a8a823078db 100644
--- a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerFilter.java
+++ b/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerFilter.java
@@ -20,9 +20,11 @@
package org.sonar.core.resource;
public final class ResourceIndexerFilter {
- private boolean enabled = true;
+ private boolean _true = true;
+ private Integer rootProjectId = null;
private String[] scopes = null;
private String[] qualifiers = null;
+ private boolean nonIndexedOnly=false;
private ResourceIndexerFilter() {
}
@@ -31,10 +33,6 @@ public final class ResourceIndexerFilter {
return new ResourceIndexerFilter();
}
- public boolean isEnabled() {
- return enabled;
- }
-
public String[] getScopes() {
return scopes;
}
@@ -52,4 +50,22 @@ public final class ResourceIndexerFilter {
this.qualifiers = qualifiers;
return this;
}
+
+ public Integer getRootProjectId() {
+ return rootProjectId;
+ }
+
+ public ResourceIndexerFilter setRootProjectId(Integer i) {
+ this.rootProjectId = i;
+ return this;
+ }
+
+ public boolean isNonIndexedOnly() {
+ return nonIndexedOnly;
+ }
+
+ public ResourceIndexerFilter setNonIndexedOnly(boolean b) {
+ this.nonIndexedOnly = b;
+ return this;
+ }
}
diff --git a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerMapper.java b/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerMapper.java
index b4d0ef63b0b..a9b044f23fa 100644
--- a/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerMapper.java
+++ b/sonar-core/src/main/java/org/sonar/core/resource/ResourceIndexerMapper.java
@@ -19,9 +19,9 @@
*/
package org.sonar.core.resource;
-public interface ResourceIndexerMapper {
+import java.util.List;
- ResourceDto selectRootId(int id);
+public interface ResourceIndexerMapper {
ResourceIndexDto selectMasterIndexByResourceId(int resourceId);
diff --git a/sonar-core/src/main/resources/org/sonar/core/resource/ResourceIndexerMapper.xml b/sonar-core/src/main/resources/org/sonar/core/resource/ResourceIndexerMapper.xml
index 4fcf08b84fd..fee6f471405 100644
--- a/sonar-core/src/main/resources/org/sonar/core/resource/ResourceIndexerMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/resource/ResourceIndexerMapper.xml
@@ -3,27 +3,47 @@
<mapper namespace="org.sonar.core.resource.ResourceIndexerMapper">
- <select id="selectResourcesToIndex" parameterType="map" resultType="Resource">
- select id, root_id as "rootId", name, scope, qualifier
- from projects
+ <!--
+ The column PROJECTS.ROOT_ID is not exact on multi-modules projects. The root id must
+ be loaded from the table SNAPSHOTS
+ -->
+ <select id="selectResources" parameterType="map" resultType="Resource">
+ select p.name as "name", p.id as "id", p.scope as "scope", p.qualifier as "qualifier", s.root_project_id as "rootId"
+ from projects p, snapshots s
<where>
- enabled=#{enabled}
- and copy_resource_id is null
- <if test="scopes != null">and scope in
+ p.enabled=#{_true}
+ and p.copy_resource_id is null
+ and p.id=s.project_id
+ and s.islast=#{_true}
+ <if test="scopes != null">
+ and p.scope in
<foreach item="scope" index="index" collection="scopes" open="(" separator="," close=")">#{scope}</foreach>
</if>
- <if test="qualifiers != null">and qualifier in
- <foreach item="qualifier" index="index" collection="qualifiers" open="(" separator="," close=")">#{qualifier}</foreach>
+ <if test="qualifiers != null">
+ and p.qualifier in
+ <foreach item="qualifier" index="index" collection="qualifiers" open="(" separator="," close=")">#{qualifier}
+ </foreach>
+ </if>
+ <if test="rootProjectId != null">
+ and s.root_project_id=#{rootProjectId}
+ </if>
+ <if test="nonIndexedOnly">
+ and not exists(select * from resource_index ri where ri.resource_id=p.id)
</if>
</where>
</select>
- <select id="selectRootId" parameterType="int" resultType="Resource">
- select id, root_id as "rootId"
- from projects
- where id=#{id}
+ <select id="selectRootProjectIds" parameterType="map" resultType="int">
+ select distinct root_project_id
+ from snapshots
+ where islast=#{_true}
+ and scope='PRJ'
+ and qualifier in ('TRK', 'VW', 'SVW')
</select>
+
+
+
<select id="selectMasterIndexByResourceId" parameterType="int" resultType="ResourceIndex">
select kee as "key", resource_id as "resourceId"
from resource_index
diff --git a/sonar-core/src/test/java/org/sonar/core/resource/ResourceIndexerDaoTest.java b/sonar-core/src/test/java/org/sonar/core/resource/ResourceIndexerDaoTest.java
index fba523f1efb..2426fdc9166 100644
--- a/sonar-core/src/test/java/org/sonar/core/resource/ResourceIndexerDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/resource/ResourceIndexerDaoTest.java
@@ -33,28 +33,28 @@ public class ResourceIndexerDaoTest extends DaoTestCase {
}
@Test
- public void shouldIndexSingleResource() {
- setupData("shouldIndexSingleResource");
+ public void shouldIndexResource() {
+ setupData("shouldIndexResource");
- dao.index("ZipUtils", "FIL", 10, 8);
+ dao.indexResource(10, "ZipUtils", "FIL", 8);
- checkTables("shouldIndexSingleResource", "resource_index");
+ checkTables("shouldIndexResource", "resource_index");
}
@Test
- public void shouldIndexAllResources() {
- setupData("shouldIndexAllResources");
+ public void shouldIndexProjects() {
+ setupData("shouldIndexProjects");
- dao.index(ResourceIndexerFilter.create());
+ dao.indexProjects();
- checkTables("shouldIndexAllResources", "resource_index");
+ checkTables("shouldIndexProjects", "resource_index");
}
@Test
public void shouldIndexMultiModulesProject() {
setupData("shouldIndexMultiModulesProject");
- dao.index(ResourceIndexerFilter.create());
+ dao.indexProject(1);
checkTables("shouldIndexMultiModulesProject", "resource_index");
}
@@ -63,7 +63,7 @@ public class ResourceIndexerDaoTest extends DaoTestCase {
public void shouldReindexProjectAfterRenaming() {
setupData("shouldReindexProjectAfterRenaming");
- dao.index(ResourceIndexerFilter.create());
+ dao.indexProject(1);
checkTables("shouldReindexProjectAfterRenaming", "resource_index");
}
diff --git a/sonar-core/src/test/java/org/sonar/core/resource/ResourceIndexerTest.java b/sonar-core/src/test/java/org/sonar/core/resource/ResourceIndexerTest.java
deleted file mode 100644
index 7e6d2e5fc0a..00000000000
--- a/sonar-core/src/test/java/org/sonar/core/resource/ResourceIndexerTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2011 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.resource;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.junit.Test;
-import org.sonar.api.resources.Qualifiers;
-
-import static org.mockito.Mockito.*;
-
-public class ResourceIndexerTest {
-
- @Test
- public void shouldNotIndexDirectories() {
- ResourceIndexerDao dao = mock(ResourceIndexerDao.class);
- ResourceIndexer indexer = new ResourceIndexer(dao);
- indexer.index("org.foo", Qualifiers.DIRECTORY, 12, 9);
-
- verifyZeroInteractions(dao);
- }
-
- @Test
- public void shouldIndexResource() {
- ResourceIndexerDao dao = mock(ResourceIndexerDao.class);
- ResourceIndexer indexer = new ResourceIndexer(dao);
- indexer.index("org.foo.Bar", Qualifiers.FILE, 12, 9);
-
- verify(dao).index("org.foo.Bar", Qualifiers.FILE, 12, 9);
- }
-
- @Test
- public void shouldIndexAll() {
- ResourceIndexerDao dao = mock(ResourceIndexerDao.class);
- ResourceIndexer indexer = new ResourceIndexer(dao);
- indexer.indexAll();
-
- verify(dao).index(argThat(new BaseMatcher<ResourceIndexerFilter>() {
- public boolean matches(Object o) {
- ResourceIndexerFilter filter = (ResourceIndexerFilter) o;
- return filter.isEnabled() && filter.getScopes().length == 2 && filter.getQualifiers().length == ResourceIndexer.INDEXABLE_QUALIFIERS.length;
- }
-
- public void describeTo(Description description) {
- }
- }));
- }
-}
diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexAllResources.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexAllResources.xml
deleted file mode 100644
index 66686dff07a..00000000000
--- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexAllResources.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<dataset>
-
- <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
- root_id="[null]"
- description="[null]"
- enabled="[true]" language="java" copy_resource_id="[null]"/>
-
- <projects long_name="org.struts.RequestContext" id="3" scope="FIL" qualifier="FIL" kee="org.struts:struts:org.struts.RequestContext"
- name="RequestContext" root_id="1"
- description="[null]"
- enabled="[true]" language="java" copy_resource_id="[null]"/>
-
-</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject-result.xml
index 0bcc35f398b..953290805fe 100644
--- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject-result.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject-result.xml
@@ -1,6 +1,6 @@
<dataset>
- <!-- project "struts" -> module "struts-core" -> file "RequestContext" -->
+ <!-- project "struts" -> module "struts-core" -> package org.struts -> file "RequestContext" -->
<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
root_id="[null]"
description="[null]"
@@ -11,14 +11,39 @@
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]"/>
- <projects long_name="org.struts.RequestContext" id="3" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:org.struts.RequestContext"
+ <!-- note that the root_id of package/file is wrong. It references the module but not the root project -->
+ <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="org.struts:struts-core:org.struts"
+ name="org.struts" root_id="2"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]"/>
+
+ <projects long_name="org.struts.RequestContext" id="4" scope="CLA" qualifier="CLA"
+ kee="org.struts:struts-core:org.struts.RequestContext"
name="RequestContext" root_id="2"
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]"/>
+ <snapshots id="1" islast="[true]" root_project_id="1" project_id="1"/>
+ <snapshots id="2" islast="[true]" root_project_id="1" project_id="2"/>
+ <snapshots id="3" islast="[true]" root_project_id="1" project_id="3"/>
+ <snapshots id="4" islast="[true]" root_project_id="1" project_id="4"/>
<!-- The major goal is to test root_project_id -->
+ <!-- RequestContext -->
+ <resource_index kee="requestcontext" position="0" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="equestcontext" position="1" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="questcontext" position="2" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="uestcontext" position="3" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="estcontext" position="4" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="stcontext" position="5" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="tcontext" position="6" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="context" position="7" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="ontext" position="8" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="ntext" position="9" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="text" position="10" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="ext" position="11" name_size="14" resource_id="4" root_project_id="1" qualifier="CLA"/>
+
<!-- Struts -->
<resource_index kee="struts" position="0" name_size="6" resource_id="1" root_project_id="1" qualifier="TRK"/>
<resource_index kee="truts" position="1" name_size="6" resource_id="1" root_project_id="1" qualifier="TRK"/>
@@ -36,17 +61,5 @@
<resource_index kee="core" position="7" name_size="11" resource_id="2" root_project_id="1" qualifier="BRC"/>
<resource_index kee="ore" position="8" name_size="11" resource_id="2" root_project_id="1" qualifier="BRC"/>
- <!-- RequestContext -->
- <resource_index kee="requestcontext" position="0" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="equestcontext" position="1" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="questcontext" position="2" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="uestcontext" position="3" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="estcontext" position="4" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="stcontext" position="5" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="tcontext" position="6" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="context" position="7" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="ontext" position="8" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="ntext" position="9" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="text" position="10" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="ext" position="11" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
+
</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject.xml
index 3fd51854a75..18ef94a4616 100644
--- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexMultiModulesProject.xml
@@ -1,6 +1,6 @@
<dataset>
- <!-- project "struts" -> module "struts-core" -> file "RequestContext" -->
+ <!-- project "struts" -> module "struts-core" -> package org.struts -> file "RequestContext" -->
<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
root_id="[null]"
description="[null]"
@@ -11,9 +11,20 @@
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]"/>
- <projects long_name="org.struts.RequestContext" id="3" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:org.struts.RequestContext"
+ <!-- note that the root_id of package/file is wrong. It references the module but not the root project -->
+ <projects long_name="org.struts" id="3" scope="DIR" qualifier="PAC" kee="org.struts:struts-core:org.struts"
+ name="org.struts" root_id="2"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]"/>
+
+ <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="CLA"
+ kee="org.struts:struts-core:org.struts.RequestContext"
name="RequestContext" root_id="2"
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]"/>
+ <snapshots id="1" islast="[true]" root_project_id="1" project_id="1"/>
+ <snapshots id="2" islast="[true]" root_project_id="1" project_id="2"/>
+ <snapshots id="3" islast="[true]" root_project_id="1" project_id="3"/>
+ <snapshots id="4" islast="[true]" root_project_id="1" project_id="4"/>
</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexAllResources-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexProjects-result.xml
index 2f35b67259d..dcdcec48803 100644
--- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexAllResources-result.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexProjects-result.xml
@@ -1,32 +1,46 @@
<dataset>
+ <!-- project -->
<projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
root_id="[null]"
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]"/>
- <projects long_name="org.struts.RequestContext" id="3" scope="FIL" qualifier="FIL" kee="org.struts:struts:org.struts.RequestContext"
+ <!-- directory -->
+ <projects long_name="org.struts" id="2" scope="DIR" qualifier="PAC" kee="org.struts:struts:org.struts"
+ name="org.struts" root_id="1"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]"/>
+
+ <!-- file -->
+ <projects long_name="org.struts.RequestContext" id="3" scope="CLA" qualifier="CLA"
+ kee="org.struts:struts:org.struts.RequestContext"
name="RequestContext" root_id="1"
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]"/>
+ <snapshots id="1" islast="[true]" root_project_id="1" project_id="1" scope="PRJ" qualifier="TRK"/>
+ <snapshots id="2" islast="[true]" root_project_id="1" project_id="2" scope="DIR" qualifier="PAC"/>
+ <snapshots id="3" islast="[true]" root_project_id="1" project_id="3" scope="CLA" qualifier="CLA"/>
+
+ <!-- RequestContext -->
+ <resource_index kee="requestcontext" position="0" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="equestcontext" position="1" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="questcontext" position="2" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="uestcontext" position="3" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="estcontext" position="4" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="stcontext" position="5" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="tcontext" position="6" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="context" position="7" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="ontext" position="8" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="ntext" position="9" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="text" position="10" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+ <resource_index kee="ext" position="11" name_size="14" resource_id="3" root_project_id="1" qualifier="CLA"/>
+
<!-- Struts -->
<resource_index kee="struts" position="0" name_size="6" resource_id="1" root_project_id="1" qualifier="TRK"/>
<resource_index kee="truts" position="1" name_size="6" resource_id="1" root_project_id="1" qualifier="TRK"/>
<resource_index kee="ruts" position="2" name_size="6" resource_id="1" root_project_id="1" qualifier="TRK"/>
<resource_index kee="uts" position="3" name_size="6" resource_id="1" root_project_id="1" qualifier="TRK"/>
- <!-- RequestContext -->
- <resource_index kee="requestcontext" position="0" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="equestcontext" position="1" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="questcontext" position="2" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="uestcontext" position="3" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="estcontext" position="4" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="stcontext" position="5" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="tcontext" position="6" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="context" position="7" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="ontext" position="8" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="ntext" position="9" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="text" position="10" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
- <resource_index kee="ext" position="11" name_size="14" resource_id="3" root_project_id="1" qualifier="FIL"/>
</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexProjects.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexProjects.xml
new file mode 100644
index 00000000000..4d463454340
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexProjects.xml
@@ -0,0 +1,24 @@
+<dataset>
+
+ <!-- project -->
+ <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+ root_id="[null]"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]"/>
+
+ <!-- directory -->
+ <projects long_name="org.struts" id="2" scope="DIR" qualifier="PAC" kee="org.struts:struts:org.struts"
+ name="org.struts" root_id="1"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]"/>
+
+ <!-- file -->
+ <projects long_name="org.struts.RequestContext" id="3" scope="FIL" qualifier="CLA" kee="org.struts:struts:org.struts.RequestContext"
+ name="RequestContext" root_id="1"
+ description="[null]"
+ enabled="[true]" language="java" copy_resource_id="[null]"/>
+
+ <snapshots id="1" islast="[true]" root_project_id="1" project_id="1" scope="PRJ" qualifier="TRK" />
+ <snapshots id="2" islast="[true]" root_project_id="1" project_id="2" scope="DIR" qualifier="PAC"/>
+ <snapshots id="3" islast="[true]" root_project_id="1" project_id="3" scope="FIL" qualifier="CLA"/>
+</dataset>
diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexSingleResource-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexResource-result.xml
index f4cf0805ede..f4cf0805ede 100644
--- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexSingleResource-result.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexResource-result.xml
diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexSingleResource.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexResource.xml
index 5a4a28b7df3..5a4a28b7df3 100644
--- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexSingleResource.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldIndexResource.xml
diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming-result.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming-result.xml
index 6523767aa7c..cda14af38a3 100644
--- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming-result.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming-result.xml
@@ -5,6 +5,7 @@
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]"/>
+ <snapshots id="1" islast="[true]" root_project_id="1" project_id="1" scope="PRJ" qualifier="TRK"/>
<resource_index kee="apache struts" position="0" name_size="13" resource_id="1" root_project_id="1" qualifier="TRK"/>
<resource_index kee="pache struts" position="1" name_size="13" resource_id="1" root_project_id="1" qualifier="TRK"/>
diff --git a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming.xml b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming.xml
index 1c5531156ba..0af2532f6b7 100644
--- a/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/resource/ResourceIndexerDaoTest/shouldReindexProjectAfterRenaming.xml
@@ -5,6 +5,8 @@
description="[null]"
enabled="[true]" language="java" copy_resource_id="[null]"/>
+ <snapshots id="1" islast="[true]" root_project_id="1" project_id="1" scope="PRJ" qualifier="TRK"/>
+
<!-- the index is on the old name "Struts" but not on "Apache Struts -->
<resource_index kee="struts" position="0" name_size="6" resource_id="1" root_project_id="1" qualifier="TRK"/>
<resource_index kee="truts" position="1" name_size="6" resource_id="1" root_project_id="1" qualifier="TRK"/>
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 492e5090f0c..23c2b4cca1a 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
@@ -44,7 +44,6 @@ import org.sonar.core.persistence.DatabaseMigrator;
import org.sonar.core.persistence.DefaultDatabase;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.qualitymodel.DefaultModelFinder;
-import org.sonar.core.resource.ResourceIndexer;
import org.sonar.core.rule.DefaultRuleFinder;
import org.sonar.core.user.DefaultUserFinder;
import org.sonar.jpa.dao.DaoFacade;
@@ -135,7 +134,6 @@ public final class Platform {
rootContainer.addSingleton(EmbeddedDatabaseFactory.class);
rootContainer.addSingleton(DefaultDatabase.class);
rootContainer.addSingleton(MyBatis.class);
- rootContainer.addSingleton(ResourceIndexer.class); // for the migration 241
rootContainer.addSingleton(DefaultDatabaseConnector.class);
rootContainer.addSingleton(DefaultServerUpgradeStatus.class);
rootContainer.addSingleton(DatabaseMigrator.class);
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 927defeac4c..ed5ec2f7fa2 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
@@ -36,7 +36,7 @@ import org.sonar.api.web.*;
import org.sonar.core.i18n.RuleI18nManager;
import org.sonar.core.persistence.Database;
import org.sonar.core.persistence.DatabaseMigrator;
-import org.sonar.core.resource.ResourceIndexer;
+import org.sonar.core.resource.ResourceIndexerDao;
import org.sonar.markdown.Markdown;
import org.sonar.server.configuration.Backup;
import org.sonar.server.configuration.ProfilesManager;
@@ -368,8 +368,8 @@ public final class JRubyFacade {
return i18n.getJsDictionnary(rubyLocale);
}
- public void indexResources() {
- getContainer().getComponentByType(ResourceIndexer.class).indexAll();
+ public void indexProjects() {
+ getContainer().getComponentByType(ResourceIndexerDao.class).indexProjects();
}
public void logError(String message) {
diff --git a/sonar-server/src/main/webapp/WEB-INF/db/migrate/241_index_resources.rb b/sonar-server/src/main/webapp/WEB-INF/db/migrate/241_index_projects.rb
index d0e43896e5a..ace26b6fc5b 100644
--- a/sonar-server/src/main/webapp/WEB-INF/db/migrate/241_index_resources.rb
+++ b/sonar-server/src/main/webapp/WEB-INF/db/migrate/241_index_projects.rb
@@ -23,10 +23,10 @@
#
# Sonar 2.13
#
-class IndexResources < ActiveRecord::Migration
+class IndexProjects < ActiveRecord::Migration
def self.up
- Java::OrgSonarServerUi::JRubyFacade.getInstance().indexResources()
+ Java::OrgSonarServerUi::JRubyFacade.getInstance().indexProjects()
end
end