From b5eb47872b34aa9d017dca62abfe49b2fd7af61b Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Wed, 17 Apr 2013 10:35:23 +0200 Subject: [PATCH] SONAR-3893 use persistent map for syntax and symbol highlighting --- .../java/org/sonar/batch/index/Cache.java | 118 +++++++++++++++++- .../sonar/batch/index/ComponentDataCache.java | 52 ++++++++ .../batch/index/ComponentDataPersister.java | 58 +++++++++ .../SymbolDataCache.java => index/Data.java} | 13 +- .../org/sonar/batch/index/SnapshotCache.java | 6 + .../StringData.java} | 24 +++- .../sonar/batch/scan/ModuleScanContainer.java | 2 - .../batch/scan/ProjectScanContainer.java | 70 ++++++----- .../scan/source/DefaultHighlightable.java | 19 +-- .../scan/source/DefaultSymbolPerspective.java | 10 +- .../scan/source/HighlightableBuilder.java | 7 +- .../batch/scan/source/SourceDataCache.java | 45 ------- .../scan/source/SourceDataPersister.java | 67 ---------- .../scan/source/SymbolDataRepository.java | 30 +++-- .../scan/source/SymbolPerspectiveBuilder.java | 9 +- .../source/SyntaxHighlightingRuleSet.java | 20 +-- .../org/sonar/batch/bootstrapper/logback.xml | 3 + .../resources/org/sonar/batch/logback.xml | 4 + .../java/org/sonar/batch/index/CacheTest.java | 59 ++++++++- .../batch/index/ComponentDataCacheTest.java | 85 +++++++++++++ .../index/ComponentDataPersisterTest.java | 64 ++++++++++ .../scan/source/DefaultHighlightableTest.java | 18 +-- .../source/DefaultSymbolPerspectiveTest.java | 12 +- .../scan/source/HighlightableBuilderTest.java | 3 +- .../scan/source/SourceDataPersisterTest.java | 95 -------------- .../scan/source/SymbolDataRepositoryTest.java | 4 +- .../source/SymbolPerspectiveBuilderTest.java | 7 +- .../source/SyntaxHighlightingRuleSetTest.java | 12 +- .../should_persist_component_data-result.xml | 5 + .../should_persist_component_data.xml | 4 + 30 files changed, 599 insertions(+), 326 deletions(-) create mode 100644 sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java create mode 100644 sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataPersister.java rename sonar-batch/src/main/java/org/sonar/batch/{scan/source/SymbolDataCache.java => index/Data.java} (79%) rename sonar-batch/src/main/java/org/sonar/batch/{scan/source/SyntaxHighlightingCache.java => index/StringData.java} (71%) delete mode 100644 sonar-batch/src/main/java/org/sonar/batch/scan/source/SourceDataCache.java delete mode 100644 sonar-batch/src/main/java/org/sonar/batch/scan/source/SourceDataPersister.java create mode 100644 sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java create mode 100644 sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataPersisterTest.java delete mode 100644 sonar-batch/src/test/java/org/sonar/batch/scan/source/SourceDataPersisterTest.java create mode 100644 sonar-batch/src/test/resources/org/sonar/batch/index/ComponentDataPersisterTest/should_persist_component_data-result.xml create mode 100644 sonar-batch/src/test/resources/org/sonar/batch/index/ComponentDataPersisterTest/should_persist_component_data.xml diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/Cache.java b/sonar-batch/src/main/java/org/sonar/batch/index/Cache.java index 4bd6b3bf0a1..79425b0e546 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/Cache.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/Cache.java @@ -23,18 +23,27 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.persistit.Exchange; import com.persistit.Key; +import com.persistit.exception.PersistitException; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; import java.io.Serializable; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Set; /** + * + *

* This cache is not thread-safe, due to direct usage of {@link com.persistit.Exchange} + *

*/ public class Cache { private static final String DEFAULT_GROUP = "_"; + // TODO improve exception messages by using this cache name private final String name; private final Exchange exchange; @@ -187,11 +196,11 @@ public class Cache { List values = Lists.newLinkedList(); exchange.clear(); Exchange iteratorExchange = new Exchange(exchange); - - iteratorExchange.append(group); - iteratorExchange.append(Key.BEFORE); + iteratorExchange.append(group).append(Key.BEFORE); while (iteratorExchange.next(false)) { - values.add((V) iteratorExchange.getValue().get()); + if (iteratorExchange.getValue().isDefined()) { + values.add((V) iteratorExchange.getValue().get()); + } } return values; } catch (Exception e) { @@ -217,4 +226,105 @@ public class Cache { throw new IllegalStateException("Fail to get cache values", e); } } + + public Set groups() { + try { + Set groups = Sets.newLinkedHashSet(); + exchange.clear(); + Exchange iteratorExchange = new Exchange(exchange); + iteratorExchange.append(Key.BEFORE); + while (iteratorExchange.next(false)) { + groups.add(iteratorExchange.getKey().decodeString()); + } + return groups; + } catch (Exception e) { + throw new IllegalStateException("Fail to get cache values", e); + } + } + + public Iterable> entries() { + exchange.clear().to(Key.BEFORE); + return new EntryIterable(new Exchange(exchange), true); + } + + public Iterable> entries(String group) { + exchange.clear().append(group).append(Key.BEFORE); + return new EntryIterable(new Exchange(exchange), false); + } + + private static class EntryIterable implements Iterable> { + private final EntryIterator it; + + private EntryIterable(Exchange exchange, boolean deep) { + it = new EntryIterator(exchange, deep); + } + + @Override + public Iterator> iterator() { + return it; + } + } + + private static class EntryIterator implements Iterator> { + private final Exchange exchange; + private final boolean deep; + + private EntryIterator(Exchange exchange, boolean deep) { + this.exchange = exchange; + this.deep = deep; + } + + @Override + public boolean hasNext() { + try { + return exchange.next(deep); + } catch (PersistitException e) { + throw new IllegalStateException(e); + } + } + + @Override + public Entry next() { + Serializable value = null; + if (exchange.getValue().isDefined()) { + value = (Serializable) exchange.getValue().get(); + } + Key key = exchange.getKey(); + return new Entry(key.indexTo(-2).decodeString(), key.indexTo(-1).decodeString(), value); + } + + @Override + public void remove() { + } + } + + public static class Entry { + private final String group; + private final String key; + private final T value; + + Entry(String group, String key, T value) { + this.group = group; + this.key = key; + this.value = value; + } + + public String group() { + return group; + } + + public String key() { + return key; + } + + @CheckForNull + public T value() { + return value; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java b/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java new file mode 100644 index 00000000000..efdd17ffa85 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java @@ -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.batch.index; + +import org.sonar.api.BatchComponent; + +public class ComponentDataCache implements BatchComponent { + private final Cache cache; + + public ComponentDataCache(Caches caches) { + cache = caches.createCache("componentData"); + } + + public ComponentDataCache setData(String componentKey, String dataType, D data) { + cache.put(componentKey, dataType, data); + return this; + } + + public ComponentDataCache setStringData(String componentKey, String dataType, String data) { + return setData(componentKey, dataType, new StringData(data)); + } + + public D getData(String componentKey, String dataType) { + return (D) cache.get(componentKey, dataType); + } + + public String getStringData(String componentKey, String dataType) { + Data data = (Data) cache.get(componentKey, dataType); + return data==null ? null : ((StringData)data).data(); + } + + public Iterable> entries(String componentKey) { + return cache.entries(componentKey); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataPersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataPersister.java new file mode 100644 index 00000000000..98949e5f0bb --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataPersister.java @@ -0,0 +1,58 @@ +/* + * 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.batch.index; + +import org.sonar.api.database.model.Snapshot; +import org.sonar.core.source.jdbc.SnapshotDataDao; +import org.sonar.core.source.jdbc.SnapshotDataDto; + +import java.util.Map; + +public class ComponentDataPersister implements ScanPersister { + private final ComponentDataCache data; + private final SnapshotCache snapshots; + private final SnapshotDataDao dao; + + public ComponentDataPersister(ComponentDataCache data, SnapshotCache snapshots, SnapshotDataDao dao) { + this.data = data; + this.snapshots = snapshots; + this.dao = dao; + } + + @Override + public void persist() { + for (Map.Entry componentEntry : snapshots.snapshots()) { + String componentKey = componentEntry.getKey(); + Snapshot snapshot = componentEntry.getValue(); + for (Cache.Entry dataEntry : data.entries(componentKey)) { + if (dataEntry.value() != null) { + SnapshotDataDto dto = new SnapshotDataDto(); + dto.setSnapshotId(snapshot.getId()); + dto.setResourceId(snapshot.getResourceId()); + dto.setDataType(dataEntry.key()); + dto.setData(dataEntry.value().writeString()); + + // TODO bulk insert + dao.insert(dto); + } + } + } + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolDataCache.java b/sonar-batch/src/main/java/org/sonar/batch/index/Data.java similarity index 79% rename from sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolDataCache.java rename to sonar-batch/src/main/java/org/sonar/batch/index/Data.java index 0608659645d..6013db70ccc 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolDataCache.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/Data.java @@ -17,15 +17,14 @@ * License along with Sonar; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 */ +package org.sonar.batch.index; -package org.sonar.batch.scan.source; +import java.io.Serializable; -import org.sonar.core.source.jdbc.SnapshotDataDto; +public interface Data extends Serializable { -public class SymbolDataCache extends SourceDataCache { + String writeString(); + + void readString(String s); - @Override - public String getDataType() { - return SnapshotDataDto.SYMBOL; - } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/SnapshotCache.java b/sonar-batch/src/main/java/org/sonar/batch/index/SnapshotCache.java index 4b687f03435..611cb9e5a06 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/SnapshotCache.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/SnapshotCache.java @@ -24,7 +24,9 @@ import com.google.common.collect.Maps; import org.sonar.api.BatchComponent; import org.sonar.api.database.model.Snapshot; +import java.util.Collection; import java.util.Map; +import java.util.Set; public class SnapshotCache implements BatchComponent { // snapshots by component key @@ -39,4 +41,8 @@ public class SnapshotCache implements BatchComponent { snapshots.put(componentKey, snapshot); return this; } + + public Set> snapshots() { + return snapshots.entrySet(); + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SyntaxHighlightingCache.java b/sonar-batch/src/main/java/org/sonar/batch/index/StringData.java similarity index 71% rename from sonar-batch/src/main/java/org/sonar/batch/scan/source/SyntaxHighlightingCache.java rename to sonar-batch/src/main/java/org/sonar/batch/index/StringData.java index aa56cdb51a2..2f8a7c3adb4 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SyntaxHighlightingCache.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/StringData.java @@ -17,15 +17,29 @@ * License along with Sonar; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 */ +package org.sonar.batch.index; -package org.sonar.batch.scan.source; +public class StringData implements Data { + private String data = null; -import org.sonar.core.source.jdbc.SnapshotDataDto; + public StringData() { + } + + public StringData(String s) { + this.data = s; + } -public class SyntaxHighlightingCache extends SourceDataCache { + public String data() { + return data; + } + + @Override + public String writeString() { + return data; + } @Override - public String getDataType() { - return SnapshotDataDto.HIGHLIGHT_SYNTAX; + public void readString(String s) { + this.data = s; } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java index 2180eb20b4e..01878068c5a 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java @@ -124,8 +124,6 @@ public class ModuleScanContainer extends ComponentContainer { ModuleIssues.class, IssuableFactory.class, - HighlightableBuilder.class, - SymbolPerspectiveBuilder.class, ScanPerspectives.class ); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index ed9c5bba0c5..b7ecaa3d407 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -33,6 +33,8 @@ import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; import org.sonar.batch.bootstrap.ExtensionUtils; import org.sonar.batch.bootstrap.MetricProvider; +import org.sonar.batch.index.ComponentDataCache; +import org.sonar.batch.index.ComponentDataPersister; import org.sonar.batch.index.DefaultIndex; import org.sonar.batch.index.DefaultPersistenceManager; import org.sonar.batch.index.DefaultResourcePersister; @@ -51,9 +53,8 @@ import org.sonar.batch.phases.GraphPersister; import org.sonar.batch.profiling.PhasesSumUpTimeProfiler; import org.sonar.batch.scan.maven.FakeMavenPluginExecutor; import org.sonar.batch.scan.maven.MavenPluginExecutor; -import org.sonar.batch.scan.source.SourceDataPersister; -import org.sonar.batch.scan.source.SymbolDataCache; -import org.sonar.batch.scan.source.SyntaxHighlightingCache; +import org.sonar.batch.scan.source.HighlightableBuilder; +import org.sonar.batch.scan.source.SymbolPerspectiveBuilder; import org.sonar.core.component.ScanGraph; import org.sonar.core.notification.DefaultNotificationManager; import org.sonar.core.test.TestPlanBuilder; @@ -79,39 +80,42 @@ public class ProjectScanContainer extends ComponentContainer { private void addBatchComponents() { add( - DefaultResourceCreationLock.class, - DefaultPersistenceManager.class, - DependencyPersister.class, - EventPersister.class, - LinkPersister.class, - MeasurePersister.class, - MemoryOptimizer.class, - DefaultResourcePersister.class, - SourcePersister.class, - DefaultNotificationManager.class, - MetricProvider.class, - ProjectConfigurator.class, - DefaultIndex.class, - DefaultFileLinesContextFactory.class, - ProjectLock.class, - LastSnapshots.class, - SnapshotCache.class, + DefaultResourceCreationLock.class, + DefaultPersistenceManager.class, + DependencyPersister.class, + EventPersister.class, + LinkPersister.class, + MeasurePersister.class, + MemoryOptimizer.class, + DefaultResourcePersister.class, + SourcePersister.class, + DefaultNotificationManager.class, + MetricProvider.class, + ProjectConfigurator.class, + DefaultIndex.class, + DefaultFileLinesContextFactory.class, + ProjectLock.class, + LastSnapshots.class, + SnapshotCache.class, - ScanIssueActions.class, - DeprecatedViolations.class, - IssueCache.class, - IssuePersister.class, + ComponentDataCache.class, + ComponentDataPersister.class, - TestPlanPerspectiveLoader.class, - TestablePerspectiveLoader.class, - TestPlanBuilder.class, - TestableBuilder.class, - ScanGraph.create(), - GraphPersister.class, + ScanIssueActions.class, + DeprecatedViolations.class, + IssueCache.class, + IssuePersister.class, - SyntaxHighlightingCache.class, - SymbolDataCache.class, - SourceDataPersister.class); + TestPlanPerspectiveLoader.class, + TestablePerspectiveLoader.class, + TestPlanBuilder.class, + TestableBuilder.class, + ScanGraph.create(), + GraphPersister.class, + + HighlightableBuilder.class, + SymbolPerspectiveBuilder.class + ); } private void fixMavenExecutor() { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/DefaultHighlightable.java b/sonar-batch/src/main/java/org/sonar/batch/scan/source/DefaultHighlightable.java index 3129bcec164..d89d5bcb32b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/DefaultHighlightable.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/source/DefaultHighlightable.java @@ -21,6 +21,8 @@ package org.sonar.batch.scan.source; import org.sonar.api.component.Component; import org.sonar.api.scan.source.Highlightable; +import org.sonar.batch.index.ComponentDataCache; +import org.sonar.core.source.jdbc.SnapshotDataDto; /** * @since 3.6 @@ -28,13 +30,13 @@ import org.sonar.api.scan.source.Highlightable; public class DefaultHighlightable implements Highlightable { private final Component component; - private final SyntaxHighlightingCache syntaxHighlightingCache; - private final SyntaxHighlightingRuleSet.Builder highlightingRulesBuilder; + private final ComponentDataCache cache; + private final SyntaxHighlightingRuleSet.Builder builder; - public DefaultHighlightable(Component component, SyntaxHighlightingCache syntaxHighlightingCache) { + public DefaultHighlightable(Component component, ComponentDataCache cache) { this.component = component; - this.syntaxHighlightingCache = syntaxHighlightingCache; - this.highlightingRulesBuilder = SyntaxHighlightingRuleSet.builder(); + this.cache = cache; + this.builder = SyntaxHighlightingRuleSet.builder(); } @Override @@ -48,21 +50,20 @@ public class DefaultHighlightable implements Highlightable { } public SyntaxHighlightingRuleSet getHighlightingRules() { - return highlightingRulesBuilder.build(); + return builder.build(); } private class DefaultHighlightingBuilder implements HighlightingBuilder { @Override public HighlightingBuilder highlight(int startOffset, int endOffset, String typeOfText) { - highlightingRulesBuilder.registerHighlightingRule(startOffset, endOffset, typeOfText); + builder.registerHighlightingRule(startOffset, endOffset, typeOfText); return this; } @Override public void done() { - String serializedHighlightingRules = highlightingRulesBuilder.build().serializeAsString(); - syntaxHighlightingCache.registerSourceData(component().key(), serializedHighlightingRules); + cache.setStringData(component().key(), SnapshotDataDto.HIGHLIGHT_SYNTAX, builder.build().writeString()); } } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/DefaultSymbolPerspective.java b/sonar-batch/src/main/java/org/sonar/batch/scan/source/DefaultSymbolPerspective.java index 879e1dc9bae..db9fbdec6da 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/DefaultSymbolPerspective.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/source/DefaultSymbolPerspective.java @@ -23,15 +23,17 @@ package org.sonar.batch.scan.source; import org.sonar.api.component.Component; import org.sonar.api.scan.source.Symbol; import org.sonar.api.scan.source.SymbolPerspective; +import org.sonar.batch.index.ComponentDataCache; +import org.sonar.core.source.jdbc.SnapshotDataDto; public class DefaultSymbolPerspective implements SymbolPerspective { - private final SymbolDataCache symbolDataCache; + private final ComponentDataCache cache; private final Component component; private final SymbolDataRepository symbolDataRepository; - public DefaultSymbolPerspective(SymbolDataCache symbolDataCache, Component component, SymbolDataRepository symbolDataRepository) { - this.symbolDataCache = symbolDataCache; + public DefaultSymbolPerspective(ComponentDataCache cache, Component component, SymbolDataRepository symbolDataRepository) { + this.cache = cache; this.component = component; this.symbolDataRepository = symbolDataRepository; } @@ -59,7 +61,7 @@ public class DefaultSymbolPerspective implements SymbolPerspective { @Override public void end() { - symbolDataCache.registerSourceData(component().key(), symbolDataRepository.serializeAsString()); + cache.setStringData(component().key(), SnapshotDataDto.SYMBOL, symbolDataRepository.writeString()); } @Override diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/HighlightableBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/source/HighlightableBuilder.java index 7b891015d76..53c4d08310f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/HighlightableBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/source/HighlightableBuilder.java @@ -24,10 +24,12 @@ import org.sonar.api.component.Component; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; import org.sonar.api.scan.source.Highlightable; +import org.sonar.batch.index.ComponentDataCache; import org.sonar.core.component.PerspectiveBuilder; import org.sonar.core.component.ResourceComponent; import javax.annotation.CheckForNull; + import java.util.Set; /** @@ -36,10 +38,9 @@ import java.util.Set; public class HighlightableBuilder extends PerspectiveBuilder { private static final Set SUPPORTED_QUALIFIERS = ImmutableSet.of(Qualifiers.FILE, Qualifiers.CLASS, Qualifiers.UNIT_TEST_FILE); - private final SyntaxHighlightingCache cache; - + private final ComponentDataCache cache; - public HighlightableBuilder(SyntaxHighlightingCache cache) { + public HighlightableBuilder(ComponentDataCache cache) { super(Highlightable.class); this.cache = cache; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SourceDataCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan/source/SourceDataCache.java deleted file mode 100644 index 49f1a7af1e3..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SourceDataCache.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.batch.scan.source; - -import com.google.common.collect.Maps; -import org.sonar.api.BatchComponent; - -import java.util.Map; - -public abstract class SourceDataCache implements BatchComponent { - - protected Map sourceDataByComponent; - - protected SourceDataCache() { - sourceDataByComponent = Maps.newHashMap(); - } - - public void registerSourceData(String componentKey, String serializedData) { - sourceDataByComponent.put(componentKey, serializedData); - } - - public Map getSourceDataByComponent() { - return sourceDataByComponent; - } - - public abstract String getDataType(); -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SourceDataPersister.java b/sonar-batch/src/main/java/org/sonar/batch/scan/source/SourceDataPersister.java deleted file mode 100644 index 3e601200181..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SourceDataPersister.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.batch.scan.source; - -import org.sonar.api.database.model.Snapshot; -import org.sonar.batch.index.ScanPersister; -import org.sonar.batch.index.SnapshotCache; -import org.sonar.core.source.jdbc.SnapshotDataDao; -import org.sonar.core.source.jdbc.SnapshotDataDto; - -import java.util.Map; - -public class SourceDataPersister implements ScanPersister { - - private final SnapshotDataDao snapshotDataDao; - private final SourceDataCache[] sourceDataCache; - private final SnapshotCache snapshots; - - public SourceDataPersister(SnapshotDataDao snapshotDataDao, SourceDataCache[] sourceDataCache, SnapshotCache snapshots) { - this.snapshotDataDao = snapshotDataDao; - this.sourceDataCache = sourceDataCache; - this.snapshots = snapshots; - } - - @Override - public void persist() { - - for (SourceDataCache dataCache : sourceDataCache) { - persistDataCache(dataCache.getDataType(), dataCache.getSourceDataByComponent()); - } - } - - private void persistDataCache(String dataType, Map sourceDataByComponent) { - - for (Map.Entry componentData : sourceDataByComponent.entrySet()) { - - Snapshot snapshotForComponent = snapshots.get(componentData.getKey()); - - SnapshotDataDto snapshotDataDto = new SnapshotDataDto(); - if(snapshotForComponent != null) { - snapshotDataDto.setSnapshotId(snapshotForComponent.getId()); - snapshotDataDto.setResourceId(snapshotForComponent.getResourceId()); - snapshotDataDto.setDataType(dataType); - snapshotDataDto.setData(componentData.getValue()); - snapshotDataDao.insert(snapshotDataDto); - } - } - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolDataRepository.java b/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolDataRepository.java index 1e645d748b0..0568da81a33 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolDataRepository.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolDataRepository.java @@ -23,11 +23,12 @@ package org.sonar.batch.scan.source; import com.google.common.collect.Multimap; import com.google.common.collect.TreeMultimap; import org.sonar.api.scan.source.Symbol; +import org.sonar.batch.index.Data; import java.util.Collection; import java.util.Comparator; -public class SymbolDataRepository { +public class SymbolDataRepository implements Data { private static final String FIELD_SEPARATOR = ","; private static final String SYMBOL_SEPARATOR = ";"; @@ -43,29 +44,34 @@ public class SymbolDataRepository { } public void registerSymbolReference(Symbol symbol, int startOffset) { - if(startOffset >= symbol.getDeclarationStartOffset() && startOffset < symbol.getDeclarationEndOffset()) { + if (startOffset >= symbol.getDeclarationStartOffset() && startOffset < symbol.getDeclarationEndOffset()) { throw new UnsupportedOperationException("Cannot add reference overlapping the symbol declaration"); } referencesBySymbol.put(symbol, startOffset); } - public String serializeAsString() { - - StringBuilder serializedData = new StringBuilder(); + @Override + public String writeString() { + StringBuilder sb = new StringBuilder(); for (Symbol symbol : referencesBySymbol.keySet()) { - serializedData.append(symbol.getDeclarationStartOffset()) - .append(FIELD_SEPARATOR) - .append(symbol.getDeclarationEndOffset()); + sb.append(symbol.getDeclarationStartOffset()) + .append(FIELD_SEPARATOR) + .append(symbol.getDeclarationEndOffset()); Collection symbolReferences = referencesBySymbol.get(symbol); for (Integer symbolReference : symbolReferences) { - serializedData.append(FIELD_SEPARATOR).append(symbolReference); + sb.append(FIELD_SEPARATOR).append(symbolReference); } - serializedData.append(SYMBOL_SEPARATOR); + sb.append(SYMBOL_SEPARATOR); } - return serializedData.toString(); + return sb.toString(); + } + + @Override + public void readString(String s) { + throw new UnsupportedOperationException(); } @@ -80,7 +86,7 @@ public class SymbolDataRepository { @Override public int compare(Integer left, Integer right) { int result; - if(left != null & right != null) { + if (left != null & right != null) { result = left - right; } else { result = left == null ? -1 : 1; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolPerspectiveBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolPerspectiveBuilder.java index 26578cd0e45..f711062e98e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolPerspectiveBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/source/SymbolPerspectiveBuilder.java @@ -22,19 +22,20 @@ package org.sonar.batch.scan.source; import org.sonar.api.component.Component; import org.sonar.api.scan.source.SymbolPerspective; +import org.sonar.batch.index.ComponentDataCache; import org.sonar.core.component.PerspectiveBuilder; public class SymbolPerspectiveBuilder extends PerspectiveBuilder { - private final SymbolDataCache symbolDataCache; + private final ComponentDataCache cache; - public SymbolPerspectiveBuilder(SymbolDataCache symbolDataCache) { + public SymbolPerspectiveBuilder(ComponentDataCache cache) { super(SymbolPerspective.class); - this.symbolDataCache = symbolDataCache; + this.cache = cache; } @Override protected SymbolPerspective loadPerspective(Class perspectiveClass, Component component) { - return new DefaultSymbolPerspective(symbolDataCache, component, new SymbolDataRepository()); + return new DefaultSymbolPerspective(cache, component, new SymbolDataRepository()); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SyntaxHighlightingRuleSet.java b/sonar-batch/src/main/java/org/sonar/batch/scan/source/SyntaxHighlightingRuleSet.java index dd567ffbf92..8fe2650d0bd 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/source/SyntaxHighlightingRuleSet.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/source/SyntaxHighlightingRuleSet.java @@ -25,8 +25,10 @@ import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.Ordering; import org.slf4j.LoggerFactory; +import org.sonar.batch.index.Data; import javax.annotation.Nullable; + import java.util.Collection; import java.util.List; @@ -35,7 +37,7 @@ import static com.google.common.collect.Lists.newArrayList; /** * @since 3.6 */ -public class SyntaxHighlightingRuleSet { +public class SyntaxHighlightingRuleSet implements Data { private static final String FIELD_SEPARATOR = ","; private static final String RULE_SEPARATOR = ";"; @@ -103,13 +105,13 @@ public class SyntaxHighlightingRuleSet { return syntaxHighlightingRuleSet; } - public String serializeAsString() { - - StringBuilder serializedRules = new StringBuilder(); + @Override + public String writeString() { + StringBuilder sb = new StringBuilder(); List orderedRules = getOrderedHighlightingRules(); for (SyntaxHighlightingRule highlightingRule : orderedRules) { - serializedRules.append(highlightingRule.getStartPosition()) + sb.append(highlightingRule.getStartPosition()) .append(FIELD_SEPARATOR) .append(highlightingRule.getEndPosition()) .append(FIELD_SEPARATOR) @@ -117,12 +119,16 @@ public class SyntaxHighlightingRuleSet { .append(RULE_SEPARATOR); } - return serializedRules.toString(); + return sb.toString(); + } + + @Override + public void readString(String s) { + throw new UnsupportedOperationException(); } @VisibleForTesting protected List getOrderedHighlightingRules() { - Ordering ruleOrdering = new Ordering() { @Override public int compare(@Nullable SyntaxHighlightingRule left, diff --git a/sonar-batch/src/main/resources/org/sonar/batch/bootstrapper/logback.xml b/sonar-batch/src/main/resources/org/sonar/batch/bootstrapper/logback.xml index 08e4a0a3703..5fbe0ef32a8 100644 --- a/sonar-batch/src/main/resources/org/sonar/batch/bootstrapper/logback.xml +++ b/sonar-batch/src/main/resources/org/sonar/batch/bootstrapper/logback.xml @@ -48,6 +48,9 @@ + + + diff --git a/sonar-batch/src/main/resources/org/sonar/batch/logback.xml b/sonar-batch/src/main/resources/org/sonar/batch/logback.xml index 539320cd1b8..042b3ec145d 100644 --- a/sonar-batch/src/main/resources/org/sonar/batch/logback.xml +++ b/sonar-batch/src/main/resources/org/sonar/batch/logback.xml @@ -44,6 +44,10 @@ + + + + diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java index 975db7affe1..acc5ca95649 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.index; +import com.google.common.collect.Iterables; +import com.persistit.exception.PersistitException; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -106,7 +108,7 @@ public class CacheTest { @Test public void test_keyset_of_group() { - Cache cache = caches.createCache("issues"); + Cache cache = caches.createCache("measures"); cache.put("org/apache/struts/Action.java", "ncloc", 123f); cache.put("org/apache/struts/Action.java", "lines", 200f); cache.put("org/apache/struts/Filter.java", "coverage", 500f); @@ -116,7 +118,7 @@ public class CacheTest { @Test public void test_values_of_group() { - Cache cache = caches.createCache("issues"); + Cache cache = caches.createCache("measures"); cache.put("org/apache/struts/Action.java", "ncloc", 123f); cache.put("org/apache/struts/Action.java", "lines", 200f); cache.put("org/apache/struts/Filter.java", "lines", 500f); @@ -126,7 +128,7 @@ public class CacheTest { @Test public void test_values() { - Cache cache = caches.createCache("issues"); + Cache cache = caches.createCache("measures"); cache.put("ncloc", 123f); cache.put("lines", 200f); assertThat(cache.values()).containsOnly(123f, 200f); @@ -134,7 +136,7 @@ public class CacheTest { @Test public void test_all_values() { - Cache cache = caches.createCache("issues"); + Cache cache = caches.createCache("measures"); cache.put("org/apache/struts/Action.java", "ncloc", 123f); cache.put("org/apache/struts/Action.java", "lines", 200f); cache.put("org/apache/struts/Filter.java", "ncloc", 400f); @@ -142,4 +144,53 @@ public class CacheTest { assertThat(cache.allValues()).containsOnly(123f, 200f, 400f, 500f); } + + @Test + public void test_groups() { + Cache cache = caches.createCache("issues"); + assertThat(cache.groups()).isEmpty(); + + cache.put("org/apache/struts/Action.java", "ncloc", 123f); + cache.put("org/apache/struts/Action.java", "lines", 200f); + cache.put("org/apache/struts/Filter.java", "ncloc", 400f); + + assertThat(cache.groups()).containsOnly("org/apache/struts/Action.java", "org/apache/struts/Filter.java"); + } + + @Test + public void test_entries() throws PersistitException { + Cache cache = caches.createCache("issues"); + cache.put("org/apache/struts/Action.java", "ncloc", 123f); + cache.put("org/apache/struts/Action.java", "lines", 200f); + cache.put("org/apache/struts/Filter.java", "ncloc", 400f); + + Cache.Entry[] entries = Iterables.toArray(cache.entries(), Cache.Entry.class); + assertThat(entries).hasSize(3); + assertThat(entries[0].group()).isEqualTo("org/apache/struts/Action.java"); + assertThat(entries[0].key()).isEqualTo("lines"); + assertThat(entries[0].value()).isEqualTo(200f); + assertThat(entries[1].group()).isEqualTo("org/apache/struts/Action.java"); + assertThat(entries[1].key()).isEqualTo("ncloc"); + assertThat(entries[1].value()).isEqualTo(123f); + assertThat(entries[2].group()).isEqualTo("org/apache/struts/Filter.java"); + assertThat(entries[2].key()).isEqualTo("ncloc"); + assertThat(entries[2].value()).isEqualTo(400f); + } + + @Test + public void test_entries_of_group() throws PersistitException { + Cache cache = caches.createCache("issues"); + cache.put("org/apache/struts/Action.java", "ncloc", 123f); + cache.put("org/apache/struts/Action.java", "lines", 200f); + cache.put("org/apache/struts/Filter.java", "ncloc", 400f); + + Cache.Entry[] entries = Iterables.toArray(cache.entries("org/apache/struts/Action.java"), Cache.Entry.class); + assertThat(entries).hasSize(2); + assertThat(entries[0].group()).isEqualTo("org/apache/struts/Action.java"); + assertThat(entries[0].key()).isEqualTo("lines"); + assertThat(entries[0].value()).isEqualTo(200f); + assertThat(entries[1].group()).isEqualTo("org/apache/struts/Action.java"); + assertThat(entries[1].key()).isEqualTo("ncloc"); + assertThat(entries[1].value()).isEqualTo(123f); + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java new file mode 100644 index 00000000000..8092b3b683d --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java @@ -0,0 +1,85 @@ +/* + * 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.batch.index; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class ComponentDataCacheTest { + + Caches caches = new Caches(); + + @Before + public void start() { + caches.start(); + } + + @After + public void stop() { + caches.stop(); + } + + @Test + public void should_get_and_set_string_data() { + ComponentDataCache cache = new ComponentDataCache(caches); + cache.setStringData("org/struts/Action.java", "SYNTAX", "1:foo;3:bar"); + assertThat(cache.getStringData("org/struts/Action.java", "SYNTAX")).isEqualTo("1:foo;3:bar"); + assertThat(cache.getStringData("org/struts/Action.java", "OTHER")).isNull(); + assertThat(cache.getStringData("Other.java", "SYNTAX")).isNull(); + assertThat(cache.getStringData("Other.java", "OTHER")).isNull(); + } + + @Test + public void should_get_and_set_data() { + ComponentDataCache cache = new ComponentDataCache(caches); + cache.setData("org/struts/Action.java", "COUNT", new LongData(1234L)); + LongData count = cache.getData("org/struts/Action.java", "COUNT"); + assertThat(count.data()).isEqualTo(1234L); + } + + static class LongData implements Data { + + private long data; + + LongData() { + } + + LongData(long data) { + this.data = data; + } + + public long data() { + return data; + } + + @Override + public String writeString() { + return String.valueOf(data); + } + + @Override + public void readString(String s) { + data = Long.parseLong(s); + } + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataPersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataPersisterTest.java new file mode 100644 index 00000000000..f9387794072 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataPersisterTest.java @@ -0,0 +1,64 @@ +/* + * 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.batch.index; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.database.model.Snapshot; +import org.sonar.core.persistence.AbstractDaoTestCase; +import org.sonar.core.source.jdbc.SnapshotDataDao; + +public class ComponentDataPersisterTest extends AbstractDaoTestCase { + + SnapshotCache snapshots = new SnapshotCache(); + ComponentDataCache data; + Caches caches = new Caches(); + + @Before + public void start() { + caches.start(); + } + + @After + public void stop() { + caches.stop(); + } + + @Test + public void should_persist_component_data() throws Exception { + setupData("should_persist_component_data"); + Snapshot snapshot = new Snapshot(); + snapshot.setId(100); + snapshot.setResourceId(200); + snapshots.put("org/struts/Action.java", snapshot); + + data = new ComponentDataCache(caches); + data.setStringData("org/struts/Action.java", "SYMBOL", "content of symbol"); + data.setStringData("org/struts/Action.java", "SYNTAX", "content of syntax"); + data.setStringData("org/struts/Other.java", "SYMBOL", "unregistered component, should not be persisted"); + + SnapshotDataDao dataDao = new SnapshotDataDao(getMyBatis()); + ComponentDataPersister persister = new ComponentDataPersister(data, snapshots, dataDao); + persister.persist(); + + checkTables("should_persist_component_data", new String[]{"id", "created_at", "updated_at"}, "snapshot_data"); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/source/DefaultHighlightableTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/source/DefaultHighlightableTest.java index 3fb17eab3cb..e1f4b7d4066 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/source/DefaultHighlightableTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/source/DefaultHighlightableTest.java @@ -23,6 +23,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.component.Component; +import org.sonar.batch.index.ComponentDataCache; +import org.sonar.core.source.jdbc.SnapshotDataDto; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -36,7 +38,6 @@ public class DefaultHighlightableTest { @Test public void should_store_highlighting_rules() throws Exception { - DefaultHighlightable highlightablePerspective = new DefaultHighlightable(null, null); highlightablePerspective.newHighlighting().highlight(0, 10, "k").highlight(20, 30, "cppd"); @@ -45,18 +46,17 @@ public class DefaultHighlightableTest { @Test public void should_apply_registered_highlighting() throws Exception { - Component component = mock(Component.class); when(component.key()).thenReturn("myComponent"); - SyntaxHighlightingCache highlightingCache = mock(SyntaxHighlightingCache.class); + ComponentDataCache cache = mock(ComponentDataCache.class); - DefaultHighlightable highlightablePerspective = new DefaultHighlightable(component, highlightingCache); - highlightablePerspective.newHighlighting() - .highlight(0, 10, "k") - .highlight(20, 30, "cppd") - .done(); + DefaultHighlightable highlightable = new DefaultHighlightable(component, cache); + highlightable.newHighlighting() + .highlight(0, 10, "k") + .highlight(20, 30, "cppd") + .done(); - verify(highlightingCache).registerSourceData("myComponent", "0,10,k;20,30,cppd;"); + verify(cache).setStringData("myComponent", SnapshotDataDto.HIGHLIGHT_SYNTAX, "0,10,k;20,30,cppd;"); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/source/DefaultSymbolPerspectiveTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/source/DefaultSymbolPerspectiveTest.java index e1ce5d3540c..63dfc23eb9d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/source/DefaultSymbolPerspectiveTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/source/DefaultSymbolPerspectiveTest.java @@ -23,8 +23,12 @@ package org.sonar.batch.scan.source; import org.junit.Test; import org.sonar.api.component.Component; import org.sonar.api.scan.source.Symbol; +import org.sonar.batch.index.ComponentDataCache; +import org.sonar.core.source.jdbc.SnapshotDataDto; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class DefaultSymbolPerspectiveTest { @@ -32,7 +36,7 @@ public class DefaultSymbolPerspectiveTest { public void should_store_references_for_new_symbol() throws Exception { Component component = mock(Component.class); - SymbolDataCache cache = mock(SymbolDataCache.class); + ComponentDataCache cache = mock(ComponentDataCache.class); SymbolDataRepository symbolDataRepository = mock(SymbolDataRepository.class); DefaultSymbolPerspective symbolPerspective = new DefaultSymbolPerspective(cache, component, symbolDataRepository); @@ -51,7 +55,7 @@ public class DefaultSymbolPerspectiveTest { Component component = mock(Component.class); when(component.key()).thenReturn("myComponent"); - SymbolDataCache cache = mock(SymbolDataCache.class); + ComponentDataCache cache = mock(ComponentDataCache.class); DefaultSymbolPerspective symbolPerspective = new DefaultSymbolPerspective(cache, component, new SymbolDataRepository()); Symbol firstSymbol = symbolPerspective.newSymbol().setDeclaration(4, 8).build(); @@ -61,6 +65,6 @@ public class DefaultSymbolPerspectiveTest { symbolPerspective.end(); - verify(cache).registerSourceData("myComponent", "4,8,4,12,70;25,33,25,44,60,108;"); + verify(cache).setStringData("myComponent", SnapshotDataDto.SYMBOL, "4,8,4,12,70;25,33,25,44,60,108;"); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/source/HighlightableBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/source/HighlightableBuilderTest.java index 3b8009cd160..6a96e264c7f 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/source/HighlightableBuilderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/source/HighlightableBuilderTest.java @@ -24,6 +24,7 @@ import org.sonar.api.component.Component; import org.sonar.api.resources.File; import org.sonar.api.resources.Project; import org.sonar.api.scan.source.Highlightable; +import org.sonar.batch.index.ComponentDataCache; import org.sonar.core.component.ResourceComponent; import org.sonar.java.api.JavaClass; @@ -32,7 +33,7 @@ import static org.mockito.Mockito.mock; public class HighlightableBuilderTest { - SyntaxHighlightingCache cache = mock(SyntaxHighlightingCache.class); + ComponentDataCache cache = mock(ComponentDataCache.class); @Test public void should_load_default_perspective() throws Exception { diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/source/SourceDataPersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/source/SourceDataPersisterTest.java deleted file mode 100644 index c28ceb6fc7b..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/source/SourceDataPersisterTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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.batch.scan.source; - -import com.google.common.collect.Maps; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentMatcher; -import org.sonar.api.database.model.Snapshot; -import org.sonar.batch.index.SnapshotCache; -import org.sonar.core.source.jdbc.SnapshotDataDao; -import org.sonar.core.source.jdbc.SnapshotDataDto; - -import java.util.Map; - -import static org.mockito.Mockito.*; - -public class SourceDataPersisterTest { - - private SnapshotCache snapshots; - private SourceDataCache sourceDataCache; - private SnapshotDataDao snapshotDataDao; - - @Before - public void setUpInjectedObjects() { - snapshots = mock(SnapshotCache.class); - sourceDataCache = mock(SyntaxHighlightingCache.class); - snapshotDataDao = mock(SnapshotDataDao.class); - } - - @Test - public void should_persist_source_cache_data() throws Exception { - - final String componentKey = "component1"; - final String dataType = "myDataType"; - final String data = "source data for component 1"; - - Snapshot snapshotComponent1 = mock(Snapshot.class); - when(snapshotComponent1.getId()).thenReturn(1); - when(snapshotComponent1.getResourceId()).thenReturn(1); - - Map sourceData = Maps.newHashMap(); - sourceData.put(componentKey, data); - - when(sourceDataCache.getSourceDataByComponent()).thenReturn(sourceData); - when(sourceDataCache.getDataType()).thenReturn(dataType); - when(snapshots.get(componentKey)).thenReturn(snapshotComponent1); - - SourceDataPersister persister = new SourceDataPersister(snapshotDataDao, new SourceDataCache[]{sourceDataCache}, snapshots); - persister.persist(); - - verify(snapshotDataDao).insert(argThat(new ArgumentMatcher() { - @Override - public boolean matches(Object o) { - SnapshotDataDto insertedData = (SnapshotDataDto) o; - return insertedData.getSnapshotId() == 1 - && dataType.equals(insertedData.getDataType()) - && data.equals(insertedData.getData()); - } - })); - } - - @Test - public void should_ignore_components_without_snapshot() throws Exception { - - Map sourceData = Maps.newHashMap(); - sourceData.put("component1", "source data for component 1"); - - when(sourceDataCache.getSourceDataByComponent()).thenReturn(sourceData); - when(snapshots.get("component1")).thenReturn(null); - - SourceDataPersister persister = new SourceDataPersister(snapshotDataDao, new SourceDataCache[]{sourceDataCache}, snapshots); - persister.persist(); - - verify(snapshotDataDao, times(0)).insert(any(SnapshotDataDto.class)); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/source/SymbolDataRepositoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/source/SymbolDataRepositoryTest.java index c37e739d3d2..10f038f1039 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/source/SymbolDataRepositoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/source/SymbolDataRepositoryTest.java @@ -45,7 +45,7 @@ public class SymbolDataRepositoryTest { dataRepository.registerSymbolReference(secondSymbol, 124); dataRepository.registerSymbolReference(thirdSymbol, 70); - String serializedSymbolData = dataRepository.serializeAsString(); + String serializedSymbolData = dataRepository.writeString(); assertThat(serializedSymbolData).isEqualTo("10,20,10,32;55,62,55,70;84,92,84,124;"); } @@ -58,7 +58,7 @@ public class SymbolDataRepositoryTest { Symbol unusedSymbol = DefaultSymbol.builder(dataRepository).setDeclaration(10, 20).build(); dataRepository.registerSymbol(unusedSymbol); - String serializedSymbolData = dataRepository.serializeAsString(); + String serializedSymbolData = dataRepository.writeString(); assertThat(serializedSymbolData).isEqualTo("10,20,10;"); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/source/SymbolPerspectiveBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/source/SymbolPerspectiveBuilderTest.java index 9bc511866bd..9fdd9a0b760 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/source/SymbolPerspectiveBuilderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/source/SymbolPerspectiveBuilderTest.java @@ -24,19 +24,20 @@ import org.junit.Test; import org.sonar.api.component.Component; import org.sonar.api.component.Perspective; import org.sonar.api.scan.source.SymbolPerspective; +import org.sonar.batch.index.ComponentDataCache; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.mock; public class SymbolPerspectiveBuilderTest { + ComponentDataCache dataCache = mock(ComponentDataCache.class); + @Test public void should_load_perspective() throws Exception { - - SymbolDataCache symbolDataCache = mock(SymbolDataCache.class); Component component = mock(Component.class); - SymbolPerspectiveBuilder perspectiveBuilder = new SymbolPerspectiveBuilder(symbolDataCache); + SymbolPerspectiveBuilder perspectiveBuilder = new SymbolPerspectiveBuilder(dataCache); Perspective perspective = perspectiveBuilder.loadPerspective(SymbolPerspective.class, component); assertThat(perspective).isInstanceOf(SymbolPerspective.class); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/source/SyntaxHighlightingRuleSetTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/source/SyntaxHighlightingRuleSetTest.java index e6cddd2db4c..6aa60318884 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/source/SyntaxHighlightingRuleSetTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/source/SyntaxHighlightingRuleSetTest.java @@ -54,7 +54,7 @@ public class SyntaxHighlightingRuleSetTest { public void should_register_highlighting_rule() throws Exception { assertThat(highlightingRules.getSyntaxHighlightingRuleSet()).hasSize(6); } - + @Test public void should_order_by_start_then_end_offset() throws Exception { @@ -66,9 +66,9 @@ public class SyntaxHighlightingRuleSetTest { } @Test - public void should_serialize_rules() throws Exception { + public void should_serialize_rules_to_string() throws Exception { - String serializedRules = highlightingRules.serializeAsString(); + String serializedRules = highlightingRules.writeString(); assertThat(serializedRules).isEqualTo("0,10,cd;10,12,k;12,20,cd;24,38,k;24,65,cppd;42,50,k;"); } @@ -77,8 +77,8 @@ public class SyntaxHighlightingRuleSetTest { throwable.expect(UnsupportedOperationException.class); - SyntaxHighlightingRuleSet.Builder highlightingRuleSet = SyntaxHighlightingRuleSet.builder(); - highlightingRuleSet.registerHighlightingRule(0, 10, "k"); - highlightingRuleSet.registerHighlightingRule(8, 15, "k"); + SyntaxHighlightingRuleSet.Builder builder = SyntaxHighlightingRuleSet.builder(); + builder.registerHighlightingRule(0, 10, "k"); + builder.registerHighlightingRule(8, 15, "k"); } } diff --git a/sonar-batch/src/test/resources/org/sonar/batch/index/ComponentDataPersisterTest/should_persist_component_data-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/index/ComponentDataPersisterTest/should_persist_component_data-result.xml new file mode 100644 index 00000000000..2795b1bee33 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/index/ComponentDataPersisterTest/should_persist_component_data-result.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/index/ComponentDataPersisterTest/should_persist_component_data.xml b/sonar-batch/src/test/resources/org/sonar/batch/index/ComponentDataPersisterTest/should_persist_component_data.xml new file mode 100644 index 00000000000..3809a9b9f9a --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/index/ComponentDataPersisterTest/should_persist_component_data.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file -- 2.39.5