@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
public class InitialOpenIssuesStack implements BatchExtension {
- private final Cache<String, IssueDto> issuesCache;
- private final Cache<String, ArrayList<IssueChangeDto>> issuesChangelogCache;
+ private final Cache<IssueDto> issuesCache;
+ private final Cache<ArrayList<IssueChangeDto>> issuesChangelogCache;
public InitialOpenIssuesStack(Caches caches) {
issuesCache = caches.createCache("last-open-issues");
}
public Iterable<IssueDto> selectAllIssues() {
- return issuesCache.allValues();
+ return issuesCache.values();
}
public InitialOpenIssuesStack addChangelog(IssueChangeDto issueChangeDto) {
}
public void clear() {
- issuesCache.clearAll();
- issuesChangelogCache.clearAll();
+ issuesCache.clear();
+ issuesChangelogCache.clear();
}
}
*/
package org.sonar.plugins.core.sensors;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
-
-import org.sonar.api.scan.filesystem.InputFile;
import com.google.common.collect.Maps;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.index.ComponentDataCache;
public void analyse(Project project, SensorContext context) {
Map<String, String> map = Maps.newHashMap();
for (InputFile inputFile : fileCache.byModule(project.key())) {
- String hash = inputFile.attribute(DefaultInputFile.ATTRIBUTE_HASH);
+ String hash = ((DefaultInputFile) inputFile).hash();
if (hash != null) {
- map.put(inputFile.path(), hash);
+ map.put(inputFile.relativePath(), hash);
}
}
if (!map.isEmpty()) {
Caches caches;
@Before
- public void setUp() throws Exception {
+ public void before() throws Exception {
caches = createCacheOnTemp(temp);
caches.start();
stack = new InitialOpenIssuesStack(caches);
}
@After
- public void tearDown() {
+ public void after() {
caches.stop();
}
*/
package org.sonar.plugins.core.sensors;
-import org.sonar.api.scan.filesystem.InputFile;
-
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.resources.Project;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
import org.sonar.batch.index.ComponentDataCache;
import org.sonar.batch.scan.filesystem.InputFileCache;
import org.sonar.core.source.SnapshotDataTypes;
@Test
public void store_file_hashes() throws Exception {
when(fileCache.byModule("struts")).thenReturn(Lists.<InputFile>newArrayList(
- DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "src/Foo.java", ImmutableMap.of(DefaultInputFile.ATTRIBUTE_HASH, "ABC")),
- DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "src/Bar.java", ImmutableMap.of(DefaultInputFile.ATTRIBUTE_HASH, "DEF"))
- ));
+ new DefaultInputFile("src/Foo.java").setFile(temp.newFile()).setHash("ABC"),
+ new DefaultInputFile("src/Bar.java").setFile(temp.newFile()).setHash("DEF")));
SensorContext sensorContext = mock(SensorContext.class);
sensor.analyse(project, sensorContext);
public void store_file_hashes_for_branches() throws Exception {
project = new Project("struts", "branch-2.x", "Struts 2.x");
when(fileCache.byModule("struts:branch-2.x")).thenReturn(Lists.<InputFile>newArrayList(
- DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "src/Foo.java", ImmutableMap.of(DefaultInputFile.ATTRIBUTE_HASH, "ABC")),
- DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "src/Bar.java", ImmutableMap.of(DefaultInputFile.ATTRIBUTE_HASH, "DEF"))
- ));
+ new DefaultInputFile("src/Foo.java").setFile(temp.newFile()).setHash("ABC"),
+ new DefaultInputFile("src/Bar.java").setFile(temp.newFile()).setHash("DEF")));
SensorContext sensorContext = mock(SensorContext.class);
sensor.analyse(project, sensorContext);
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.CpdMapping;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Project;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
import org.sonar.api.utils.SonarException;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.duplications.DuplicationPredicates;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.index.CloneGroup;
import org.sonar.plugins.cpd.index.SonarDuplicationsIndex;
import javax.annotation.CheckForNull;
-
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import java.util.concurrent.*;
public class SonarBridgeEngine extends CpdEngine {
private final IndexFactory indexFactory;
private final CpdMapping[] mappings;
- private final DefaultModuleFileSystem fileSystem;
+ private final FileSystem fs;
private final Settings settings;
- public SonarBridgeEngine(IndexFactory indexFactory, CpdMapping[] mappings, DefaultModuleFileSystem moduleFileSystem, Settings settings) {
+ public SonarBridgeEngine(IndexFactory indexFactory, CpdMapping[] mappings, FileSystem fs, Settings settings) {
this.indexFactory = indexFactory;
this.mappings = mappings;
- this.fileSystem = moduleFileSystem;
+ this.fs = fs;
this.settings = settings;
}
- public SonarBridgeEngine(IndexFactory indexFactory, DefaultModuleFileSystem moduleFileSystem, Settings settings) {
- this(indexFactory, new CpdMapping[0], moduleFileSystem, settings);
+ public SonarBridgeEngine(IndexFactory indexFactory, FileSystem fs, Settings settings) {
+ this(indexFactory, new CpdMapping[0], fs, settings);
}
@Override
public void analyse(Project project, String languageKey, SensorContext context) {
String[] cpdExclusions = settings.getStringArray(CoreProperties.CPD_EXCLUSIONS);
logExclusions(cpdExclusions, LOG);
- Iterable<InputFile> sourceFiles = fileSystem.inputFiles(FileQuery.onMain().onLanguage(languageKey)
- .withExclusions(cpdExclusions));
+ Iterable<InputFile> sourceFiles = fs.inputFiles(FilePredicates.and(
+ FilePredicates.hasType(InputFile.Type.MAIN),
+ FilePredicates.hasLanguage(languageKey),
+ FilePredicates.doesNotMatchPathPatterns(cpdExclusions)
+ ));
if (!sourceFiles.iterator().hasNext()) {
return;
}
// Create index
SonarDuplicationsIndex index = indexFactory.create(project);
- TokenizerBridge bridge = new TokenizerBridge(mapping.getTokenizer(), fileSystem.sourceCharset().name(), getBlockSize(project, languageKey));
+ TokenizerBridge bridge = new TokenizerBridge(mapping.getTokenizer(), fs.encoding().name(), getBlockSize(project, languageKey));
for (InputFile inputFile : sourceFiles) {
LOG.debug("Populating index from {}", inputFile);
- String resourceEffectiveKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY);
+ String resourceEffectiveKey = ((DefaultInputFile) inputFile).key();
List<Block> blocks = bridge.chunk(resourceEffectiveKey, inputFile.file());
index.insert(inputFile, blocks);
}
try {
for (InputFile inputFile : sourceFiles) {
LOG.debug("Detection of duplications for {}", inputFile);
- String resourceEffectiveKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY);
+ String resourceEffectiveKey = ((DefaultInputFile) inputFile).key();
Collection<Block> fileBlocks = index.getByInputFile(inputFile, resourceEffectiveKey);
Iterable<CloneGroup> filtered;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.PersistenceMode;
import org.sonar.api.resources.Java;
import org.sonar.api.resources.Project;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
import org.sonar.api.utils.SonarException;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.block.BlockChunker;
import org.sonar.duplications.detector.suffixtree.SuffixTreeCloneDetectionAlgorithm;
import org.sonar.plugins.cpd.index.SonarDuplicationsIndex;
import javax.annotation.Nullable;
-
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import java.util.concurrent.*;
public class SonarEngine extends CpdEngine {
private static final int TIMEOUT = 5 * 60;
private final IndexFactory indexFactory;
- private final DefaultModuleFileSystem fileSystem;
+ private final FileSystem fs;
private final Settings settings;
- public SonarEngine(IndexFactory indexFactory, DefaultModuleFileSystem moduleFileSystem, Settings settings) {
+ public SonarEngine(IndexFactory indexFactory, FileSystem fs, Settings settings) {
this.indexFactory = indexFactory;
- this.fileSystem = moduleFileSystem;
+ this.fs = fs;
this.settings = settings;
}
public void analyse(Project project, String languageKey, SensorContext context) {
String[] cpdExclusions = settings.getStringArray(CoreProperties.CPD_EXCLUSIONS);
logExclusions(cpdExclusions, LOG);
- Iterable<InputFile> sourceFiles = fileSystem.inputFiles(FileQuery.onMain().onLanguage(languageKey).withExclusions(cpdExclusions));
+ Iterable<InputFile> sourceFiles = fs.inputFiles(FilePredicates.and(
+ FilePredicates.hasType(InputFile.Type.MAIN),
+ FilePredicates.hasLanguage(languageKey),
+ FilePredicates.doesNotMatchPathPatterns(cpdExclusions)
+ ));
if (!sourceFiles.iterator().hasNext()) {
return;
}
for (InputFile inputFile : sourceFiles) {
LOG.debug("Populating index from {}", inputFile);
- String resourceEffectiveKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY);
+ String resourceEffectiveKey = ((DefaultInputFile) inputFile).key();
List<Statement> statements;
Reader reader = null;
try {
- reader = new InputStreamReader(new FileInputStream(inputFile.file()), fileSystem.sourceCharset());
+ reader = new InputStreamReader(new FileInputStream(inputFile.file()), fs.encoding());
statements = statementChunker.chunk(tokenChunker.chunk(reader));
} catch (FileNotFoundException e) {
throw new SonarException("Cannot find file " + inputFile.file(), e);
try {
for (InputFile inputFile : sourceFiles) {
LOG.debug("Detection of duplications for {}", inputFile);
- String resourceEffectiveKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY);
+ String resourceEffectiveKey = ((DefaultInputFile) inputFile).key();
Collection<Block> fileBlocks = index.getByInputFile(inputFile, resourceEffectiveKey);
*/
package org.sonar.plugins.cpd.index;
-import org.sonar.api.scan.filesystem.InputFile;
-
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Project;
import org.sonar.batch.index.ResourcePersister;
*/
package org.sonar.plugins.cpd.index;
-import org.sonar.api.scan.filesystem.InputFile;
-
import com.google.common.collect.Lists;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.block.ByteArray;
import org.sonar.duplications.index.AbstractCloneIndex;
*/
package org.sonar.plugins.cpd;
-import org.sonar.api.scan.filesystem.InputFile;
-
-import com.google.common.base.Charsets;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
import org.sonar.api.test.IsMeasure;
import org.sonar.duplications.index.CloneGroup;
import org.sonar.duplications.index.ClonePart;
+import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.*;
public class SonarEngineTest {
- private SensorContext context;
- private InputFile inputFile;
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ SensorContext context = mock(SensorContext.class);
+ DefaultInputFile inputFile;
@Before
- public void setUp() {
- context = mock(SensorContext.class);
- inputFile = new InputFileBuilder(new java.io.File(""), Charsets.UTF_8, "src/main/java/Foo.java").build();
+ public void before() throws IOException {
+ inputFile = new DefaultInputFile("src/main/java/Foo.java");
+ inputFile.setFile(temp.newFile("Foo.java"));
}
@SuppressWarnings("unchecked")
}
@Test
- public void shouldEscapeXmlEntities() {
- InputFile csharpFile = new InputFileBuilder(new java.io.File(""), Charsets.UTF_8, "Loads/File Loads/Subs & Reds/SubsRedsDelivery.cs").build();
+ public void shouldEscapeXmlEntities() throws IOException {
+ InputFile csharpFile = new DefaultInputFile("Loads/File Loads/Subs & Reds/SubsRedsDelivery.cs")
+ .setFile(temp.newFile("SubsRedsDelivery.cs"));
List<CloneGroup> groups = Arrays.asList(newCloneGroup(
new ClonePart("Loads/File Loads/Subs & Reds/SubsRedsDelivery.cs", 0, 5, 204),
new ClonePart("Loads/File Loads/Subs & Reds/SubsRedsDelivery2.cs", 0, 15, 214)));
package org.sonar.batch;
import org.sonar.api.batch.SonarIndex;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.measures.FileLinesContext;
import org.sonar.api.measures.FileLinesContextFactory;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Resource;
-import org.sonar.api.scan.filesystem.InputFile;
public class DefaultFileLinesContextFactory implements FileLinesContextFactory {
@Override
public FileLinesContext createFor(InputFile inputFile) {
- File sonarFile = File.create(inputFile.path());
+ File sonarFile = File.create(inputFile.relativePath());
// Reload resource from index
sonarFile = index.getResource(sonarFile);
return new DefaultFileLinesContext(index, sonarFile);
import org.sonar.api.batch.Event;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.batch.SonarIndex;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.*;
import org.sonar.api.rules.Violation;
-import org.sonar.api.scan.filesystem.InputFile;
import org.sonar.api.utils.SonarException;
import org.sonar.core.measure.MeasurementFilters;
}
private Resource fromInputFile(InputFile inputFile) {
- return File.create(inputFile.path());
+ return File.create(inputFile.relativePath());
}
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * This package is a part of bootstrap process, so we should take care about backward compatibility.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.batch.fs;
+
+import javax.annotation.ParametersAreNonnullByDefault;
* This cache is not thread-safe, due to direct usage of {@link com.persistit.Exchange}
* </p>
*/
-public class Cache<K, V extends Serializable> {
+public class Cache<V extends Serializable> {
- private static final String DEFAULT_GROUP = "_";
private final String name;
private final Exchange exchange;
this.exchange = exchange;
}
- public Cache put(K key, V value) {
- return put(DEFAULT_GROUP, key, value);
+ public Cache put(Object key, V value) {
+ resetKey(key);
+ return doPut(value);
}
- public Cache put(String group, K key, V value) {
+ public Cache put(Object firstKey, Object secondKey, V value) {
+ resetKey(firstKey, secondKey);
+ return doPut(value);
+ }
+
+ public Cache put(Object firstKey, Object secondKey, Object thirdKey, V value) {
+ resetKey(firstKey, secondKey, thirdKey);
+ return doPut(value);
+ }
+
+ public Cache put(Object[] key, V value) {
+ resetKey(key);
+ return doPut(value);
+ }
+
+ private Cache doPut(V value) {
try {
- exchange.clear();
- exchange.append(group).append(key);
exchange.getValue().put(value);
exchange.store();
return this;
}
/**
- * Implements group-based retrieval of cache elements.
- *
- * @param key The key.
- * @param group The group.
- * @return The element associated with key in the group, or null.
+ * Returns the value object associated with keys, or null if not found.
*/
- @SuppressWarnings("unchecked")
- public V get(String group, K key) {
+ public V get(Object key) {
+ resetKey(key);
+ return doGet();
+ }
+
+ /**
+ * Returns the value object associated with keys, or null if not found.
+ */
+ @CheckForNull
+ public V get(Object firstKey, Object secondKey) {
+ resetKey(firstKey, secondKey);
+ return doGet();
+ }
+
+ /**
+ * Returns the value object associated with keys, or null if not found.
+ */
+ @CheckForNull
+ public V get(Object firstKey, Object secondKey, Object thirdKey) {
+ resetKey(firstKey, secondKey, thirdKey);
+ return doGet();
+ }
+
+ /**
+ * Returns the value object associated with keys, or null if not found.
+ */
+ @CheckForNull
+ public V get(Object[] key) {
+ resetKey(key);
+ return doGet();
+ }
+
+ @CheckForNull
+ private V doGet() {
try {
- exchange.clear();
- exchange.append(group).append(key);
exchange.fetch();
if (!exchange.getValue().isDefined()) {
return null;
}
}
- /**
- * Returns the object associated with key from the cache, or null if not found.
- *
- * @param key The key whose associated value is to be retrieved.
- * @return The value, or null if not found.
- */
- @SuppressWarnings("unchecked")
- public V get(K key) {
- return get(DEFAULT_GROUP, key);
+ public boolean containsKey(Object key) {
+ resetKey(key);
+ return doContainsKey();
+ }
+
+ public boolean containsKey(Object firstKey, Object secondKey) {
+ resetKey(firstKey, secondKey);
+ return doContainsKey();
+ }
+
+ public boolean containsKey(Object firstKey, Object secondKey, Object thirdKey) {
+ resetKey(firstKey, secondKey, thirdKey);
+ return doContainsKey();
}
- public boolean containsKey(String group, K key) {
+ public boolean containsKey(Object[] key) {
+ resetKey(key);
+ return doContainsKey();
+ }
+
+ private boolean doContainsKey() {
try {
- exchange.clear();
- exchange.append(group).append(key);
exchange.fetch();
return exchange.isValueDefined();
} catch (Exception e) {
}
}
- public boolean remove(String group, K key) {
+ public boolean remove(Object key) {
+ resetKey(key);
+ return doRemove();
+ }
+
+ public boolean remove(Object firstKey, Object secondKey) {
+ resetKey(firstKey, secondKey);
+ return doRemove();
+ }
+
+ public boolean remove(Object firstKey, Object secondKey, Object thirdKey) {
+ resetKey(firstKey, secondKey, thirdKey);
+ return doRemove();
+ }
+
+ public boolean remove(Object[] key) {
+ resetKey(key);
+ return doRemove();
+ }
+
+ private boolean doRemove() {
try {
- exchange.clear();
- exchange.append(group).append(key);
return exchange.remove();
} catch (Exception e) {
// TODO add parameters to message
}
}
- public boolean remove(K key) {
- return remove(DEFAULT_GROUP, key);
- }
-
/**
* Removes everything in the specified group.
*
* @param group The group name.
*/
- public Cache clear(String group) {
+ public Cache clear(Object key) {
+ resetKey(key);
+ return doClear();
+ }
+
+ public Cache clear(Object firstKey, Object secondKey) {
+ resetKey(firstKey, secondKey);
+ return doClear();
+ }
+
+ public Cache clear(Object firstKey, Object secondKey, Object thirdKey) {
+ resetKey(firstKey, secondKey, thirdKey);
+ return doClear();
+ }
+
+ public Cache clear(Object[] key) {
+ resetKey(key);
+ return doClear();
+ }
+
+ private Cache doClear() {
try {
- exchange.clear();
- exchange.append(group);
- Key key = new Key(exchange.getKey());
- key.append(Key.AFTER);
- exchange.removeKeyRange(exchange.getKey(), key);
+ Key to = new Key(exchange.getKey());
+ to.append(Key.AFTER);
+ exchange.removeKeyRange(exchange.getKey(), to);
return this;
} catch (Exception e) {
- throw new IllegalStateException("Fail to clear group '" + group + "' from cache " + name, e);
+ throw new IllegalStateException("Fail to clear values from cache " + name, e);
}
}
- /**
- * Removes everything in the default cache, but not any of the group caches.
- */
- public Cache clear() {
- return clear(DEFAULT_GROUP);
- }
-
/**
* Clears the default as well as all group caches.
*/
- public void clearAll() {
+ public void clear() {
try {
exchange.clear();
exchange.removeAll();
* @return The set of cache keys for this group.
*/
@SuppressWarnings("unchecked")
- public Set<K> keySet(String group) {
+ public Set keySet(Object key) {
try {
- Set<K> keys = Sets.newLinkedHashSet();
+ Set<Object> keys = Sets.newLinkedHashSet();
exchange.clear();
Exchange iteratorExchange = new Exchange(exchange);
-
- iteratorExchange.append(group);
+ iteratorExchange.append(key);
iteratorExchange.append(Key.BEFORE);
while (iteratorExchange.next(false)) {
- keys.add((K) iteratorExchange.getKey().indexTo(-1).decode());
+ keys.add(iteratorExchange.getKey().indexTo(-1).decode());
}
return keys;
} catch (Exception e) {
}
}
+ public Set keySet(Object firstKey, Object secondKey) {
+ try {
+ Set<Object> keys = Sets.newLinkedHashSet();
+ exchange.clear();
+ Exchange iteratorExchange = new Exchange(exchange);
+ iteratorExchange.append(firstKey);
+ iteratorExchange.append(secondKey);
+ iteratorExchange.append(Key.BEFORE);
+ while (iteratorExchange.next(false)) {
+ keys.add(iteratorExchange.getKey().indexTo(-1).decode());
+ }
+ return keys;
+ } catch (Exception e) {
+ throw new IllegalStateException("Fail to get keys from cache " + name, e);
+ }
+ }
/**
* Returns the set of keys associated with this cache.
*
* @return The set containing the keys for this cache.
*/
- public Set<K> keySet() {
- return keySet(DEFAULT_GROUP);
+ public Set<Object> keySet() {
+ try {
+ Set<Object> keys = Sets.newLinkedHashSet();
+ exchange.clear();
+ Exchange iteratorExchange = new Exchange(exchange);
+ iteratorExchange.append(Key.BEFORE);
+ while (iteratorExchange.next(false)) {
+ keys.add(iteratorExchange.getKey().indexTo(-1).decode());
+ }
+ return keys;
+ } catch (Exception e) {
+ throw new IllegalStateException("Fail to get keys from cache " + name, e);
+ }
}
/**
- * Lazy-loading values for a given group
+ * Lazy-loading values for a given key
*/
- public Iterable<V> values(String group) {
+ public Iterable<V> values(Object key) {
try {
exchange.clear();
+ exchange.append(key).append(Key.BEFORE);
Exchange iteratorExchange = new Exchange(exchange);
- iteratorExchange.append(group).append(Key.BEFORE);
return new ValueIterable<V>(iteratorExchange, false);
} catch (Exception e) {
throw new IllegalStateException("Fail to get values from cache " + name, e);
* Lazy-loading values
*/
public Iterable<V> values() {
- return values(DEFAULT_GROUP);
- }
-
- /**
- * Lazy-loading values of all groups
- */
- public Iterable<V> allValues() {
try {
- exchange.clear();
+ exchange.clear().append(Key.BEFORE);
Exchange iteratorExchange = new Exchange(exchange);
- iteratorExchange.append(Key.BEFORE);
return new ValueIterable<V>(iteratorExchange, true);
} catch (Exception e) {
throw new IllegalStateException("Fail to get values from cache " + name, e);
}
}
- public Set<String> groups() {
- try {
- Set<String> 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 values from cache " + name, e);
- }
- }
-
- public <T extends Serializable> Iterable<Entry<T>> entries() {
+ public Iterable<Entry<V>> entries() {
exchange.clear().to(Key.BEFORE);
return new EntryIterable(new Exchange(exchange), true);
}
- public <T extends Serializable> Iterable<Entry<T>> entries(String group) {
- exchange.clear().append(group).append(Key.BEFORE);
- return new EntryIterable(new Exchange(exchange), false);
+ public Iterable<SubEntry<V>> subEntries(Object key) {
+ exchange.clear().append(key).append(Key.BEFORE);
+ return new SubEntryIterable(new Exchange(exchange), false);
+ }
+
+ private void resetKey(Object key) {
+ exchange.clear();
+ exchange.append(key);
+ }
+
+ private void resetKey(Object first, Object second) {
+ exchange.clear();
+ exchange.append(first).append(second);
+ }
+
+ private void resetKey(Object first, Object second, Object third) {
+ exchange.clear();
+ exchange.append(first).append(second).append(third);
+ }
+
+ private void resetKey(Object[] keys) {
+ exchange.clear();
+ for (Object o : keys) {
+ exchange.append(o);
+ }
}
@Override
public boolean hasNext() {
try {
- return exchange.next(deep);
+ return exchange.hasNext(deep);
} catch (PersistitException e) {
throw new IllegalStateException(e);
}
@Override
public T next() {
+ try {
+ exchange.next(deep);
+ } catch (PersistitException e) {
+ throw new IllegalStateException(e);
+ }
T value = null;
if (exchange.getValue().isDefined()) {
value = (T) exchange.getValue().get();
}
}
+ private static class SubEntryIterable<T extends Serializable> implements Iterable<SubEntry<T>> {
+ private final SubEntryIterator<T> it;
+
+ private SubEntryIterable(Exchange exchange, boolean deep) {
+ it = new SubEntryIterator<T>(exchange, deep);
+ }
+
+ @Override
+ public Iterator<SubEntry<T>> iterator() {
+ return it;
+ }
+ }
+
+ private static class SubEntryIterator<T extends Serializable> implements Iterator<SubEntry<T>> {
+ private final Exchange exchange;
+ private final boolean deep;
+
+ private SubEntryIterator(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 SubEntry next() {
+ Serializable value = null;
+ if (exchange.getValue().isDefined()) {
+ value = (Serializable) exchange.getValue().get();
+ }
+ Key key = exchange.getKey();
+ return new SubEntry(key.indexTo(-1).decode(), value);
+ }
+
+ @Override
+ public void remove() {
+ // nothing to do
+ }
+ }
+
+ public static class SubEntry<V extends Serializable> {
+ private final Object key;
+ private final V value;
+
+ SubEntry(Object key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Object key() {
+ return key;
+ }
+
+ public String keyAsString() {
+ return (String) key;
+ }
+
+ @CheckForNull
+ public V value() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+ }
+
private static class EntryIterable<T extends Serializable> implements Iterable<Entry<T>> {
private final EntryIterator<T> it;
value = (Serializable) exchange.getValue().get();
}
Key key = exchange.getKey();
- return new Entry(key.indexTo(-2).decodeString(), key.indexTo(-1).decodeString(), value);
+ Object[] array = new Object[key.getDepth()];
+ for (int i = 0; i < key.getDepth(); i++) {
+ array[i] = key.indexTo(i - key.getDepth()).decode();
+ }
+ return new Entry(array, value);
}
@Override
}
}
- public static class Entry<T extends Serializable> {
- private final String group;
- private final String key;
- private final T value;
+ public static class Entry<V extends Serializable> {
+ private final Object[] key;
+ private final V value;
- Entry(String group, String key, T value) {
- this.group = group;
+ Entry(Object[] key, V value) {
this.key = key;
this.value = value;
}
- public String group() {
- return group;
- }
-
- public String key() {
+ public Object[] key() {
return key;
}
@CheckForNull
- public T value() {
+ public V value() {
return value;
}
}
}
- public <K extends Serializable, V extends Serializable> Cache<K, V> createCache(String cacheName) {
+ public <V extends Serializable> Cache<V> createCache(String cacheName) {
Preconditions.checkState(volume != null && volume.isOpened(), "Caches are not initialized");
Preconditions.checkState(!cacheNames.contains(cacheName), "Cache is already created: " + cacheName);
try {
Exchange exchange = persistit.getExchange(volume, cacheName, true);
- Cache<K, V> cache = new Cache<K, V>(cacheName, exchange);
+ Cache<V> cache = new Cache<V>(cacheName, exchange);
cacheNames.add(cacheName);
return cache;
} catch (Exception e) {
return data == null ? null : ((StringData) data).data();
}
- public <D extends Data> Iterable<Cache.Entry<D>> entries(String componentKey) {
- return cache.entries(componentKey);
+ public <D extends Data> Iterable<Cache.SubEntry<D>> entries(String componentKey) {
+ return cache.subEntries(componentKey);
}
}
for (Map.Entry<String, Snapshot> componentEntry : snapshots.snapshots()) {
String componentKey = componentEntry.getKey();
Snapshot snapshot = componentEntry.getValue();
- for (Cache.Entry<Data> dataEntry : data.entries(componentKey)) {
+ for (Cache.SubEntry<Data> dataEntry : data.entries(componentKey)) {
Data value = dataEntry.value();
if (value != null) {
SnapshotDataDto dto = new SnapshotDataDto();
dto.setSnapshotId(snapshot.getId());
dto.setResourceId(snapshot.getResourceId());
- dto.setDataType(dataEntry.key());
+ dto.setDataType(dataEntry.keyAsString());
dto.setData(value.writeString());
dao.insert(session, dto);
}
import com.google.common.collect.Maps;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.model.ResourceModel;
import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Library;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.scan.filesystem.InputFile;
+import org.sonar.api.resources.*;
import org.sonar.api.security.ResourcePermissions;
import org.sonar.api.utils.SonarException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.Query;
-
import java.util.Date;
import java.util.Iterator;
import java.util.List;
}
private Resource fromInputFile(InputFile inputFile) {
- return File.create(inputFile.path());
+ return File.create(inputFile.relativePath());
}
/**
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.database.DatabaseSession;
import org.sonar.api.database.model.ResourceModel;
-import org.sonar.api.resources.Directory;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.JavaFile;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.api.resources.*;
import org.sonar.api.utils.PathUtils;
import java.util.HashMap;
Map<String, InputFile> deprecatedTestKeyMapper = new HashMap<String, InputFile>();
Map<String, String> deprecatedDirectoryKeyMapper = new HashMap<String, String>();
for (InputFile inputFile : inputFiles) {
- String deprecatedKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_DEPRECATED_KEY);
+ String deprecatedKey = ((DefaultInputFile) inputFile).deprecatedKey();
if (deprecatedKey != null) {
- if (InputFile.TYPE_TEST.equals(inputFile.attribute(InputFile.ATTRIBUTE_TYPE))) {
+ if (InputFile.Type.TEST == inputFile.type()) {
deprecatedTestKeyMapper.put(deprecatedKey, inputFile);
} else {
deprecatedFileKeyMapper.put(deprecatedKey, inputFile);
boolean isTest = Qualifiers.UNIT_TEST_FILE.equals(resourceModel.getQualifier());
InputFile matchedFile = findInputFile(deprecatedFileKeyMapper, deprecatedTestKeyMapper, oldEffectiveKey, isTest);
if (matchedFile != null) {
- String newEffectiveKey = matchedFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY);
+ String newEffectiveKey = ((DefaultInputFile) matchedFile).key();
// Now compute migration of the parent dir
String oldKey = StringUtils.substringAfterLast(oldEffectiveKey, ":");
Resource sonarFile;
}
private String getParentKey(InputFile matchedFile) {
- String filePath = PathUtils.sanitize(matchedFile.path());
+ String filePath = PathUtils.sanitize(matchedFile.relativePath());
String parentFolderPath;
if (filePath.contains(Directory.SEPARATOR)) {
parentFolderPath = StringUtils.substringBeforeLast(filePath, Directory.SEPARATOR);
*/
package org.sonar.batch.index;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.database.model.Snapshot;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
-import org.sonar.api.scan.filesystem.InputFile;
public interface ResourcePersister {
public class IssueCache implements BatchComponent {
// component key -> issue key -> issue
- private final Cache<String, DefaultIssue> cache;
+ private final Cache<DefaultIssue> cache;
public IssueCache(Caches caches) {
cache = caches.createCache("issues");
}
public Iterable<DefaultIssue> all() {
- return cache.allValues();
+ return cache.values();
}
public IssueCache put(DefaultIssue issue) {
package org.sonar.batch.issue.ignore.scanner;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.resources.Project;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import java.nio.charset.Charset;
private final IssueExclusionsRegexpScanner regexpScanner;
private final IssueExclusionPatternInitializer exclusionPatternInitializer;
private final IssueInclusionPatternInitializer inclusionPatternInitializer;
- private final DefaultModuleFileSystem fileSystem;
+ private final FileSystem fileSystem;
public IssueExclusionsLoader(IssueExclusionsRegexpScanner regexpScanner, IssueExclusionPatternInitializer exclusionPatternInitializer,
IssueInclusionPatternInitializer inclusionPatternInitializer,
- DefaultModuleFileSystem fileSystem) {
+ FileSystem fileSystem) {
this.regexpScanner = regexpScanner;
this.exclusionPatternInitializer = exclusionPatternInitializer;
this.inclusionPatternInitializer = inclusionPatternInitializer;
* {@inheritDoc}
*/
public void execute() {
- Charset sourcesEncoding = fileSystem.sourceCharset();
+ Charset sourcesEncoding = fileSystem.encoding();
- for (InputFile inputFile : fileSystem.inputFiles(FileQuery.all())) {
+ for (InputFile inputFile : fileSystem.inputFiles(FilePredicates.all())) {
try {
- String componentEffectiveKey = inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY);
+ String componentEffectiveKey = ((DefaultInputFile) inputFile).key();
if (componentEffectiveKey != null) {
- String path = inputFile.path();
+ String path = inputFile.relativePath();
inclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey);
exclusionPatternInitializer.initializePatternsForPath(path, componentEffectiveKey);
if (exclusionPatternInitializer.hasFileContentPattern()) {
import org.sonar.api.BatchComponent;
import org.sonar.api.batch.ModuleLanguages;
import org.sonar.api.config.Settings;
-import org.sonar.api.resources.Language;
+import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.rule.ModuleQProfiles;
import org.sonar.batch.rule.ModuleQProfiles.QProfile;
void execute(Logger logger) {
String defaultName = settings.getString(ModuleQProfiles.SONAR_PROFILE_PROP);
boolean defaultNameUsed = StringUtils.isBlank(defaultName);
- for (Language lang : languages.languages()) {
- QProfile profile = profiles.findByLanguage(lang.getKey());
- logger.info("Quality profile for {}: {}", lang.getName(), profile.name());
+ for (String lang : languages.keys()) {
+ QProfile profile = profiles.findByLanguage(lang);
+ logger.info("Quality profile for {}: {}", lang, profile.name());
if (StringUtils.isNotBlank(defaultName) && defaultName.equals(profile.name())) {
defaultNameUsed = true;
}
}
- if (!defaultNameUsed && !languages.languages().isEmpty()) {
- throw new SonarException("sonar.profile was set to '" + defaultName + "' but didn't match any profile for any language. Please check your configuration.");
+ if (!defaultNameUsed && !languages.keys().isEmpty()) {
+ throw MessageException.of("sonar.profile was set to '" + defaultName + "' but didn't match any profile for any language. Please check your configuration.");
}
}
import org.sonar.batch.rule.ModuleQProfiles;
import org.sonar.batch.rule.QProfileSensor;
import org.sonar.batch.rule.RulesProfileProvider;
-import org.sonar.batch.scan.filesystem.ComponentIndexer;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
-import org.sonar.batch.scan.filesystem.DeprecatedFileFilters;
-import org.sonar.batch.scan.filesystem.ExclusionFilters;
-import org.sonar.batch.scan.filesystem.FileIndex;
-import org.sonar.batch.scan.filesystem.FileSystemLogger;
-import org.sonar.batch.scan.filesystem.InputFileBuilderFactory;
-import org.sonar.batch.scan.filesystem.LanguageDetectionFactory;
-import org.sonar.batch.scan.filesystem.ModuleFileSystemInitializer;
-import org.sonar.batch.scan.filesystem.PreviousFileHashLoader;
-import org.sonar.batch.scan.filesystem.ProjectFileSystemAdapter;
-import org.sonar.batch.scan.filesystem.StatusDetectionFactory;
+import org.sonar.batch.scan.filesystem.*;
+import org.sonar.batch.scan.filesystem.FileIndexer;
import org.sonar.batch.scan.language.DefaultModuleLanguages;
import org.sonar.batch.scan.report.JsonReport;
import org.sonar.core.component.ScanPerspectives;
moduleDefinition.getContainerExtensions(),
// file system
+ ModuleInputFileCache.class,
FileExclusions.class,
ExclusionFilters.class,
DeprecatedFileFilters.class,
StatusDetectionFactory.class,
LanguageDetectionFactory.class,
PreviousFileHashLoader.class,
- FileIndex.class,
+ FileIndexer.class,
ComponentIndexer.class,
DefaultModuleLanguages.class,
FileSystemLogger.class,
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.scan.filesystem;
-
-import org.sonar.api.scan.filesystem.InputFileFilter;
-
-import org.sonar.api.scan.filesystem.InputFile;
-import com.google.common.annotations.VisibleForTesting;
-
-import java.util.Collection;
-
-class AttributeFilter implements InputFileFilter {
- private final String key;
- private final Collection<String> values;
-
- AttributeFilter(String key, Collection<String> values) {
- this.key = key;
- this.values = values;
- }
-
- @Override
- public boolean accept(InputFile inputFile) {
- String value = inputFile.attribute(key);
- return values.contains(value);
- }
-
- @VisibleForTesting
- String key() {
- return key;
- }
-
- @VisibleForTesting
- Collection<String> values() {
- return values;
- }
-}
import org.sonar.api.BatchComponent;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.SonarIndex;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.JavaFile;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.api.resources.*;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.index.ResourceKeyMigration;
import org.sonar.batch.scan.language.DefaultModuleLanguages;
this.fileCache = fileCache;
}
- public void execute(DefaultModuleFileSystem fs) {
+ public void execute(FileSystem fs) {
boolean shouldImportSource = settings.getBoolean(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY);
- Iterable<InputFile> inputFiles = fs.inputFiles(FileQuery.all());
+ Iterable<InputFile> inputFiles = fs.inputFiles(FilePredicates.all());
migration.migrateIfNeeded(module, inputFiles);
for (InputFile inputFile : inputFiles) {
- String languageKey = inputFile.attribute(InputFile.ATTRIBUTE_LANGUAGE);
- boolean unitTest = InputFile.TYPE_TEST.equals(inputFile.attribute(InputFile.ATTRIBUTE_TYPE));
- String pathFromSourceDir = inputFile.attribute(DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH);
+ String languageKey = inputFile.language();
+ boolean unitTest = InputFile.Type.TEST == inputFile.type();
+ String pathFromSourceDir = ((DefaultInputFile) inputFile).pathRelativeToSourceDir();
if (pathFromSourceDir == null) {
- pathFromSourceDir = inputFile.path();
+ pathFromSourceDir = inputFile.relativePath();
}
- Resource sonarFile = File.create(inputFile.path(), pathFromSourceDir, languages.get(languageKey), unitTest);
+ Resource sonarFile = File.create(inputFile.relativePath(), pathFromSourceDir, languages.get(languageKey), unitTest);
if (Java.KEY.equals(languageKey)) {
sonarFile.setDeprecatedKey(JavaFile.fromRelativePath(pathFromSourceDir, false).getDeprecatedKey());
} else {
if (sonarFile != null) {
moduleLanguages.addLanguage(languageKey);
sonarIndex.index(sonarFile);
- importSources(shouldImportSource, inputFile, sonarFile);
+ importSources(fs, shouldImportSource, inputFile, sonarFile);
}
}
}
@VisibleForTesting
- void importSources(boolean shouldImportSource, InputFile inputFile, Resource sonarFile) {
+ void importSources(FileSystem fs, boolean shouldImportSource, InputFile inputFile, Resource sonarFile) {
try {
- // TODO this part deserve optimization.
+ // TODO this part deserves optimization.
// No need to read full content in memory when shouldImportSource=false
// We should try to remove BOM and count lines in a single pass
- String source = Files.toString(inputFile.file(), inputFile.encoding());
+ String source = Files.toString(inputFile.file(), fs.encoding());
// SONAR-3860 Remove BOM character from source
source = CharMatcher.anyOf("\uFEFF").removeFrom(source);
- String[] lines = source.split("(\r)?\n|\r", -1);
- inputFile.attributes().put(InputFile.ATTRIBUTE_LINE_COUNT, String.valueOf(lines.length));
fileCache.put(module.getKey(), inputFile);
if (shouldImportSource) {
sonarIndex.setSource(sonarFile, source);
}
} catch (Exception e) {
throw new SonarException("Unable to read and import the source file : '" + inputFile.absolutePath() + "' with the charset : '"
- + inputFile.encoding() + "'.", e);
+ + fs.encoding() + "'.", e);
}
}
}
*/
package org.sonar.batch.scan.filesystem;
-import com.google.common.base.Preconditions;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Project;
import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.InputFile;
import org.sonar.api.scan.filesystem.ModuleFileSystem;
-import org.sonar.api.scan.filesystem.internal.InputFiles;
import org.sonar.api.utils.SonarException;
-import org.sonar.batch.bootstrap.AnalysisMode;
import javax.annotation.CheckForNull;
-
+import javax.annotation.Nullable;
import java.io.File;
import java.nio.charset.Charset;
+import java.util.Collection;
import java.util.List;
+import java.util.Map;
/**
* This class can't be immutable because of execution of maven plugins that can change the project structure (see MavenPluginHandler and sonar.phase)
*
* @since 3.5
*/
-public class DefaultModuleFileSystem implements ModuleFileSystem {
-
- private static final Logger LOG = LoggerFactory.getLogger(DefaultModuleFileSystem.class);
+public class DefaultModuleFileSystem extends DefaultFileSystem implements ModuleFileSystem {
private final String moduleKey;
- private final FileIndex index;
+ private final FileIndexer index;
private final Settings settings;
- private File baseDir, workingDir, buildDir;
+ private File buildDir;
private List<File> sourceDirs = Lists.newArrayList();
private List<File> testDirs = Lists.newArrayList();
private List<File> binaryDirs = Lists.newArrayList();
private List<File> sourceFiles = Lists.newArrayList();
private List<File> testFiles = Lists.newArrayList();
- private AnalysisMode analysisMode;
private ComponentIndexer componentIndexer;
private boolean initialized;
- public DefaultModuleFileSystem(Project module, Settings settings, FileIndex index, ModuleFileSystemInitializer initializer, AnalysisMode analysisMode,
- ComponentIndexer componentIndexer) {
+ public DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, Project module, Settings settings, FileIndexer index, ModuleFileSystemInitializer initializer,
+ ComponentIndexer componentIndexer) {
+ super(moduleInputFileCache);
this.componentIndexer = componentIndexer;
this.moduleKey = module.getKey();
this.settings = settings;
this.index = index;
- this.analysisMode = analysisMode;
- this.baseDir = initializer.baseDir();
- this.workingDir = initializer.workingDir();
+ setBaseDir(initializer.baseDir());
+ setWorkDir(initializer.workingDir());
this.buildDir = initializer.buildDir();
this.sourceDirs = initializer.sourceDirs();
this.testDirs = initializer.testDirs();
return moduleKey;
}
- @Override
- public File baseDir() {
- return baseDir;
- }
-
@Override
@CheckForNull
public File buildDir() {
return binaryDirs;
}
- @Override
- public File workingDir() {
- return workingDir;
- }
-
List<File> sourceFiles() {
return sourceFiles;
}
return testFiles;
}
+ @Override
+ public Charset encoding() {
+ final Charset charset;
+ String encoding = settings.getString(CoreProperties.ENCODING_PROPERTY);
+ if (StringUtils.isNotEmpty(encoding)) {
+ charset = Charset.forName(StringUtils.trim(encoding));
+ } else {
+ charset = Charset.defaultCharset();
+ }
+ return charset;
+ }
+
+ @Override
+ public boolean isDefaultJvmEncoding() {
+ return !settings.hasKey(CoreProperties.ENCODING_PROPERTY);
+ }
+
/**
* Should not be used - only for old plugins
* @deprecated since 4.0
throw new UnsupportedOperationException("Modifications of the file system are not permitted");
}
+ /**
+ * @return
+ * @deprecated in 4.2. Replaced by {@link #encoding()}
+ */
@Override
+ @Deprecated
public Charset sourceCharset() {
- final Charset charset;
- String encoding = settings.getString(CoreProperties.ENCODING_PROPERTY);
- if (StringUtils.isNotEmpty(encoding)) {
- charset = Charset.forName(StringUtils.trim(encoding));
- } else {
- charset = Charset.defaultCharset();
- }
- return charset;
- }
-
- boolean isDefaultSourceCharset() {
- return !settings.hasKey(CoreProperties.ENCODING_PROPERTY);
+ return encoding();
}
/**
- * @since 4.0
+ * @deprecated in 4.2. Replaced by {@link #workDir()}
*/
+ @Deprecated
@Override
- public Iterable<InputFile> inputFiles(FileQuery query) {
- if (!initialized) {
- LOG.warn("Accessing the filesystem before the Sensor phase is deprecated and will not be supported in the future. Please update your plugin.");
- index.index(this);
- }
- List<InputFile> result = Lists.newArrayList();
- FileQueryFilter filter = new FileQueryFilter(analysisMode, query);
- for (InputFile input : index.inputFiles(moduleKey)) {
- if (filter.accept(input)) {
- result.add(input);
- }
- }
- return result;
- }
-
- @Override
- public InputFile inputFile(File ioFile) {
- if (!ioFile.isFile()) {
- throw new SonarException(ioFile.getAbsolutePath() + "is not a file");
- }
- return index.inputFile(this, ioFile);
+ public File workingDir() {
+ return workDir();
}
@Override
public List<File> files(FileQuery query) {
- return InputFiles.toFiles(inputFiles(query));
+ Collection<FilePredicate> predicates = Lists.newArrayList();
+ for (Map.Entry<String, Collection<String>> entry : query.attributes().entrySet()) {
+ predicates.add(fromDeprecatedAttribute(entry.getKey(), entry.getValue()));
+ }
+ return ImmutableList.copyOf(files(FilePredicates.and(predicates)));
}
public void resetDirs(File basedir, File buildDir, List<File> sourceDirs, List<File> testDirs, List<File> binaryDirs) {
if (initialized) {
throw new SonarException("Module filesystem is already initialized. Modification of the filesystem are only allowed during Initializer phase.");
}
- Preconditions.checkNotNull(basedir, "Basedir can't be null");
- this.baseDir = basedir;
+ setBaseDir(basedir);
this.buildDir = buildDir;
this.sourceDirs = existingDirs(sourceDirs);
this.testDirs = existingDirs(testDirs);
if (initialized) {
throw new SonarException("Module filesystem can only be indexed once");
}
- initialized = true;
index.index(this);
componentIndexer.execute(this);
+ initialized = true;
}
private List<File> existingDirs(List<File> dirs) {
return builder.build();
}
+ static FilePredicate fromDeprecatedAttribute(String key, Collection<String> value) {
+ if ("TYPE".equals(key)) {
+ return FilePredicates.or(Collections2.transform(value, new Function<String, FilePredicate>() {
+ @Override
+ public FilePredicate apply(@Nullable String s) {
+ return FilePredicates.hasType(org.sonar.api.batch.fs.InputFile.Type.valueOf(s));
+ }
+ }));
+ }
+ if ("STATUS".equals(key)) {
+ return FilePredicates.or(Collections2.transform(value, new Function<String, FilePredicate>() {
+ @Override
+ public FilePredicate apply(@Nullable String s) {
+ return FilePredicates.hasStatus(org.sonar.api.batch.fs.InputFile.Status.valueOf(s));
+ }
+ }));
+ }
+ if ("LANG".equals(key)) {
+ return FilePredicates.or(Collections2.transform(value, new Function<String, FilePredicate>() {
+ @Override
+ public FilePredicate apply(@Nullable String s) {
+ return FilePredicates.hasLanguage(s);
+ }
+ }));
+ }
+ if ("CMP_KEY".equals(key)) {
+ return FilePredicates.or(Collections2.transform(value, new Function<String, FilePredicate>() {
+ @Override
+ public FilePredicate apply(@Nullable String s) {
+ return new FilePredicateAdapters.KeyPredicate(s);
+ }
+ }));
+ }
+ if ("CMP_DEPRECATED_KEY".equals(key)) {
+ return FilePredicates.or(Collections2.transform(value, new Function<String, FilePredicate>() {
+ @Override
+ public FilePredicate apply(@Nullable String s) {
+ return new FilePredicateAdapters.DeprecatedKeyPredicate(s);
+ }
+ }));
+ }
+ if ("SRC_REL_PATH".equals(key)) {
+ return FilePredicates.or(Collections2.transform(value, new Function<String, FilePredicate>() {
+ @Override
+ public FilePredicate apply(@Nullable String s) {
+ return new FilePredicateAdapters.SourceRelativePathPredicate(s);
+ }
+ }));
+ }
+ if ("SRC_DIR_PATH".equals(key)) {
+ return FilePredicates.or(Collections2.transform(value, new Function<String, FilePredicate>() {
+ @Override
+ public FilePredicate apply(@Nullable String s) {
+ return new FilePredicateAdapters.SourceDirPredicate(s);
+ }
+ }));
+ }
+ throw new IllegalArgumentException("Unsupported file attribute: " + key);
+ }
+
+
@Override
public boolean equals(Object o) {
if (this == o) {
*/
package org.sonar.batch.scan.filesystem;
-import org.sonar.api.scan.filesystem.InputFileFilter;
-
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
-import org.sonar.api.scan.filesystem.*;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFileFilter;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.scan.filesystem.FileSystemFilter;
+import org.sonar.api.scan.filesystem.FileType;
+import org.sonar.api.scan.filesystem.ModuleFileSystem;
import java.io.File;
@Override
public FileType type() {
- String type = inputFile.attribute(InputFile.ATTRIBUTE_TYPE);
- return type == null ? null : FileType.valueOf(type.toUpperCase());
+ String type = inputFile.type().name();
+ return FileType.valueOf(type);
}
@Override
public File relativeDir() {
- String path = inputFile.attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH);
- return path != null ? new File(path) : null;
+ return new File(((DefaultInputFile)inputFile).sourceDirAbsolutePath());
}
@Override
public String relativePath() {
- return inputFile.attribute(DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH);
+ return ((DefaultInputFile)inputFile).pathRelativeToSourceDir();
}
@Override
*/
package org.sonar.batch.scan.filesystem;
-import org.sonar.api.scan.filesystem.InputFileFilter;
-import org.sonar.api.scan.filesystem.InputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFileFilter;
+import org.sonar.api.batch.fs.internal.PathPattern;
class ExclusionFilter implements InputFileFilter {
private final PathPattern pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.PathPattern;
import org.sonar.api.scan.filesystem.FileExclusions;
-import org.sonar.api.scan.filesystem.InputFile;
import org.sonar.api.scan.filesystem.ModuleFileSystem;
import org.sonar.api.scan.filesystem.PathResolver;
}
}
- public boolean accept(File ioFile, String relativePathFromBasedir, String type) {
+ public boolean accept(File ioFile, String relativePathFromBasedir, InputFile.Type type) {
PathPattern[] inclusionPatterns = null;
PathPattern[] exclusionPatterns = null;
- if (InputFile.TYPE_MAIN.equals(type)) {
+ if (InputFile.Type.MAIN==type) {
inclusionPatterns = sourceInclusions;
exclusionPatterns = sourceExclusions;
- } else if (InputFile.TYPE_TEST.equals(type)) {
+ } else if (InputFile.Type.TEST==type) {
inclusionPatterns = testInclusions;
exclusionPatterns = testExclusions;
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.scan.filesystem;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.filefilter.FileFilterUtils;
-import org.apache.commons.io.filefilter.HiddenFileFilter;
-import org.apache.commons.io.filefilter.IOFileFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchComponent;
-import org.sonar.api.resources.Project;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.InputFileFilter;
-import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.api.utils.SonarException;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Index input files into {@link InputFileCache}.
- */
-public class FileIndex implements BatchComponent {
-
- private static final String FILE_IS_NOT_DECLARED_IN_MODULE_BASEDIR = "File '%s' is not declared in module basedir %s";
-
- private static class Progress {
- private final Set<String> removedPaths;
- private final Set<String> indexed;
-
- Progress(Set<String> removedPaths) {
- this.removedPaths = removedPaths;
- this.indexed = new HashSet<String>();
- }
-
- void markAsIndexed(String relativePath) {
- if (indexed.contains(relativePath)) {
- throw new SonarException("File " + relativePath + " can't be indexed twice. Please check that inclusion/exclusion patterns produce "
- + "disjoint sets for main and test files");
- }
- removedPaths.remove(relativePath);
- indexed.add(relativePath);
- }
-
- int count() {
- return indexed.size();
- }
- }
-
- private static final IOFileFilter DIR_FILTER = FileFilterUtils.and(HiddenFileFilter.VISIBLE, FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter(".")));
- private static final IOFileFilter FILE_FILTER = HiddenFileFilter.VISIBLE;
-
- private final PathResolver pathResolver;
- private final List<InputFileFilter> filters;
- private final InputFileCache fileCache;
- private final Project module;
- private final ExclusionFilters exclusionFilters;
- private final InputFileBuilderFactory inputFileBuilderFactory;
-
- public FileIndex(List<InputFileFilter> filters, ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory,
- InputFileCache cache, PathResolver pathResolver, Project project) {
- this.filters = filters;
- this.exclusionFilters = exclusionFilters;
- this.inputFileBuilderFactory = inputFileBuilderFactory;
- this.fileCache = cache;
- this.pathResolver = pathResolver;
- this.module = project;
- }
-
- void index(DefaultModuleFileSystem fileSystem) {
- Logger logger = LoggerFactory.getLogger(FileIndex.class);
- if (!module.getModules().isEmpty()) {
- // No indexing for an aggregator module
- return;
- }
- logger.info("Index files");
- exclusionFilters.prepare(fileSystem);
- // TODO log configuration too (replace FileSystemLogger)
-
- Progress progress = new Progress(fileCache.fileRelativePaths(fileSystem.moduleKey()));
-
- InputFileBuilder inputFileBuilder = inputFileBuilderFactory.create(fileSystem);
- if (!fileSystem.sourceFiles().isEmpty() || !fileSystem.testFiles().isEmpty()) {
- // Index only provided files
- indexFiles(inputFileBuilder, fileSystem, progress, fileSystem.sourceFiles(), InputFile.TYPE_MAIN);
- indexFiles(inputFileBuilder, fileSystem, progress, fileSystem.testFiles(), InputFile.TYPE_TEST);
- } else if (fileSystem.baseDir() != null) {
- // index from basedir
- indexDirectory(inputFileBuilder, fileSystem, progress, fileSystem.baseDir());
- }
-
- // Remove files that have been removed since previous indexation
- for (String path : progress.removedPaths) {
- fileCache.remove(fileSystem.moduleKey(), path);
- }
-
- logger.info(String.format("%d files indexed", progress.count()));
-
- }
-
- private void indexFiles(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress progress, List<File> sourceFiles, String type) {
- for (File sourceFile : sourceFiles) {
- String path = pathResolver.relativePath(fileSystem.baseDir(), sourceFile);
- if (path == null) {
- LoggerFactory.getLogger(getClass()).warn(String.format(
- FILE_IS_NOT_DECLARED_IN_MODULE_BASEDIR, sourceFile.getAbsoluteFile(), fileSystem.baseDir()
- ));
- } else {
- if (exclusionFilters.accept(sourceFile, path, type)) {
- indexFile(inputFileBuilder, fileSystem, progress, sourceFile, path, type);
- }
- }
- }
- }
-
- Iterable<InputFile> inputFiles(String moduleKey) {
- return fileCache.byModule(moduleKey);
- }
-
- InputFile inputFile(DefaultModuleFileSystem fileSystem, File ioFile) {
- String path = computeFilePath(fileSystem, ioFile);
- return fileCache.byPath(fileSystem.moduleKey(), path);
- }
-
- private void indexDirectory(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress status, File dirToIndex) {
- Collection<File> files = FileUtils.listFiles(dirToIndex, FILE_FILTER, DIR_FILTER);
- for (File sourceFile : files) {
- String path = pathResolver.relativePath(fileSystem.baseDir(), sourceFile);
- if (path == null) {
- LoggerFactory.getLogger(getClass()).warn(String.format(
- FILE_IS_NOT_DECLARED_IN_MODULE_BASEDIR, sourceFile.getAbsoluteFile(), fileSystem.baseDir()
- ));
- } else {
- if (exclusionFilters.accept(sourceFile, path, InputFile.TYPE_MAIN)) {
- indexFile(inputFileBuilder, fileSystem, status, sourceFile, path, InputFile.TYPE_MAIN);
- }
- if (exclusionFilters.accept(sourceFile, path, InputFile.TYPE_TEST)) {
- indexFile(inputFileBuilder, fileSystem, status, sourceFile, path, InputFile.TYPE_TEST);
- }
- }
- }
- }
-
- private void indexFile(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fs, Progress status, File file, String path, String type) {
- InputFile inputFile = inputFileBuilder.create(file, type);
- if (inputFile != null && accept(inputFile)) {
- fileCache.put(fs.moduleKey(), inputFile);
- status.markAsIndexed(path);
- }
- }
-
- private String computeFilePath(DefaultModuleFileSystem fileSystem, File file) {
- return pathResolver.relativePath(fileSystem.baseDir(), file);
- }
-
- private boolean accept(InputFile inputFile) {
- // InputFileFilter extensions
- for (InputFileFilter filter : filters) {
- if (!filter.accept(inputFile)) {
- return false;
- }
- }
- return true;
- }
-}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.scan.filesystem;
+
+import com.google.common.collect.Sets;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.filefilter.HiddenFileFilter;
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFileFilter;
+import org.sonar.api.resources.Project;
+import org.sonar.api.scan.filesystem.PathResolver;
+import org.sonar.api.utils.SonarException;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Index input files into {@link InputFileCache}.
+ */
+public class FileIndexer implements BatchComponent {
+
+ private static final String FILE_IS_NOT_DECLARED_IN_MODULE_BASEDIR = "File '%s' is not declared in module basedir %s";
+ private static final IOFileFilter DIR_FILTER = FileFilterUtils.and(HiddenFileFilter.VISIBLE, FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter(".")));
+ private static final IOFileFilter FILE_FILTER = HiddenFileFilter.VISIBLE;
+
+ private final PathResolver pathResolver;
+ private final List<InputFileFilter> filters;
+ private final InputFileCache fileCache;
+ private final Project module;
+ private final ExclusionFilters exclusionFilters;
+ private final InputFileBuilderFactory inputFileBuilderFactory;
+
+ public FileIndexer(List<InputFileFilter> filters, ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory,
+ InputFileCache cache, PathResolver pathResolver, Project module) {
+ this.filters = filters;
+ this.exclusionFilters = exclusionFilters;
+ this.inputFileBuilderFactory = inputFileBuilderFactory;
+ this.fileCache = cache;
+ this.pathResolver = pathResolver;
+ this.module = module;
+ }
+
+ void index(DefaultModuleFileSystem fileSystem) {
+ Logger logger = LoggerFactory.getLogger(FileIndexer.class);
+ if (!module.getModules().isEmpty()) {
+ // No indexing for an aggregator module
+ return;
+ }
+ logger.info("Index files");
+ exclusionFilters.prepare(fileSystem);
+ // TODO log configuration too (replace FileSystemLogger)
+
+ Progress progress = new Progress(fileCache.byModule(fileSystem.moduleKey()));
+
+ InputFileBuilder inputFileBuilder = inputFileBuilderFactory.create(fileSystem);
+ if (!fileSystem.sourceFiles().isEmpty() || !fileSystem.testFiles().isEmpty()) {
+ // Index only provided files
+ indexFiles(inputFileBuilder, fileSystem, progress, fileSystem.sourceFiles(), InputFile.Type.MAIN);
+ indexFiles(inputFileBuilder, fileSystem, progress, fileSystem.testFiles(), InputFile.Type.TEST);
+ } else if (fileSystem.baseDir() != null) {
+ // index from basedir
+ indexDirectory(inputFileBuilder, fileSystem, progress, fileSystem.baseDir());
+ }
+
+ // Remove files that have been removed since previous indexation
+ for (InputFile removed : progress.removed) {
+ fileCache.remove(fileSystem.moduleKey(), removed);
+ }
+
+ logger.info(String.format("%d files indexed", progress.count()));
+
+ }
+
+ private void indexFiles(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress progress, List<File> sourceFiles, InputFile.Type type) {
+ for (File sourceFile : sourceFiles) {
+ String path = pathResolver.relativePath(fileSystem.baseDir(), sourceFile);
+ if (path == null) {
+ LoggerFactory.getLogger(getClass()).warn(String.format(
+ FILE_IS_NOT_DECLARED_IN_MODULE_BASEDIR, sourceFile.getAbsoluteFile(), fileSystem.baseDir()
+ ));
+ } else {
+ if (exclusionFilters.accept(sourceFile, path, type)) {
+ indexFile(inputFileBuilder, fileSystem, progress, sourceFile, path, type);
+ }
+ }
+ }
+ }
+
+ private void indexDirectory(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress status, File dirToIndex) {
+ Collection<File> files = FileUtils.listFiles(dirToIndex, FILE_FILTER, DIR_FILTER);
+ for (File sourceFile : files) {
+ String path = pathResolver.relativePath(fileSystem.baseDir(), sourceFile);
+ if (path == null) {
+ LoggerFactory.getLogger(getClass()).warn(String.format(
+ FILE_IS_NOT_DECLARED_IN_MODULE_BASEDIR, sourceFile.getAbsoluteFile(), fileSystem.baseDir()
+ ));
+ } else {
+ if (exclusionFilters.accept(sourceFile, path, InputFile.Type.MAIN)) {
+ indexFile(inputFileBuilder, fileSystem, status, sourceFile, path, InputFile.Type.MAIN);
+ }
+ if (exclusionFilters.accept(sourceFile, path, InputFile.Type.TEST)) {
+ indexFile(inputFileBuilder, fileSystem, status, sourceFile, path, InputFile.Type.TEST);
+ }
+ }
+ }
+ }
+
+ private void indexFile(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fs, Progress status, File file, String path, InputFile.Type type) {
+ InputFile inputFile = inputFileBuilder.create(file, type);
+ if (inputFile != null && accept(inputFile)) {
+ fs.add(inputFile);
+ status.markAsIndexed(inputFile);
+ }
+ }
+
+ private boolean accept(InputFile inputFile) {
+ // InputFileFilter extensions
+ for (InputFileFilter filter : filters) {
+ if (!filter.accept(inputFile)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static class Progress {
+ private final Set<InputFile> removed;
+ private final Set<InputFile> indexed;
+
+ Progress(Iterable<InputFile> removed) {
+ this.removed = Sets.newHashSet(removed);
+ this.indexed = new HashSet<InputFile>();
+ }
+
+ void markAsIndexed(InputFile inputFile) {
+ if (indexed.contains(inputFile)) {
+ throw new SonarException("File " + inputFile + " can't be indexed twice. Please check that inclusion/exclusion patterns produce "
+ + "disjoint sets for main and test files");
+ }
+ removed.remove(inputFile);
+ indexed.add(inputFile);
+ }
+
+ int count() {
+ return indexed.size();
+ }
+ }
+
+}
*/
Metadata read(File file, Charset encoding) {
Reader reader = null;
- long lines = 0L;
+ int lines = 0;
char c = (char)-1;
try {
MessageDigest md5Digest = DigestUtils.getMd5Digest();
}
static class Metadata {
- long lines;
+ int lines;
String hash;
- private Metadata(long lines, String hash) {
+ private Metadata(int lines, String hash) {
this.lines = lines;
this.hash = hash;
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.scan.filesystem;
+
+import org.apache.commons.io.FilenameUtils;
+import org.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+
+class FilePredicateAdapters {
+ static class KeyPredicate implements FilePredicate {
+ private final String key;
+
+ KeyPredicate(String key) {
+ this.key = key;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return key.equals(((DefaultInputFile) f).key());
+ }
+ }
+
+ static class DeprecatedKeyPredicate implements FilePredicate {
+ private final String key;
+
+ DeprecatedKeyPredicate(String key) {
+ this.key = key;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return key.equals(((DefaultInputFile) f).deprecatedKey());
+ }
+ }
+
+ static class SourceRelativePathPredicate implements FilePredicate {
+ private final String path;
+
+ SourceRelativePathPredicate(String s) {
+ this.path = FilenameUtils.normalize(s, true);
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return path.equals(((DefaultInputFile) f).pathRelativeToSourceDir());
+ }
+ }
+
+ static class SourceDirPredicate implements FilePredicate {
+ private final String path;
+
+ SourceDirPredicate(String s) {
+ this.path = FilenameUtils.normalize(s, true);
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return path.equals(((DefaultInputFile) f).sourceDirAbsolutePath());
+ }
+ }
+}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.scan.filesystem;
-
-import org.sonar.api.scan.filesystem.InputFileFilter;
-
-import org.sonar.api.scan.filesystem.InputFile;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.batch.bootstrap.AnalysisMode;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-class FileQueryFilter {
-
- private final List<InputFileFilter> filters;
-
- FileQueryFilter(AnalysisMode analysisMode, FileQuery query) {
- filters = Lists.newArrayList();
- for (String pattern : query.inclusions()) {
- filters.add(new InclusionFilter(pattern));
- }
- for (String pattern : query.exclusions()) {
- filters.add(new ExclusionFilter(pattern));
- }
- for (Map.Entry<String, Collection<String>> entry : query.attributes().entrySet()) {
- filters.add(new AttributeFilter(entry.getKey(), entry.getValue()));
- }
-
- if (analysisMode.isIncremental()) {
- Collection<String> status = query.attributes().get(InputFile.ATTRIBUTE_STATUS);
- if (status == null || status.isEmpty()) {
- filters.add(new AttributeFilter(InputFile.ATTRIBUTE_STATUS, Lists.newArrayList(InputFile.STATUS_ADDED, InputFile.STATUS_CHANGED)));
- }
- }
- }
-
- @VisibleForTesting
- List<InputFileFilter> filters() {
- return filters;
- }
-
- boolean accept(InputFile inputFile) {
- for (InputFileFilter filter : filters) {
- if (!filter.accept(inputFile)) {
- return false;
- }
- }
- return true;
- }
-}
}
private void logEncoding(Logger logger, Charset charset) {
- if (!fs.isDefaultSourceCharset()) {
+ if (!fs.isDefaultJvmEncoding()) {
logger.info("Source encoding: " + charset.displayName() + ", default locale: " + Locale.getDefault());
} else {
logger.warn("Source encoding is platform dependent (" + charset.displayName() + "), default locale: " + Locale.getDefault());
*/
package org.sonar.batch.scan.filesystem;
-import org.sonar.api.scan.filesystem.InputFileFilter;
-import org.sonar.api.scan.filesystem.InputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFileFilter;
+import org.sonar.api.batch.fs.internal.PathPattern;
class InclusionFilter implements InputFileFilter {
private final PathPattern pattern;
*/
package org.sonar.batch.scan.filesystem;
-import com.google.common.collect.Maps;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.resources.Java;
import org.sonar.api.resources.JavaFile;
-import org.sonar.api.scan.filesystem.InputFile;
import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.batch.bootstrap.AnalysisMode;
import javax.annotation.CheckForNull;
-
import java.io.File;
import java.util.List;
private final LanguageDetection langDetection;
private final StatusDetection statusDetection;
private final DefaultModuleFileSystem fs;
+ private final AnalysisMode analysisMode;
InputFileBuilder(String moduleKey, PathResolver pathResolver, LanguageDetection langDetection,
- StatusDetection statusDetection, DefaultModuleFileSystem fs) {
+ StatusDetection statusDetection, DefaultModuleFileSystem fs, AnalysisMode analysisMode) {
this.moduleKey = moduleKey;
this.pathResolver = pathResolver;
this.langDetection = langDetection;
this.statusDetection = statusDetection;
this.fs = fs;
+ this.analysisMode = analysisMode;
}
String moduleKey() {
return statusDetection;
}
- DefaultModuleFileSystem fs() {
+ FileSystem fs() {
return fs;
}
@CheckForNull
- DefaultInputFile create(File file, String type) {
+ DefaultInputFile create(File file, InputFile.Type type) {
String relativePath = pathResolver.relativePath(fs.baseDir(), file);
if (relativePath == null) {
LoggerFactory.getLogger(getClass()).warn(
"File '%s' is ignored. It is not in module basedir '%s'.", file.getAbsolutePath(), fs.baseDir());
return null;
}
- DefaultInputFile inputFile = DefaultInputFile.create(file, fs.sourceCharset(), relativePath, Maps.<String, String>newHashMap());
+ DefaultInputFile inputFile = new DefaultInputFile(relativePath);
inputFile.setType(type);
- inputFile.setKey(moduleKey + ":" + inputFile.path());
+ inputFile.setKey(new StringBuilder().append(moduleKey).append(":").append(inputFile.relativePath()).toString());
+ inputFile.setBasedir(fs.baseDir());
+ inputFile.setAbsolutePath(file.getAbsolutePath());
+ inputFile.setFile(file);
+ FileMetadata.Metadata metadata = FileMetadata.INSTANCE.read(inputFile.file(), fs.encoding());
+ inputFile.setLines(metadata.lines);
+ inputFile.setHash(metadata.hash);
+ inputFile.setStatus(statusDetection.status(inputFile.relativePath(), metadata.hash));
+ if (analysisMode.isIncremental() && inputFile.status() == InputFile.Status.SAME) {
+ return null;
+ }
String lang = langDetection.language(inputFile);
if (lang == null) {
- // TODO use a default plain-text language ?
return null;
}
inputFile.setLanguage(lang);
- FileMetadata.Metadata metadata = FileMetadata.INSTANCE.read(inputFile.file(), fs.sourceCharset());
- inputFile.setLines(metadata.lines);
- inputFile.setHash(metadata.hash);
- inputFile.setStatus(statusDetection.status(inputFile.path(), metadata.hash));
fillDeprecatedData(inputFile);
return inputFile;
}
private void fillDeprecatedData(DefaultInputFile inputFile) {
- List<File> sourceDirs = InputFile.TYPE_MAIN.equals(inputFile.type()) ? fs.sourceDirs() : fs.testDirs();
+ List<File> sourceDirs = InputFile.Type.MAIN == inputFile.type() ? fs.sourceDirs() : fs.testDirs();
for (File sourceDir : sourceDirs) {
String sourceRelativePath = pathResolver.relativePath(sourceDir, inputFile.file());
if (sourceRelativePath != null) {
inputFile.setSourceDirAbsolutePath(FilenameUtils.normalize(sourceDir.getAbsolutePath(), true));
if (Java.KEY.equals(inputFile.language())) {
- inputFile.setDeprecatedKey(moduleKey + ":" + JavaFile.fromRelativePath(sourceRelativePath, false).getDeprecatedKey());
+ inputFile.setDeprecatedKey(new StringBuilder()
+ .append(moduleKey).append(":").append(JavaFile.fromRelativePath(sourceRelativePath, false).getDeprecatedKey()).toString());
} else {
- inputFile.setDeprecatedKey(moduleKey + ":" + sourceRelativePath);
+ inputFile.setDeprecatedKey(new StringBuilder().append(moduleKey).append(":").append(sourceRelativePath).toString());
}
}
}
import org.sonar.api.BatchComponent;
import org.sonar.api.resources.Project;
import org.sonar.api.scan.filesystem.PathResolver;
+import org.sonar.batch.bootstrap.AnalysisMode;
public class InputFileBuilderFactory implements BatchComponent {
private final PathResolver pathResolver;
private final LanguageDetectionFactory langDetectionFactory;
private final StatusDetectionFactory statusDetectionFactory;
+ private final AnalysisMode analysisMode;
public InputFileBuilderFactory(Project moduleDef, PathResolver pathResolver, LanguageDetectionFactory langDetectionFactory,
- StatusDetectionFactory statusDetectionFactory) {
+ StatusDetectionFactory statusDetectionFactory, AnalysisMode analysisMode) {
this.moduleKey = moduleDef.getEffectiveKey();
this.pathResolver = pathResolver;
this.langDetectionFactory = langDetectionFactory;
this.statusDetectionFactory = statusDetectionFactory;
+ this.analysisMode = analysisMode;
}
InputFileBuilder create(DefaultModuleFileSystem fs) {
- return new InputFileBuilder(moduleKey, pathResolver, langDetectionFactory.create(), statusDetectionFactory.create(), fs);
+ return new InputFileBuilder(moduleKey, pathResolver, langDetectionFactory.create(), statusDetectionFactory.create(), fs, analysisMode);
}
}
package org.sonar.batch.scan.filesystem;
import org.sonar.api.BatchComponent;
-import org.sonar.api.scan.filesystem.InputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.FileIndex;
+import org.sonar.api.batch.fs.internal.RelativePathIndex;
import org.sonar.batch.index.Cache;
import org.sonar.batch.index.Caches;
import javax.annotation.CheckForNull;
-import java.util.Set;
-
/**
* Cache of all files. This cache is shared amongst all project modules. Inclusion and
* exclusion patterns are already applied.
*/
public class InputFileCache implements BatchComponent {
- // module key -> path -> InputFile
- private final Cache<String, InputFile> cache;
+ // [path type | module key | path] -> InputFile
+ // For example:
+ // [rel | struts-core | src/main/java/Action.java] -> InputFile
+ // [rel | struts-core | src/main/java/Filter.java] -> InputFile
+ // [abs | struts-core | /absolute/path/to/src/main/java/Action.java] -> InputFile
+ // [abs | struts-core | /absolute/path/to/src/main/java/Filter.java] -> InputFile
+ private final Cache<InputFile> cache;
public InputFileCache(Caches caches) {
cache = caches.createCache("inputFiles");
}
- public Iterable<InputFile> byModule(String moduleKey) {
- return cache.values(moduleKey);
+ public Iterable<InputFile> all() {
+ return cache.values();
}
- @CheckForNull
- public InputFile byPath(String moduleKey, String path) {
- return cache.get(moduleKey, path);
+ public Iterable<InputFile> byModule(String moduleKey) {
+ return cache.values(moduleKey);
}
public InputFileCache removeModule(String moduleKey) {
return this;
}
- public InputFileCache remove(String moduleKey, String relativePath) {
- cache.remove(moduleKey, relativePath);
+ public InputFileCache remove(String moduleKey, InputFile inputFile) {
+ cache.remove(moduleKey, inputFile.relativePath());
return this;
}
- public Iterable<InputFile> all() {
- return cache.allValues();
+ public InputFileCache put(String moduleKey, InputFile inputFile) {
+ cache.put(moduleKey, inputFile.relativePath(), inputFile);
+ return this;
}
- public Set<String> fileRelativePaths(String moduleKey) {
- return cache.keySet(moduleKey);
- }
- public boolean containsFile(String moduleKey, String relativePath) {
- return cache.containsKey(moduleKey, relativePath);
+ public void index(String moduleKey, String indexId, Object indexValue, InputFile inputFile) {
+ // already indexed by relative path is already used
+ if (!indexId.equals(RelativePathIndex.ID)) {
+ // See limitation of org.sonar.batch.index.Cache -> fail
+ // to traverse a sub-tree, for example in order to
+ // have the following structure in InputFileCache :
+ // [index id|module key|index value]
+ throw new UnsupportedOperationException("Only relative path index is supported yet");
+ }
}
- public InputFileCache put(String moduleKey, InputFile file) {
- cache.put(moduleKey, file.path(), file);
- return this;
+ @CheckForNull
+ public InputFile get(String moduleKey, String indexId, Object indexValue) {
+ if (!indexId.equals(RelativePathIndex.ID)) {
+ throw new UnsupportedOperationException("Only relative path index is supported yet");
+ }
+ return cache.get(moduleKey, indexValue);
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.PathPattern;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
-import org.sonar.api.scan.filesystem.InputFile;
import org.sonar.api.utils.MessageException;
import javax.annotation.CheckForNull;
break;
} else {
// Language was already forced by another pattern
- throw MessageException.of("Language of file '" + inputFile.path() + "' can not be decided as the file matches patterns of both " + getDetails(detectedLanguage)
+ throw MessageException.of("Language of file '" + inputFile.relativePath() + "' can not be decided as the file matches patterns of both " + getDetails(detectedLanguage)
+ " and " + getDetails(languageKey));
}
}
}
}
if (detectedLanguage != null) {
- LOG.debug("Language of file '" + inputFile.path() + "' was detected to be '" + detectedLanguage + "'");
+ LOG.debug("Language of file '" + inputFile.relativePath() + "' was detected to be '" + detectedLanguage + "'");
return detectedLanguage;
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.scan.filesystem;
+
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.UniqueIndexPredicate;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.resources.Project;
+
+public class ModuleInputFileCache extends DefaultFileSystem.Cache implements BatchComponent {
+
+ private final String moduleKey;
+ private final InputFileCache projectCache;
+
+ public ModuleInputFileCache(Project module, InputFileCache projectCache) {
+ this.moduleKey = module.getKey();
+ this.projectCache = projectCache;
+ }
+
+ @Override
+ protected Iterable<InputFile> inputFiles() {
+ return projectCache.byModule(moduleKey);
+ }
+
+ @Override
+ protected InputFile inputFile(UniqueIndexPredicate predicate) {
+ return projectCache.get(moduleKey, predicate.indexId(), predicate.value());
+ }
+
+ @Override
+ protected void doAdd(InputFile inputFile) {
+ projectCache.put(moduleKey, inputFile);
+ }
+
+ @Override
+ protected void doIndex(String indexId, Object value, InputFile inputFile) {
+ projectCache.index(moduleKey, indexId, value, inputFile);
+ }
+}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.scan.filesystem;
-
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.utils.PathUtils;
-import org.sonar.api.utils.WildcardPattern;
-
-import java.io.File;
-
-abstract class PathPattern {
-
- private static final Logger LOG = LoggerFactory.getLogger(PathPattern.class);
-
- final WildcardPattern pattern;
-
- PathPattern(String pattern) {
- this.pattern = WildcardPattern.create(pattern);
- }
-
- abstract boolean match(Resource resource);
-
- abstract boolean match(InputFile inputFile);
-
- abstract boolean match(File ioFile, String relativePathFromBasedir);
-
- abstract boolean match(InputFile inputFile, boolean caseSensitiveFileExtension);
-
- abstract boolean supportResource();
-
- static PathPattern create(String s) {
- String trimmed = StringUtils.trim(s);
- if (StringUtils.startsWithIgnoreCase(trimmed, "file:")) {
- LOG.warn("Absolute path patterns are deprecated. Please replace {} by a path pattern relative to the basedir of the module.", trimmed);
- return new AbsolutePathPattern(StringUtils.substring(trimmed, "file:".length()));
- }
- return new RelativePathPattern(trimmed);
- }
-
- static PathPattern[] create(String[] s) {
- PathPattern[] result = new PathPattern[s.length];
- for (int i = 0; i < s.length; i++) {
- result[i] = create(s[i]);
- }
- return result;
- }
-
- /**
- * @deprecated since 4.2
- */
- @Deprecated
- private static class AbsolutePathPattern extends PathPattern {
- private AbsolutePathPattern(String pattern) {
- super(pattern);
- }
-
- @Override
- boolean match(File ioFile, String relativePathFromBasedir) {
- String path = PathUtils.canonicalPath(ioFile);
- return pattern.match(path);
- }
-
- @Override
- boolean match(InputFile inputFile) {
- return match(inputFile, true);
- }
-
- @Override
- boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
- String path = inputFile.absolutePath();
- if (!caseSensitiveFileExtension) {
- String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
- if (StringUtils.isNotBlank(extension)) {
- StringUtils.removeEndIgnoreCase(path, extension);
- path = path + extension;
- }
- }
- return pattern.match(path);
- }
-
- @Override
- boolean match(Resource resource) {
- return false;
- }
-
- @Override
- boolean supportResource() {
- return false;
- }
-
- @Override
- public String toString() {
- return "file:" + pattern.toString();
- }
- }
-
- /**
- * Path relative to module basedir
- */
- private static class RelativePathPattern extends PathPattern {
- private RelativePathPattern(String pattern) {
- super(pattern);
- }
-
- @Override
- boolean match(File ioFile, String relativePathFromBasedir) {
- return relativePathFromBasedir != null && pattern.match(relativePathFromBasedir);
- }
-
- @Override
- boolean match(InputFile inputFile) {
- return match(inputFile, true);
- }
-
- @Override
- boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
- String path = inputFile.path();
- if (!caseSensitiveFileExtension) {
- String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
- if (StringUtils.isNotBlank(extension)) {
- path = StringUtils.removeEndIgnoreCase(path, extension);
- path = path + extension;
- }
- }
- return path != null && pattern.match(path);
- }
-
- @Override
- boolean match(Resource resource) {
- return resource.matchFilePattern(pattern.toString());
- }
-
- @Override
- boolean supportResource() {
- return true;
- }
-
- @Override
- public String toString() {
- return pattern.toString();
- }
- }
-
- static String sanitizeExtension(String suffix) {
- return StringUtils.lowerCase(StringUtils.removeStart(suffix, "."));
- }
-}
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
+import java.util.Arrays;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.CharEncoding;
import org.apache.maven.project.MavenProject;
-import org.sonar.api.resources.InputFile;
-import org.sonar.api.resources.InputFileUtils;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.Language;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.ProjectFileSystem;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.scan.filesystem.FileQuery;
+import org.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.resources.*;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.api.utils.SonarException;
import javax.annotation.Nullable;
-
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
}
public List<File> getSourceFiles(Language... langs) {
- List<File> result = Lists.newArrayList();
- for (Language lang : langs) {
- result.addAll(target.files(FileQuery.onMain().onLanguage(lang.getKey())));
- }
- return result;
+ return Lists.newArrayList(target.files(FilePredicates.and(
+ FilePredicates.hasType(org.sonar.api.batch.fs.InputFile.Type.MAIN),
+ newHasLanguagesPredicate(langs))));
}
public List<File> getJavaSourceFiles() {
}
public List<File> getTestFiles(Language... langs) {
- List<File> result = Lists.newArrayList();
- for (Language lang : langs) {
- result.addAll(target.files(FileQuery.onTest().onLanguage(lang.getKey())));
- }
- return result;
+ return Lists.newArrayList(target.files(FilePredicates.and(
+ FilePredicates.hasType(org.sonar.api.batch.fs.InputFile.Type.TEST),
+ newHasLanguagesPredicate(langs))));
}
public boolean hasTestFiles(Language lang) {
- return !getTestFiles(lang).isEmpty();
+ return target.hasFiles(FilePredicates.and(
+ FilePredicates.hasType(org.sonar.api.batch.fs.InputFile.Type.TEST),
+ FilePredicates.hasLanguage(lang.getKey())));
}
public File writeToWorkingDirectory(String content, String fileName) throws IOException {
}
public List<InputFile> mainFiles(String... langs) {
- List<InputFile> result = Lists.newArrayList();
- Iterable<org.sonar.api.scan.filesystem.InputFile> files = target.inputFiles(FileQuery.onMain().onLanguage(langs));
- for (org.sonar.api.scan.filesystem.InputFile file : files) {
- String sourceDir = file.attribute(org.sonar.api.scan.filesystem.internal.DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH);
- String sourceRelativePath = file.attribute(org.sonar.api.scan.filesystem.internal.DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH);
- if (sourceDir != null && sourceRelativePath != null) {
- result.add(InputFileUtils.create(new File(sourceDir), sourceRelativePath));
- } else {
- result.add(InputFileUtils.create(target.baseDir(), file.path()));
- }
- }
- return result;
+ return Lists.newArrayList((Iterable) target.inputFiles(FilePredicates.and(
+ FilePredicates.hasType(org.sonar.api.batch.fs.InputFile.Type.MAIN),
+ FilePredicates.hasLanguages(Arrays.asList(langs))
+ )));
+
}
public List<InputFile> testFiles(String... langs) {
- List<InputFile> result = Lists.newArrayList();
- Iterable<org.sonar.api.scan.filesystem.InputFile> files = target.inputFiles(FileQuery.onTest().onLanguage(langs));
- for (org.sonar.api.scan.filesystem.InputFile file : files) {
- String sourceDir = file.attribute(org.sonar.api.scan.filesystem.internal.DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH);
- String sourceRelativePath = file.attribute(org.sonar.api.scan.filesystem.internal.DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH);
- if (sourceDir != null && sourceRelativePath != null) {
- result.add(InputFileUtils.create(new File(sourceDir), sourceRelativePath));
- } else {
- result.add(InputFileUtils.create(target.baseDir(), file.path()));
- }
+ return Lists.newArrayList((Iterable) target.inputFiles(FilePredicates.and(
+ FilePredicates.hasType(org.sonar.api.batch.fs.InputFile.Type.TEST),
+ FilePredicates.hasLanguages(Arrays.asList(langs))
+ )));
+ }
+
+ private static FilePredicate newHasLanguagesPredicate(Language... languages) {
+ List<FilePredicate> list = Lists.newArrayList();
+ for (Language language : languages) {
+ list.add(FilePredicates.hasLanguage(language.getKey()));
}
- return result;
+ return FilePredicates.or(list);
}
}
package org.sonar.batch.scan.filesystem;
import org.apache.commons.lang.StringUtils;
-import org.sonar.api.scan.filesystem.InputFile;
+import org.sonar.api.batch.fs.InputFile;
import java.util.Map;
this.previousHashByRelativePath = previousHashByRelativePath;
}
- String status(String relativePath, String hash) {
+ InputFile.Status status(String relativePath, String hash) {
String previousHash = previousHashByRelativePath.get(relativePath);
if (StringUtils.equals(hash, previousHash)) {
- return InputFile.STATUS_SAME;
+ return InputFile.Status.SAME;
}
if (StringUtils.isEmpty(previousHash)) {
- return InputFile.STATUS_ADDED;
+ return InputFile.Status.ADDED;
}
- return InputFile.STATUS_CHANGED;
+ return InputFile.Status.CHANGED;
}
}
*/
package org.sonar.batch.scan.language;
+import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.utils.MessageException;
-import org.sonar.api.utils.SonarException;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.List;
/**
* Give access to all languages detected on the current module
+ *
* @since 4.2
*/
public class DefaultModuleLanguages implements ModuleLanguages {
private static final Logger LOG = LoggerFactory.getLogger(DefaultModuleLanguages.class);
- private Map<String, Language> moduleLanguages = new HashMap<String, Language>();
-
- private Languages languages;
+ private final List<String> moduleLanguages = Lists.newArrayList();
public DefaultModuleLanguages(Settings settings, Languages languages) {
- this.languages = languages;
if (settings.hasKey(CoreProperties.PROJECT_LANGUAGE_PROPERTY)) {
String languageKey = settings.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY);
LOG.info("Language is forced to {}", languageKey);
}
public void addLanguage(String languageKey) {
- Language language = languages.get(languageKey);
- if (language == null) {
- throw new SonarException("Language with key '" + languageKey + "' not found");
- }
- moduleLanguages.put(languageKey, language);
+ moduleLanguages.add(languageKey);
}
+ @Override
public Collection<String> keys() {
- return moduleLanguages.keySet();
- }
-
- public Collection<Language> languages() {
- return moduleLanguages.values();
+ return moduleLanguages;
}
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.scan.report;
-
-import org.sonar.api.issue.Issue;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.batch.scan.filesystem.InputFileCache;
-
-import java.util.Set;
-
-abstract class ComponentSelector {
-
- private final InputFileCache cache;
-
- ComponentSelector(InputFileCache cache) {
- this.cache = cache;
- }
-
- public InputFileCache getCache() {
- return cache;
- }
-
- abstract void init();
-
- abstract boolean register(Issue issue);
-
- abstract Set<String> componentKeys();
-
- InputFile component(String componentKey) {
- String moduleKey = org.apache.commons.lang.StringUtils.substringBeforeLast(componentKey, ":");
- String path = org.apache.commons.lang.StringUtils.substringAfterLast(componentKey, ":");
- return cache.byPath(moduleKey, path);
- }
-}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.platform.Server;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.ModuleFileSystem;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.scan.filesystem.InputFileCache;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
+import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
private static final Logger LOG = LoggerFactory.getLogger(JsonReport.class);
private final Settings settings;
- private final ModuleFileSystem fileSystem;
+ private final FileSystem fileSystem;
private final Server server;
private final RuleFinder ruleFinder;
private final IssueCache issueCache;
private final InputFileCache fileCache;
private final Project rootModule;
- public JsonReport(Settings settings, ModuleFileSystem fileSystem, Server server, RuleFinder ruleFinder, IssueCache issueCache,
- EventBus eventBus, AnalysisMode analysisMode, UserFinder userFinder, Project rootModule, InputFileCache fileCache) {
+ public JsonReport(Settings settings, FileSystem fileSystem, Server server, RuleFinder ruleFinder, IssueCache issueCache,
+ EventBus eventBus, AnalysisMode analysisMode, UserFinder userFinder, Project rootModule, InputFileCache fileCache) {
this.settings = settings;
this.fileSystem = fileSystem;
this.server = server;
}
private void exportResults() {
- File exportFile = new File(fileSystem.workingDir(), settings.getString("sonar.report.export.path"));
+ File exportFile = new File(fileSystem.workDir(), settings.getString("sonar.report.export.path"));
LOG.info("Export results to " + exportFile.getAbsolutePath());
Writer output = null;
writeJsonModuleComponents(json, rootModule);
// TODO we need to dump directories
for (InputFile inputFile : fileCache.all()) {
+ String key = ((DefaultInputFile) inputFile).key();
json
.beginObject()
- .prop("key", inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY))
- .prop("path", inputFile.path())
- .prop("moduleKey", StringUtils.substringBeforeLast(inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY), ":"))
- .prop("status", inputFile.attribute(InputFile.ATTRIBUTE_STATUS))
+ .prop("key", key)
+ .prop("path", inputFile.relativePath())
+ .prop("moduleKey", StringUtils.substringBeforeLast(key, ":"))
+ .prop("status", inputFile.status().name())
.endObject();
}
json.endArray();
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.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class CacheTest {
- @ClassRule
- public static TemporaryFolder temp = new TemporaryFolder();
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
Caches caches;
}
@Test
- public void test_put_get_remove() throws Exception {
- Cache<String, String> cache = caches.createCache("issues");
- assertThat(cache.get("foo")).isNull();
- cache.put("foo", "bar");
- assertThat(cache.get("foo")).isEqualTo("bar");
- assertThat(cache.keySet()).containsOnly("foo");
- cache.remove("foo");
- assertThat(cache.get("foo")).isNull();
- assertThat(cache.keySet()).isEmpty();
+ public void one_part_key() throws Exception {
+ Cache<String> cache = caches.createCache("capitals");
+
+ assertThat(cache.get("france")).isNull();
+
+ cache.put("france", "paris");
+ cache.put("italy", "rome");
+ assertThat(cache.get("france")).isEqualTo("paris");
+ assertThat(cache.keySet()).containsOnly("france", "italy");
+ assertThat(cache.keySet("france")).isEmpty();
+ assertThat(cache.values()).containsOnly("paris", "rome");
+ assertThat(cache.containsKey("france")).isTrue();
+
+ Cache.Entry[] entries = Iterables.toArray(cache.<String>entries(), Cache.Entry.class);
+ assertThat(entries).hasSize(2);
+ assertThat(entries[0].key()[0]).isEqualTo("france");
+ assertThat(entries[0].value()).isEqualTo("paris");
+ assertThat(entries[1].key()[0]).isEqualTo("italy");
+ assertThat(entries[1].value()).isEqualTo("rome");
+
+ cache.remove("france");
+ assertThat(cache.get("france")).isNull();
+ assertThat(cache.get("italy")).isEqualTo("rome");
+ assertThat(cache.keySet()).containsOnly("italy");
+ assertThat(cache.keySet("france")).isEmpty();
+ assertThat(cache.containsKey("france")).isFalse();
+ assertThat(cache.containsKey("italy")).isTrue();
+ assertThat(cache.values()).containsOnly("rome");
+
+ cache.clear();
+ assertThat(cache.values()).isEmpty();
}
@Test
public void test_key_being_prefix_of_another_key() throws Exception {
- Cache<String, String> cache = caches.createCache("components");
+ Cache<String> cache = caches.createCache("components");
cache.put("struts-el:org.apache.strutsel.taglib.html.ELButtonTag", "the Tag");
cache.put("struts-el:org.apache.strutsel.taglib.html.ELButtonTagBeanInfo", "the BeanInfo");
}
@Test
- public void test_put_get_remove_on_groups() throws Exception {
- Cache<String, Float> cache = caches.createCache("measures");
- String group = "org/apache/struts/Action.java";
- assertThat(cache.get(group, "ncloc")).isNull();
- cache.put(group, "ncloc", 123f);
- assertThat(cache.get(group, "ncloc")).isEqualTo(123f);
- assertThat(cache.keySet(group)).containsOnly("ncloc");
- assertThat(cache.containsKey(group, "ncloc")).isTrue();
- assertThat(cache.get("ncloc")).isNull();
- assertThat(cache.get(group)).isNull();
- cache.remove(group, "ncloc");
- assertThat(cache.get(group, "ncloc")).isNull();
- assertThat(cache.keySet(group)).isEmpty();
- assertThat(cache.containsKey(group, "ncloc")).isFalse();
- }
-
- @Test
- public void test_clear_group() throws Exception {
- Cache<String, Float> cache = caches.createCache("measures");
- String group = "org/apache/struts/Action.java";
- cache.put(group, "ncloc", 123f);
- cache.put(group, "lines", 200f);
- cache.put("otherGroup", "lines", 400f);
- assertThat(cache.get(group, "lines")).isNotNull();
- assertThat(cache.get("otherGroup", "lines")).isNotNull();
-
- cache.clear(group);
- assertThat(cache.get(group, "lines")).isNull();
- assertThat(cache.get("otherGroup", "lines")).isNotNull();
- }
-
- @Test
- public void test_operations_on_empty_cache() throws Exception {
- Cache<String, String> cache = caches.createCache("issues");
- assertThat(cache.get("foo")).isNull();
- assertThat(cache.get("group", "foo")).isNull();
+ public void two_parts_key() throws Exception {
+ Cache<String> cache = caches.createCache("capitals");
+
+ assertThat(cache.get("europe", "france")).isNull();
+
+ cache.put("europe", "france", "paris");
+ cache.put("europe", "italy", "rome");
+ assertThat(cache.get("europe")).isNull();
+ assertThat(cache.get("europe", "france")).isEqualTo("paris");
+ assertThat(cache.get("europe", "italy")).isEqualTo("rome");
+ assertThat(cache.get("europe")).isNull();
+ assertThat(cache.keySet("europe")).containsOnly("france", "italy");
+ assertThat(cache.keySet()).containsOnly("europe");
+ assertThat(cache.containsKey("europe")).isFalse();
+ assertThat(cache.containsKey("europe", "france")).isTrue();
+ assertThat(cache.containsKey("europe", "spain")).isFalse();
+ assertThat(cache.values()).containsOnly("paris", "rome");
+ assertThat(cache.values("america")).isEmpty();
+ assertThat(cache.values("europe")).containsOnly("paris", "rome");
+ assertThat(cache.values("oceania")).isEmpty();
+
+ Cache.Entry[] allEntries = Iterables.toArray(cache.<String>entries(), Cache.Entry.class);
+ assertThat(allEntries).hasSize(2);
+ assertThat(allEntries[0].key()).isEqualTo(new String[]{"europe", "france"});
+ assertThat(allEntries[0].value()).isEqualTo("paris");
+ assertThat(allEntries[1].key()).isEqualTo(new String[]{"europe", "italy"});
+ assertThat(allEntries[1].value()).isEqualTo("rome");
+
+ Cache.SubEntry[] subEntries = Iterables.toArray(cache.<String>subEntries("europe"), Cache.SubEntry.class);
+ assertThat(subEntries).hasSize(2);
+ assertThat(subEntries[0].keyAsString()).isEqualTo("france");
+ assertThat(subEntries[0].value()).isEqualTo("paris");
+ assertThat(subEntries[1].keyAsString()).isEqualTo("italy");
+ assertThat(subEntries[1].value()).isEqualTo("rome");
+
+ cache.remove("europe", "france");
+ assertThat(cache.values()).containsOnly("rome");
+ assertThat(cache.get("europe", "france")).isNull();
+ assertThat(cache.get("europe", "italy")).isEqualTo("rome");
+ assertThat(cache.containsKey("europe", "france")).isFalse();
+ assertThat(cache.keySet("europe")).containsOnly("italy");
+
+ cache.clear("america");
+ assertThat(cache.keySet()).containsOnly("europe");
+ cache.clear("europe");
assertThat(cache.keySet()).isEmpty();
- assertThat(cache.keySet("group")).isEmpty();
- assertThat(cache.values()).isEmpty();
- assertThat(cache.values("group")).isEmpty();
-
- // do not fail
- cache.remove("foo");
- cache.remove("group", "foo");
- cache.clear();
- cache.clear("group");
- cache.clearAll();
}
@Test
- public void test_get_missing_key() {
- Cache<String, String> cache = caches.createCache("issues");
- assertThat(cache.get("foo")).isNull();
- }
-
- @Test
- public void test_keyset_of_group() {
- Cache<String, Float> 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);
- assertThat(cache.keySet("org/apache/struts/Action.java")).containsOnly("ncloc", "lines");
- assertThat(cache.keySet("org/apache/struts/Filter.java")).containsOnly("coverage");
- }
-
- @Test
- public void test_values_of_group() {
- Cache<String, Float> 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);
- assertThat(cache.values("org/apache/struts/Action.java")).containsOnly(123f, 200f);
- assertThat(cache.values("org/apache/struts/Filter.java")).containsOnly(500f);
- assertThat(cache.values("other")).isEmpty();
- }
-
- @Test
- public void test_values() {
- Cache<String, Float> cache = caches.createCache("measures");
- cache.put("ncloc", 123f);
- cache.put("lines", 200f);
- assertThat(cache.values()).containsOnly(123f, 200f);
- }
-
- @Test
- public void test_all_values() {
- Cache<String, Float> 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);
- cache.put("org/apache/struts/Filter.java", "lines", 500f);
-
- assertThat(cache.allValues()).containsOnly(123f, 200f, 400f, 500f);
+ public void three_parts_key() throws Exception {
+ Cache<String> cache = caches.createCache("places");
+ assertThat(cache.get("europe", "france", "paris")).isNull();
+
+ cache.put("europe", "france", "paris", "eiffel tower");
+ cache.put("europe", "france", "annecy", "lake");
+ cache.put("europe", "italy", "rome", "colosseum");
+ assertThat(cache.get("europe")).isNull();
+ assertThat(cache.get("europe", "france")).isNull();
+ assertThat(cache.get("europe", "france", "paris")).isEqualTo("eiffel tower");
+ assertThat(cache.get("europe", "france", "annecy")).isEqualTo("lake");
+ assertThat(cache.get("europe", "italy", "rome")).isEqualTo("colosseum");
+ assertThat(cache.keySet()).containsOnly("europe");
+ assertThat(cache.keySet("europe")).containsOnly("france", "italy");
+ assertThat(cache.keySet("europe", "france")).containsOnly("annecy", "paris");
+ assertThat(cache.containsKey("europe")).isFalse();
+ assertThat(cache.containsKey("europe", "france")).isFalse();
+ assertThat(cache.containsKey("europe", "france", "annecy")).isTrue();
+ assertThat(cache.containsKey("europe", "france", "biarritz")).isFalse();
+ assertThat(cache.values()).containsOnly("eiffel tower", "lake", "colosseum");
+
+ Cache.Entry[] allEntries = Iterables.toArray(cache.<String>entries(), Cache.Entry.class);
+ assertThat(allEntries).hasSize(3);
+ assertThat(allEntries[0].key()).isEqualTo(new String[]{"europe", "france", "annecy"});
+ assertThat(allEntries[0].value()).isEqualTo("lake");
+ assertThat(allEntries[1].key()).isEqualTo(new String[]{"europe", "france", "paris"});
+ assertThat(allEntries[1].value()).isEqualTo("eiffel tower");
+ assertThat(allEntries[2].key()).isEqualTo(new String[]{"europe", "italy", "rome"});
+ assertThat(allEntries[2].value()).isEqualTo("colosseum");
+
+ Cache.SubEntry[] subEntries = Iterables.toArray(cache.<String>subEntries("europe"), Cache.SubEntry.class);
+ assertThat(subEntries).hasSize(2);
+ assertThat(subEntries[0].keyAsString()).isEqualTo("france");
+ assertThat(subEntries[0].value()).isNull();
+ assertThat(subEntries[1].keyAsString()).isEqualTo("italy");
+ assertThat(subEntries[1].value()).isNull();
+
+ cache.remove("europe", "france", "annecy");
+ assertThat(cache.values()).containsOnly("eiffel tower", "colosseum");
+ assertThat(cache.get("europe", "france", "annecy")).isNull();
+ assertThat(cache.get("europe", "italy", "rome")).isEqualTo("colosseum");
+ assertThat(cache.containsKey("europe", "france")).isFalse();
+
+ cache.clear("europe", "italy");
+ assertThat(cache.values()).containsOnly("eiffel tower");
+
+ cache.clear("europe");
+ assertThat(cache.values()).isEmpty();
}
@Test
- public void test_groups() {
- Cache<String, Float> cache = caches.createCache("issues");
- assertThat(cache.groups()).isEmpty();
+ public void remove_versus_clear() throws Exception {
+ Cache<String> cache = caches.createCache("capitals");
+ cache.put("europe", "france", "paris");
+ cache.put("europe", "italy", "rome");
- 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);
+ // remove("europe") does not remove sub-keys
+ cache.remove("europe");
+ assertThat(cache.values()).containsOnly("paris", "rome");
- assertThat(cache.groups()).containsOnly("org/apache/struts/Action.java", "org/apache/struts/Filter.java");
+ // clear("europe") removes sub-keys
+ cache.clear("europe");
+ assertThat(cache.values()).isEmpty();
}
@Test
- public void test_entries() throws PersistitException {
- Cache<String, Float> 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.<Float>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);
- }
+ public void empty_cache() throws Exception {
+ Cache<String> cache = caches.createCache("empty");
- @Test
- public void test_entries_of_group() throws PersistitException {
- Cache<String, Float> 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);
+ assertThat(cache.get("foo")).isNull();
+ assertThat(cache.get("foo", "bar")).isNull();
+ assertThat(cache.get("foo", "bar", "baz")).isNull();
+ assertThat(cache.keySet()).isEmpty();
+ assertThat(cache.keySet("foo")).isEmpty();
+ assertThat(cache.containsKey("foo")).isFalse();
+ assertThat(cache.containsKey("foo", "bar")).isFalse();
+ assertThat(cache.containsKey("foo", "bar", "baz")).isFalse();
+ assertThat(cache.values()).isEmpty();
+ assertThat(cache.values("foo")).isEmpty();
- Cache.Entry[] entries = Iterables.toArray(cache.<Float>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);
+ // do not fail
+ cache.remove("foo");
+ cache.remove("foo", "bar");
+ cache.remove("foo", "bar", "baz");
+ cache.clear("foo");
+ cache.clear("foo", "bar");
+ cache.clear("foo", "bar", "baz");
+ cache.clear();
}
}
@Test
public void should_create_cache() throws Exception {
caches.start();
- Cache<String, Element> cache = caches.createCache("foo");
+ Cache<Element> cache = caches.createCache("foo");
assertThat(cache).isNotNull();
}
@Test
public void should_not_create_cache_twice() throws Exception {
caches.start();
- caches.<String, Element>createCache("foo");
+ caches.<Element>createCache("foo");
try {
- caches.<String, Element>createCache("foo");
+ caches.<Element>createCache("foo");
fail();
} catch (IllegalStateException e) {
// ok
*/
package org.sonar.batch.index;
-import com.google.common.base.Charsets;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.resources.Project;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
-import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
import org.sonar.jpa.test.AbstractDbUnitTestCase;
import java.io.File;
File file = new File(baseDir, path);
String effectiveKey = module.getKey() + ":" + path;
String deprecatedEffectiveKey = module.getKey() + ":" + deprecatedKey;
- return new InputFileBuilder(file, Charsets.UTF_8, path)
- .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, effectiveKey)
- .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_DEPRECATED_KEY, deprecatedEffectiveKey)
- .attribute(InputFile.ATTRIBUTE_TYPE, isTest ? InputFile.TYPE_TEST : InputFile.TYPE_MAIN).build();
+ return new DefaultInputFile(path).setFile(file)
+ .setKey(effectiveKey)
+ .setDeprecatedKey(deprecatedEffectiveKey)
+ .setType(isTest ? InputFile.Type.TEST : InputFile.Type.MAIN);
}
@Test
verify(logger).info("Migrated resource {} to {}", "b:org/foo", "b:src/main/java/org/foo");
verify(logger).info("Migrated resource {} to {}", "b:[root]", "b:src/main/java");
- checkTables("shouldMigrateResourceKeys", new String[] {"build_date", "created_at"}, "projects");
+ checkTables("shouldMigrateResourceKeys", new String[]{"build_date", "created_at"}, "projects");
}
private static Project newProject(String key, String language) {
package org.sonar.batch.issue.ignore.scanner;
-import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
-import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
-import org.sonar.batch.issue.ignore.pattern.PatternMatcher;
-import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader;
-import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner;
-
-import com.google.common.base.Charsets;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
-import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.utils.SonarException;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
+import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
+import org.sonar.batch.issue.ignore.pattern.PatternMatcher;
import java.io.File;
import java.io.IOException;
-import java.util.Arrays;
import static com.google.common.base.Charsets.UTF_8;
import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public class IssueExclusionsLoaderTest {
- private IssueExclusionsLoader scanner;
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
@Mock
private IssueExclusionsRegexpScanner regexpScanner;
+
@Mock
private IssueInclusionPatternInitializer inclusionPatternInitializer;
+
@Mock
private IssueExclusionPatternInitializer exclusionPatternInitializer;
+
@Mock
private PatternMatcher patternMatcher;
- @Mock
- private DefaultModuleFileSystem fs;
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- private File baseDir;
+ DefaultFileSystem fs = new DefaultFileSystem().setEncoding(UTF_8);
+ IssueExclusionsLoader scanner;
+ File baseDir;
@Before
- public void init() throws IOException {
+ public void before() throws IOException {
baseDir = temp.newFolder();
MockitoAnnotations.initMocks(this);
-
- when(fs.sourceCharset()).thenReturn(UTF_8);
-
scanner = new IssueExclusionsLoader(regexpScanner, exclusionPatternInitializer, inclusionPatternInitializer, fs);
}
}
@Test
- public void shouldAnalyseProject() throws IOException {
+ public void shouldAnalyzeProject() throws IOException {
File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
+ fs.add(new DefaultInputFile("src/main/java/Foo.java")
+ .setFile(javaFile1)
+ .setType(InputFile.Type.MAIN)
+ .setKey("polop:src/main/java/Foo.java"));
File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
- when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
- new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/Foo.java")
- .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/main/java/Foo.java")
- .build(),
- new InputFileBuilder(javaTestFile1, Charsets.UTF_8, "src/test/java/FooTest.java")
- .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/test/java/FooTest.java")
- .build()));
+ fs.add(new DefaultInputFile("src/test/java/FooTest.java")
+ .setFile(javaTestFile1)
+ .setType(InputFile.Type.TEST)
+ .setKey("polop:src/test/java/FooTest.java"));
when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
@Test
public void shouldAnalyseFilesOnlyWhenRegexConfigured() throws IOException {
File javaFile1 = new File(baseDir, "src/main/java/Foo.java");
+ fs.add(new DefaultInputFile("src/main/java/Foo.java")
+ .setFile(javaFile1)
+ .setType(InputFile.Type.MAIN)
+ .setKey("polop:src/main/java/Foo.java"));
File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java");
- when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
- new InputFileBuilder(javaFile1, Charsets.UTF_8, "src/main/java/Foo.java")
- .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/main/java/Foo.java")
- .build(),
- new InputFileBuilder(javaTestFile1, Charsets.UTF_8, "src/test/java/FooTest.java")
- .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/test/java/FooTest.java")
- .build()));
-
+ fs.add(new DefaultInputFile("src/test/java/FooTest.java")
+ .setFile(javaTestFile1)
+ .setType(InputFile.Type.TEST)
+ .setKey("polop:src/test/java/FooTest.java"));
when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(false);
scanner.execute();
@Test
public void shouldReportFailure() throws IOException {
File phpFile1 = new File(baseDir, "src/Foo.php");
- when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
- new InputFileBuilder(phpFile1, Charsets.UTF_8, "src/Foo.php")
- .attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY, "polop:src/Foo.php")
- .build()));
+ fs.add(new DefaultInputFile("src/Foo.php")
+ .setFile(phpFile1)
+ .setType(InputFile.Type.MAIN)
+ .setKey("polop:src/Foo.php"));
when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true);
doThrow(new IOException("BUG")).when(regexpScanner).scan("polop:src/Foo.php", phpFile1, UTF_8);
import org.slf4j.Logger;
import org.sonar.api.batch.ModuleLanguages;
import org.sonar.api.config.Settings;
-import org.sonar.api.resources.AbstractLanguage;
-import org.sonar.api.resources.Language;
-import org.sonar.api.utils.SonarException;
+import org.sonar.api.utils.MessageException;
import org.sonar.batch.rule.ModuleQProfiles;
import org.sonar.batch.rule.ModuleQProfiles.QProfile;
import java.util.Collections;
-import java.util.List;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public class ProfileLoggerTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
- private ModuleLanguages languages;
- private ModuleQProfiles profiles;
- private Settings settings;
+ ModuleLanguages languages;
+ ModuleQProfiles profiles;
+ Settings settings = new Settings();
@Before
- public void prepare() {
+ public void before() {
languages = mock(ModuleLanguages.class);
- List<Language> languageList = Lists.newArrayList();
- languageList.add(new AbstractLanguage("java", "Java") {
-
- @Override
- public String[] getFileSuffixes() {
- return null;
- }
- });
- languageList.add(new AbstractLanguage("cobol", "Cobol") {
-
- @Override
- public String[] getFileSuffixes() {
- return null;
- }
- });
- when(languages.languages()).thenReturn(languageList);
+ when(languages.keys()).thenReturn(Lists.newArrayList("java", "cobol"));
profiles = mock(ModuleQProfiles.class);
QProfile javaProfile = mock(QProfile.class);
QProfile cobolProfile = mock(QProfile.class);
when(cobolProfile.name()).thenReturn("My Cobol profile");
when(profiles.findByLanguage("cobol")).thenReturn(cobolProfile);
-
- settings = new Settings();
}
@Test
public void should_log_all_used_profiles() {
-
ProfileLogger profileLogger = new ProfileLogger(settings, languages, profiles);
Logger logger = mock(Logger.class);
profileLogger.execute(logger);
- verify(logger).info("Quality profile for {}: {}", "Java", "My Java profile");
- verify(logger).info("Quality profile for {}: {}", "Cobol", "My Cobol profile");
+ verify(logger).info("Quality profile for {}: {}", "java", "My Java profile");
+ verify(logger).info("Quality profile for {}: {}", "cobol", "My Cobol profile");
}
@Test
public void should_fail_if_default_profile_not_used() {
- settings.setProperty("sonar.profile", "Unknow");
+ settings.setProperty("sonar.profile", "Unknown");
ProfileLogger profileLogger = new ProfileLogger(settings, languages, profiles);
- thrown.expect(SonarException.class);
- thrown.expectMessage("sonar.profile was set to 'Unknow' but didn't match any profile for any language. Please check your configuration.");
+ thrown.expect(MessageException.class);
+ thrown.expectMessage("sonar.profile was set to 'Unknown' but didn't match any profile for any language. Please check your configuration.");
profileLogger.execute();
-
}
@Test
public void should_not_fail_if_no_language_on_project() {
- settings.setProperty("sonar.profile", "Unknow");
- when(languages.languages()).thenReturn(Collections.<Language>emptyList());
+ settings.setProperty("sonar.profile", "Unknown");
+ when(languages.keys()).thenReturn(Collections.<String>emptyList());
ProfileLogger profileLogger = new ProfileLogger(settings, languages, profiles);
*/
package org.sonar.batch.rule;
-import edu.emory.mathcs.backport.java.util.Collections;
+import java.util.Collections;
import org.junit.Test;
import org.sonar.api.batch.ModuleLanguages;
import org.sonar.api.batch.SensorContext;
public void no_qprofiles() throws Exception {
setupData("shared");
QualityProfileDao dao = new QualityProfileDao(getMyBatis());
- when(moduleQProfiles.findAll()).thenReturn(Collections.emptyList());
+ when(moduleQProfiles.findAll()).thenReturn(Collections.<ModuleQProfiles.QProfile>emptyList());
QProfileSensor sensor = new QProfileSensor(moduleQProfiles, moduleLanguages, dao);
assertThat(sensor.shouldExecuteOnProject(project)).isTrue();
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.scan.filesystem;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class AttributeFilterTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void should_check_attribute_value() throws Exception {
- AttributeFilter filter = new AttributeFilter("foo", Lists.newArrayList("one", "two"));
-
- assertThat(filter.key()).isEqualTo("foo");
- assertThat(filter.values()).containsOnly("one", "two");
- assertThat(filter.accept(DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "Why.java", ImmutableMap.of("foo", "two")))).isTrue();
- assertThat(filter.accept(DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "Where.java", ImmutableMap.of("foo", "three")))).isFalse();
- assertThat(filter.accept(DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "What.java", ImmutableMap.of("bar", "one")))).isFalse();
-
- }
-}
import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.SonarIndex;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
-import org.sonar.api.resources.AbstractLanguage;
-import org.sonar.api.resources.Java;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
-import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
+import org.sonar.api.resources.*;
import org.sonar.batch.index.ResourceKeyMigration;
import org.sonar.batch.scan.language.DefaultModuleLanguages;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
-import java.util.Arrays;
-import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
public class ComponentIndexerTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
- private File baseDir;
- private DefaultModuleFileSystem fs;
- private SonarIndex sonarIndex;
- private AbstractLanguage cobolLanguage;
- private Project project;
- private Settings settings;
+ File baseDir;
+ DefaultFileSystem fs = new DefaultFileSystem();
+ SonarIndex sonarIndex;
+ AbstractLanguage cobolLanguage;
+ Project project;
+ Settings settings;
- private String aClaess;
- private String explicacao;
+ String aClaess;
+ String explicacao;
@Before
public void prepare() throws IOException {
baseDir = temp.newFolder();
- fs = mock(DefaultModuleFileSystem.class);
sonarIndex = mock(SonarIndex.class);
project = mock(Project.class);
settings = new Settings();
@Test
public void should_index_java_files() throws IOException {
- when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
- newInputFile("src/main/java/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false),
- newInputFile("src/main/java2/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false),
- newInputFile("src/test/java/foo/bar/FooTest.java", "", "foo/bar/FooTest.java", "java", true)));
+ fs.add(newInputFile("src/main/java/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false));
+ fs.add(newInputFile("src/main/java2/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false));
+ fs.add(newInputFile("src/test/java/foo/bar/FooTest.java", "", "foo/bar/FooTest.java", "java", true));
Languages languages = new Languages(Java.INSTANCE);
ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages),
mock(InputFileCache.class));
@Test
public void should_index_cobol_files() throws IOException {
- when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
- newInputFile("src/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false),
- newInputFile("src2/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false),
- newInputFile("src/test/foo/bar/FooTest.cbl", "", "foo/bar/FooTest.cbl", "cobol", true)));
+ fs.add(newInputFile("src/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false));
+ fs.add(newInputFile("src2/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false));
+ fs.add(newInputFile("src/test/foo/bar/FooTest.cbl", "", "foo/bar/FooTest.cbl", "cobol", true));
Languages languages = new Languages(cobolLanguage);
ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages),
public void shouldImportSource() throws IOException {
settings.setProperty(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY, "true");
- when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
- newInputFile("src/main/java/foo/bar/Foo.java", "sample code", "foo/bar/Foo.java", "java", false)));
+ fs.add(newInputFile("src/main/java/foo/bar/Foo.java", "sample code", "foo/bar/Foo.java", "java", false));
Languages languages = new Languages(Java.INSTANCE);
ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages),
mock(InputFileCache.class));
}
@Test
- public void should_remove_byte_order_mark_character() throws Exception {
+ public void remove_byte_order_mark_character() throws Exception {
settings.setProperty(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY, "true");
File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java");
FileUtils.write(javaFile1, "\uFEFFpublic class Test", Charsets.UTF_8);
- when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(
- new InputFileBuilder(javaFile1, Charset.forName("UTF-8"), "src/main/java/foo/bar/Foo.java")
- .attribute(DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java")
- .attribute(InputFile.ATTRIBUTE_LANGUAGE, "java")
- .build()));
+ fs.add(new DefaultInputFile("src/main/java/foo/bar/Foo.java").setFile(javaFile1)
+ .setPathRelativeToSourceDir("foo/bar/Foo.java")
+ .setLanguage("java"));
Languages languages = new Languages(Java.INSTANCE);
ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages),
mock(InputFileCache.class));
private void fileEncodingTest(String encoding, String testFile) throws Exception {
settings.setProperty(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY, "true");
+ fs.setEncoding(Charset.forName(encoding));
File javaFile1 = new File(baseDir, "src/main/java/foo/bar/Foo.java");
FileUtils.copyFile(getFile(testFile), javaFile1);
- when(fs.inputFiles(FileQuery.all()))
- .thenReturn(
- (Iterable) Arrays.asList(
- new InputFileBuilder(javaFile1, Charset.forName(encoding), "src/main/java/foo/bar/Foo.java")
- .attribute(DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "foo/bar/Foo.java")
- .attribute(InputFile.ATTRIBUTE_LANGUAGE, "java")
- .build()));
+ fs.add(new DefaultInputFile("src/main/java/foo/bar/Foo.java")
+ .setFile(javaFile1)
+ .setPathRelativeToSourceDir("foo/bar/Foo.java")
+ .setLanguage("java"));
Languages languages = new Languages(Java.INSTANCE);
ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages),
mock(InputFileCache.class));
}));
}
- @Test
- public void should_compute_line_count() throws IOException {
- DefaultInputFile inputFile3lines = newInputFile("src/main/java/foo/bar/Foo1.java", "line1\nline2\nline3", "foo/bar/Foo1.java", "java", false);
- DefaultInputFile inputFileEmpty = newInputFile("src/main/java/foo/bar/Foo2.java", "", "foo/bar/Foo2.java", "java", false);
- DefaultInputFile inputFileEndsWithNewLine = newInputFile("src/main/java/foo/bar/Foo3.java", "line1\nline2\nline3\n", "foo/bar/Foo3.java", "java", false);
- DefaultInputFile inputFileMixedLineEnds = newInputFile("src/main/java/foo/bar/Foo4.java", "line1\r\r\nline3\r\n\nline5\r", "foo/bar/Foo4.java", "java", false);
- when(fs.inputFiles(FileQuery.all())).thenReturn((Iterable) Arrays.asList(inputFile3lines, inputFileEmpty, inputFileEndsWithNewLine, inputFileMixedLineEnds));
- Languages languages = new Languages(Java.INSTANCE);
- ComponentIndexer indexer = new ComponentIndexer(project, languages, sonarIndex, settings, mock(ResourceKeyMigration.class), new DefaultModuleLanguages(settings, languages),
- mock(InputFileCache.class));
- indexer.execute(fs);
-
- assertThat(inputFile3lines.attribute(InputFile.ATTRIBUTE_LINE_COUNT)).isEqualTo("3");
- assertThat(inputFileEmpty.attribute(InputFile.ATTRIBUTE_LINE_COUNT)).isEqualTo("1");
- assertThat(inputFileEndsWithNewLine.attribute(InputFile.ATTRIBUTE_LINE_COUNT)).isEqualTo("4");
- assertThat(inputFileMixedLineEnds.attribute(InputFile.ATTRIBUTE_LINE_COUNT)).isEqualTo("6");
- }
private File getFile(String testFile) {
- return new File("test-resources/org/sonar/batch/phases/FileIndexerTest/encoding/" + testFile);
+ return new File("test-resources/org/sonar/batch/phases/ComponentIndexerTest/encoding/" + testFile);
}
private DefaultInputFile newInputFile(String path, String content, String sourceRelativePath, String languageKey, boolean unitTest) throws IOException {
File file = new File(baseDir, path);
FileUtils.write(file, content);
- return new InputFileBuilder(file, Charsets.UTF_8, path)
- .attribute(DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, sourceRelativePath)
- .attribute(InputFile.ATTRIBUTE_LANGUAGE, languageKey)
- .attribute(InputFile.ATTRIBUTE_TYPE, unitTest ? InputFile.TYPE_TEST : InputFile.TYPE_MAIN)
- .build();
+ return new DefaultInputFile(path).setFile(file)
+ .setPathRelativeToSourceDir(sourceRelativePath)
+ .setLanguage(languageKey)
+ .setType(unitTest ? InputFile.Type.TEST : InputFile.Type.MAIN);
}
}
*/
package org.sonar.batch.scan.filesystem;
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mockito;
import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Project;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
-import org.sonar.batch.bootstrap.AnalysisMode;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
-import java.util.List;
import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public class DefaultModuleFileSystemTest {
public ExpectedException thrown = ExpectedException.none();
Settings settings = new Settings();
- FileIndex fileIndex = mock(FileIndex.class);
+ FileIndexer fileIndexer = mock(FileIndexer.class);
ModuleFileSystemInitializer initializer = mock(ModuleFileSystemInitializer.class, Mockito.RETURNS_DEEP_STUBS);
- private AnalysisMode mode;
- private ComponentIndexer componentIndexer;
-
- @Before
- public void before() {
- mode = mock(AnalysisMode.class);
- componentIndexer = mock(ComponentIndexer.class);
- }
+ ComponentIndexer componentIndexer = mock(ComponentIndexer.class);
+ ModuleInputFileCache moduleInputFileCache = mock(ModuleInputFileCache.class);
@Test
public void test_equals_and_hashCode() throws Exception {
- DefaultModuleFileSystem foo1 = new DefaultModuleFileSystem(new Project("foo"), settings, fileIndex, initializer, mode, componentIndexer);
- DefaultModuleFileSystem foo2 = new DefaultModuleFileSystem(new Project("foo"), settings, fileIndex, initializer, mode, componentIndexer);
- DefaultModuleFileSystem bar = new DefaultModuleFileSystem(new Project("bar"), settings, fileIndex, initializer, mode, componentIndexer);
- DefaultModuleFileSystem branch = new DefaultModuleFileSystem(new Project("bar", "branch", "My project"), settings, fileIndex, initializer, mode, componentIndexer);
+ DefaultModuleFileSystem foo1 = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("foo"), settings, fileIndexer, initializer, componentIndexer);
+ DefaultModuleFileSystem foo2 = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("foo"), settings, fileIndexer, initializer, componentIndexer);
+ DefaultModuleFileSystem bar = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("bar"), settings, fileIndexer, initializer, componentIndexer);
+ DefaultModuleFileSystem branch = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("bar", "branch", "My project"), settings, fileIndexer, initializer, componentIndexer);
assertThat(foo1.moduleKey()).isEqualTo("foo");
assertThat(branch.moduleKey()).isEqualTo("bar:branch");
@Test
public void default_source_encoding() {
- DefaultModuleFileSystem fs = new DefaultModuleFileSystem(new Project("foo"), settings, fileIndex, initializer, mode, componentIndexer);
+ DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("foo"), settings, fileIndexer, initializer, componentIndexer);
assertThat(fs.sourceCharset()).isEqualTo(Charset.defaultCharset());
- assertThat(fs.isDefaultSourceCharset()).isTrue();
+ assertThat(fs.isDefaultJvmEncoding()).isTrue();
}
@Test
public void source_encoding_is_set() {
settings.setProperty(CoreProperties.ENCODING_PROPERTY, "Cp1124");
- DefaultModuleFileSystem fs = new DefaultModuleFileSystem(new Project("foo"), settings, fileIndex, initializer, mode, componentIndexer);
+ DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("foo"), settings, fileIndexer, initializer, componentIndexer);
+ assertThat(fs.encoding()).isEqualTo(Charset.forName("Cp1124"));
assertThat(fs.sourceCharset()).isEqualTo(Charset.forName("Cp1124"));
// This test fails when default Java encoding is "IBM AIX Ukraine". Sorry for that.
- assertThat(fs.isDefaultSourceCharset()).isFalse();
+ assertThat(fs.isDefaultJvmEncoding()).isFalse();
}
@Test
when(initializer.additionalSourceFiles()).thenReturn(Arrays.asList(additionalFile));
when(initializer.additionalTestFiles()).thenReturn(Arrays.asList(additionalTest));
- DefaultModuleFileSystem fs = new DefaultModuleFileSystem(new Project("foo"), settings, fileIndex, initializer, mode, componentIndexer);
+ DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("foo"), settings, fileIndexer, initializer, componentIndexer);
assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(basedir.getCanonicalPath());
assertThat(fs.workingDir().getCanonicalPath()).isEqualTo(workingDir.getCanonicalPath());
when(initializer.workingDir()).thenReturn(basedir);
when(initializer.sourceDirs()).thenReturn(Arrays.asList(new File(basedir, "src/main/java")));
- DefaultModuleFileSystem fs = new DefaultModuleFileSystem(new Project("foo"), settings, fileIndex, initializer, mode, componentIndexer);
+ DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("foo"), settings, fileIndexer, initializer, componentIndexer);
File existingDir = temp.newFolder("new_folder");
File notExistingDir = new File(existingDir, "not_exist");
@Test
public void should_search_input_files() throws Exception {
- DefaultModuleFileSystem fs = new DefaultModuleFileSystem(new Project("foo"), settings, fileIndex, initializer, mode, componentIndexer);
+ DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("foo"), settings, fileIndexer, initializer, componentIndexer);
File mainFile = temp.newFile();
- InputFile mainInput = DefaultInputFile.create(mainFile, Charsets.UTF_8, "Main.java", ImmutableMap.of(InputFile.ATTRIBUTE_TYPE, InputFile.TYPE_MAIN));
- InputFile testInput = DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "Test.java", ImmutableMap.of(InputFile.ATTRIBUTE_TYPE, InputFile.TYPE_TEST));
-
- when(fileIndex.inputFiles("foo")).thenReturn(Lists.newArrayList(mainInput, testInput));
+ InputFile mainInput = new DefaultInputFile("Main.java").setFile(mainFile).setType(InputFile.Type.MAIN);
+ InputFile testInput = new DefaultInputFile("Test.java").setFile(temp.newFile()).setType(InputFile.Type.TEST);
+ when(moduleInputFileCache.inputFiles()).thenReturn(Lists.newArrayList(mainInput, testInput));
fs.index();
- Iterable<InputFile> inputFiles = fs.inputFiles(FileQuery.onSource());
+ Iterable<InputFile> inputFiles = fs.inputFiles(FilePredicates.hasType(InputFile.Type.MAIN));
assertThat(inputFiles).containsOnly(mainInput);
- List<File> files = fs.files(FileQuery.onSource());
+ Iterable<File> files = fs.files(FilePredicates.hasType(InputFile.Type.MAIN));
assertThat(files).containsOnly(mainFile);
}
@Test
public void should_index() throws Exception {
- DefaultModuleFileSystem fs = new DefaultModuleFileSystem(new Project("foo"), settings, fileIndex, initializer, mode, componentIndexer);
+ DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache,
+ new Project("foo"), settings, fileIndexer, initializer, componentIndexer);
- verifyZeroInteractions(fileIndex);
+ verifyZeroInteractions(fileIndexer);
fs.index();
- verify(fileIndex).index(fs);
+ verify(fileIndexer).index(fs);
verify(componentIndexer).execute(fs);
}
*/
package org.sonar.batch.scan.filesystem;
-import org.sonar.api.scan.filesystem.InputFile;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
import org.apache.commons.io.FilenameUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.scan.filesystem.FileSystemFilter;
import org.sonar.api.scan.filesystem.FileType;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
import java.io.File;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public class DeprecatedFileFiltersTest {
public void no_filters() throws Exception {
DeprecatedFileFilters filters = new DeprecatedFileFilters();
- InputFile inputFile = DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "src/main/java/Foo.java", Maps.<String, String>newHashMap());
+ InputFile inputFile = new DefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile());
assertThat(filters.accept(inputFile)).isTrue();
}
File basedir = temp.newFolder();
File file = temp.newFile();
- InputFile inputFile = DefaultInputFile.create(file, Charsets.UTF_8, "src/main/java/Foo.java", ImmutableMap.of(
- DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH, new File(basedir, "src/main/java").getAbsolutePath(),
- DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "Foo.java",
- InputFile.ATTRIBUTE_TYPE, InputFile.TYPE_TEST
-
- ));
+ InputFile inputFile = new DefaultInputFile("src/main/java/Foo.java")
+ .setFile(file)
+ .setType(InputFile.Type.MAIN)
+ .setSourceDirAbsolutePath(new File(basedir, "src/main/java").getAbsolutePath())
+ .setPathRelativeToSourceDir("Foo.java");
when(filter.accept(eq(file), any(DeprecatedFileFilters.DeprecatedContext.class))).thenReturn(false);
assertThat(filters.accept(inputFile)).isFalse();
assertThat(context.canonicalPath()).isEqualTo(FilenameUtils.separatorsToUnix(file.getAbsolutePath()));
assertThat(context.relativeDir()).isEqualTo(new File(basedir, "src/main/java"));
assertThat(context.relativePath()).isEqualTo("Foo.java");
- assertThat(context.type()).isEqualTo(FileType.TEST);
+ assertThat(context.type()).isEqualTo(FileType.MAIN);
}
}
*/
package org.sonar.batch.scan.filesystem;
-import org.sonar.api.scan.filesystem.InputFile;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import java.io.File;
ExclusionFilter absoluteFilter = new ExclusionFilter("file:**/src/main/**Foo.java");
File file = new File(temp.newFolder(), "src/main/java/org/MyFoo.java");
- InputFile inputFile = DefaultInputFile.create(file, Charsets.UTF_8, "src/main/java/org/MyFoo.java", ImmutableMap.of(
- DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "org/MyFoo.java"
- ));
+ InputFile inputFile = new DefaultInputFile("src/main/java/org/MyFoo.java")
+ .setFile(file)
+ .setPathRelativeToSourceDir("org/MyFoo.java");
assertThat(sourceRelativeFilter.accept(inputFile)).isFalse();
assertThat(absoluteFilter.accept(inputFile)).isFalse();
file = new File(temp.newFolder(), "src/main/java/org/Other.java");
- inputFile = DefaultInputFile.create(file, Charsets.UTF_8, "src/main/java/org/Other.java", ImmutableMap.of(
- DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "org/Other.java"
- ));
+ inputFile = new DefaultInputFile("src/main/java/org/Other.java")
+ .setFile(file)
+ .setPathRelativeToSourceDir("org/Other.java");
assertThat(sourceRelativeFilter.accept(inputFile)).isTrue();
assertThat(absoluteFilter.accept(inputFile)).isTrue();
}
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.config.Settings;
import org.sonar.api.scan.filesystem.FileExclusions;
-import org.sonar.api.scan.filesystem.InputFile;
import org.sonar.api.scan.filesystem.ModuleFileSystem;
import java.io.File;
java.io.File file = temp.newFile();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_MAIN)).isFalse();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.MAIN)).isFalse();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/FooDao.java", InputFile.TYPE_MAIN)).isTrue();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/FooDao.java", InputFile.Type.MAIN)).isTrue();
// test are excluded by default if no sonar.tests nor sonar.test.inclusions
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_TEST)).isFalse();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.TEST)).isFalse();
}
@Test
java.io.File file = temp.newFile();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_MAIN)).isTrue();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.MAIN)).isTrue();
- assertThat(filter.accept(file, "src/main/java2/com/mycompany/FooDao.java", InputFile.TYPE_MAIN)).isFalse();
+ assertThat(filter.accept(file, "src/main/java2/com/mycompany/FooDao.java", InputFile.Type.MAIN)).isFalse();
// source inclusions do not apply to tests
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_TEST)).isFalse();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.TEST)).isFalse();
}
@Test
java.io.File file = temp.newFile();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_MAIN)).isTrue();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.MAIN)).isTrue();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_TEST)).isFalse();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.TEST)).isFalse();
- assertThat(filter.accept(file, "src/test/java/com/mycompany/Foo.java", InputFile.TYPE_TEST)).isTrue();
+ assertThat(filter.accept(file, "src/test/java/com/mycompany/Foo.java", InputFile.Type.TEST)).isTrue();
}
@Test
java.io.File file = temp.newFile();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_MAIN)).isFalse();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.MAIN)).isFalse();
- assertThat(filter.accept(file, "src/main/java2/com/mycompany/FooDao.java", InputFile.TYPE_MAIN)).isTrue();
+ assertThat(filter.accept(file, "src/main/java2/com/mycompany/FooDao.java", InputFile.Type.MAIN)).isTrue();
// source inclusions do not apply to tests
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_TEST)).isFalse();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.TEST)).isFalse();
}
@Test
java.io.File file = temp.newFile();
// test inclusions do not apply to main code
- assertThat(filter.accept(file, "src/test/java/com/mycompany/Foo.java", InputFile.TYPE_MAIN)).isFalse();
+ assertThat(filter.accept(file, "src/test/java/com/mycompany/Foo.java", InputFile.Type.MAIN)).isFalse();
- assertThat(filter.accept(file, "src/test2/java/com/mycompany/FooTest.java", InputFile.TYPE_TEST)).isFalse();
+ assertThat(filter.accept(file, "src/test2/java/com/mycompany/FooTest.java", InputFile.Type.TEST)).isFalse();
- assertThat(filter.accept(file, "src/test/java/com/mycompany/Foo.java", InputFile.TYPE_TEST)).isTrue();
+ assertThat(filter.accept(file, "src/test/java/com/mycompany/Foo.java", InputFile.Type.TEST)).isTrue();
}
@Test
java.io.File file = temp.newFile();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_MAIN)).isFalse();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.MAIN)).isFalse();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/FooDto.java", InputFile.TYPE_MAIN)).isTrue();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/FooDto.java", InputFile.Type.MAIN)).isTrue();
}
@Test
filter.prepare(fs);
java.io.File file = temp.newFile();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/FooDao.java", InputFile.TYPE_MAIN)).isFalse();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/FooDao.java", InputFile.Type.MAIN)).isFalse();
- assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.TYPE_MAIN)).isTrue();
+ assertThat(filter.accept(file, "src/main/java/com/mycompany/Foo.java", InputFile.Type.MAIN)).isTrue();
// source exclusions do not apply to tests
- assertThat(filter.accept(file, "src/test/java/com/mycompany/FooDao.java", InputFile.TYPE_TEST)).isTrue();
+ assertThat(filter.accept(file, "src/test/java/com/mycompany/FooDao.java", InputFile.Type.TEST)).isTrue();
}
@Test
filter.prepare(fs);
- assertThat(filter.accept(includedFile, "src/main/java/org/bar/Foo.java", InputFile.TYPE_MAIN)).isTrue();
+ assertThat(filter.accept(includedFile, "src/main/java/org/bar/Foo.java", InputFile.Type.MAIN)).isTrue();
- assertThat(filter.accept(excludedFile, "src/main/java/org/bar/Bar.java", InputFile.TYPE_MAIN)).isFalse();
+ assertThat(filter.accept(excludedFile, "src/main/java/org/bar/Bar.java", InputFile.Type.MAIN)).isFalse();
}
@Test
FileUtils.write(tempFile, "foo\r\nbar\r\nbaz", Charsets.UTF_8, true);
FileMetadata.Metadata metadata = FileMetadata.INSTANCE.read(tempFile, Charsets.UTF_8);
- assertThat(metadata.lines).isEqualTo(3L);
+ assertThat(metadata.lines).isEqualTo(3);
assertThat(metadata.hash).isEqualTo(EXPECTED_HASH_WITHOUT_LATEST_EOL);
}
FileUtils.write(tempFile, "foo\r\nbar\r\nbaz\r\n", Charsets.UTF_8, true);
FileMetadata.Metadata metadata = FileMetadata.INSTANCE.read(tempFile, Charsets.UTF_8);
- assertThat(metadata.lines).isEqualTo(3L);
+ assertThat(metadata.lines).isEqualTo(3);
assertThat(metadata.hash).isEqualTo(EXPECTED_HASH_WITH_LATEST_EOL);
}
FileUtils.write(tempFile, "foo\nbar\nbaz", Charsets.UTF_8, true);
FileMetadata.Metadata metadata = FileMetadata.INSTANCE.read(tempFile, Charsets.UTF_8);
- assertThat(metadata.lines).isEqualTo(3L);
+ assertThat(metadata.lines).isEqualTo(3);
assertThat(metadata.hash).isEqualTo(EXPECTED_HASH_WITHOUT_LATEST_EOL);
}
FileUtils.write(tempFile, "foo\nbar\nbaz\n", Charsets.UTF_8, true);
FileMetadata.Metadata metadata = FileMetadata.INSTANCE.read(tempFile, Charsets.UTF_8);
- assertThat(metadata.lines).isEqualTo(3L);
+ assertThat(metadata.lines).isEqualTo(3);
assertThat(metadata.hash).isEqualTo(EXPECTED_HASH_WITH_LATEST_EOL);
}
FileUtils.write(tempFile, "foo\nbar\r\nbaz\n", Charsets.UTF_8, true);
FileMetadata.Metadata metadata = FileMetadata.INSTANCE.read(tempFile, Charsets.UTF_8);
- assertThat(metadata.lines).isEqualTo(3L);
+ assertThat(metadata.lines).isEqualTo(3);
assertThat(metadata.hash).isEqualTo(EXPECTED_HASH_WITH_LATEST_EOL);
}
FileUtils.write(tempFile, "foo\nbar\r\nbaz", Charsets.UTF_8, true);
FileMetadata.Metadata metadata = FileMetadata.INSTANCE.read(tempFile, Charsets.UTF_8);
- assertThat(metadata.lines).isEqualTo(3L);
+ assertThat(metadata.lines).isEqualTo(3);
assertThat(metadata.hash).isEqualTo(EXPECTED_HASH_WITHOUT_LATEST_EOL);
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.scan.filesystem;
-
-import org.sonar.api.scan.filesystem.InputFileFilter;
-
-import org.sonar.api.scan.filesystem.InputFile;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.scan.filesystem.FileQuery;
-import org.sonar.batch.bootstrap.AnalysisMode;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class FileQueryFilterTest {
-
- private AnalysisMode mode;
-
- @Before
- public void before() {
- mode = mock(AnalysisMode.class);
- }
-
- @Test
- public void wrap_query_on_attributes() throws Exception {
- FileQuery query = FileQuery.onSource();
- FileQueryFilter filter = new FileQueryFilter(mode, query);
-
- assertThat(filter.filters()).hasSize(1);
- InputFileFilter typeFilter = filter.filters().get(0);
- assertThat(typeFilter).isInstanceOf(AttributeFilter.class);
- assertThat(((AttributeFilter) typeFilter).key()).isEqualTo(InputFile.ATTRIBUTE_TYPE);
- assertThat(((AttributeFilter) typeFilter).values()).containsOnly(InputFile.TYPE_MAIN);
- }
-
- @Test
- public void wrap_query_on_inclusions() throws Exception {
- FileQuery query = FileQuery.on().withInclusions("Foo*.java");
- FileQueryFilter filter = new FileQueryFilter(mode, query);
-
- assertThat(filter.filters()).hasSize(1);
- InputFileFilter inclusionFilter = filter.filters().get(0);
- assertThat(inclusionFilter).isInstanceOf(InclusionFilter.class);
- assertThat(inclusionFilter.toString()).isEqualTo("Includes: Foo*.java");
- }
-
- @Test
- public void wrap_query_on_exclusions() throws Exception {
- FileQuery query = FileQuery.on().withExclusions("Foo*.java");
- FileQueryFilter filter = new FileQueryFilter(mode, query);
-
- assertThat(filter.filters()).hasSize(1);
- InputFileFilter exclusionFilter = filter.filters().get(0);
- assertThat(exclusionFilter).isInstanceOf(ExclusionFilter.class);
- assertThat(exclusionFilter.toString()).isEqualTo("Excludes: Foo*.java");
- }
-
- @Test
- public void all_files_by_default() throws Exception {
- FileQuery query = FileQuery.on();
- FileQueryFilter filter = new FileQueryFilter(mode, query);
- assertThat(filter.filters()).isEmpty();
- }
-
- @Test
- public void only_changed_files_by_default_if_incremental_mode() throws Exception {
- when(mode.isIncremental()).thenReturn(true);
-
- FileQuery query = FileQuery.on();
- FileQueryFilter filter = new FileQueryFilter(mode, query);
-
- assertThat(filter.filters()).hasSize(1);
- AttributeFilter statusFilter = (AttributeFilter) filter.filters().get(0);
- assertThat(statusFilter.key()).isEqualTo(InputFile.ATTRIBUTE_STATUS);
- assertThat(statusFilter.values()).containsOnly(InputFile.STATUS_ADDED, InputFile.STATUS_CHANGED);
- }
-
- @Test
- public void get_all_files_even_if_incremental_mode() throws Exception {
- when(mode.isIncremental()).thenReturn(true);
-
- FileQuery query = FileQuery.on().on(InputFile.ATTRIBUTE_STATUS, InputFile.STATUS_SAME);
- FileQueryFilter filter = new FileQueryFilter(mode, query);
-
- assertThat(filter.filters()).hasSize(1);
- AttributeFilter statusFilter = (AttributeFilter) filter.filters().get(0);
- assertThat(statusFilter.key()).isEqualTo(InputFile.ATTRIBUTE_STATUS);
- assertThat(statusFilter.values()).containsOnly(InputFile.STATUS_SAME);
- }
-}
*/
package org.sonar.batch.scan.filesystem;
-import org.sonar.api.scan.filesystem.InputFile;
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableMap;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import java.io.File;
InclusionFilter absoluteFilter = new InclusionFilter("file:**/src/main/**Foo.java");
File file = new File(temp.newFolder(), "src/main/java/org/MyFoo.java");
- InputFile inputFile = DefaultInputFile.create(file, Charsets.UTF_8, "src/main/java/org/MyFoo.java", ImmutableMap.of(
- DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "org/MyFoo.java"
- ));
+ InputFile inputFile = new DefaultInputFile("src/main/java/org/MyFoo.java")
+ .setFile(file)
+ .setPathRelativeToSourceDir("org/MyFoo.java");
assertThat(sourceRelativeFilter.accept(inputFile)).isTrue();
assertThat(absoluteFilter.accept(inputFile)).isTrue();
file = new File(temp.newFolder(), "src/main/java/org/Other.java");
- inputFile = DefaultInputFile.create(file, Charsets.UTF_8, "src/main/java/org/Other.java", ImmutableMap.of(
- DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH, "org/Other.java"
- ));
+ inputFile = new DefaultInputFile("src/main/java/org/Other.java")
+ .setFile(file)
+ .setPathRelativeToSourceDir("org/Other.java");
assertThat(sourceRelativeFilter.accept(inputFile)).isFalse();
assertThat(absoluteFilter.accept(inputFile)).isFalse();
}
import org.mockito.Mockito;
import org.sonar.api.resources.Project;
import org.sonar.api.scan.filesystem.PathResolver;
+import org.sonar.batch.bootstrap.AnalysisMode;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;
LanguageDetectionFactory langDetectionFactory = mock(LanguageDetectionFactory.class, Mockito.RETURNS_MOCKS);
StatusDetectionFactory statusDetectionFactory = mock(StatusDetectionFactory.class, Mockito.RETURNS_MOCKS);
DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
+ AnalysisMode analysisMode = mock(AnalysisMode.class);
InputFileBuilderFactory factory = new InputFileBuilderFactory(
project, pathResolver, langDetectionFactory,
- statusDetectionFactory);
+ statusDetectionFactory, analysisMode);
InputFileBuilder builder = factory.create(fs);
assertThat(builder.langDetection()).isNotNull();
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.sonar.api.scan.filesystem.InputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
import org.sonar.api.utils.PathUtils;
+import org.sonar.batch.bootstrap.AnalysisMode;
import java.io.File;
import java.util.Arrays;
LanguageDetection langDetection = mock(LanguageDetection.class);
StatusDetection statusDetection = mock(StatusDetection.class);
DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
+ AnalysisMode analysisMode = mock(AnalysisMode.class);
@Test
public void create_input_file() throws Exception {
FileUtils.touch(srcFile);
FileUtils.write(srcFile, "single line");
when(fs.baseDir()).thenReturn(basedir);
- when(fs.sourceCharset()).thenReturn(Charsets.UTF_8);
+ when(fs.encoding()).thenReturn(Charsets.UTF_8);
// lang
when(langDetection.language(any(InputFile.class))).thenReturn("java");
// status
- when(statusDetection.status("src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a")).thenReturn(InputFile.STATUS_ADDED);
+ when(statusDetection.status("src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a"))
+ .thenReturn(InputFile.Status.ADDED);
InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
- langDetection, statusDetection, fs);
- DefaultInputFile inputFile = builder.create(srcFile, InputFile.TYPE_MAIN);
+ langDetection, statusDetection, fs, analysisMode);
+ DefaultInputFile inputFile = builder.create(srcFile, InputFile.Type.MAIN);
- assertThat(inputFile.name()).isEqualTo("Bar.java");
assertThat(inputFile.file()).isEqualTo(srcFile.getAbsoluteFile());
assertThat(inputFile.absolutePath()).isEqualTo(PathUtils.sanitize(srcFile.getAbsolutePath()));
assertThat(inputFile.language()).isEqualTo("java");
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY)).isEqualTo("struts:src/main/java/foo/Bar.java");
- assertThat(inputFile.path()).isEqualTo("src/main/java/foo/Bar.java");
-
- assertThat(inputFile.attribute(InputFile.ATTRIBUTE_LINE_COUNT)).isEqualTo("1");
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH)).isNull();
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH)).isNull();
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_DEPRECATED_KEY)).isNull();
+ assertThat(inputFile.key()).isEqualTo("struts:src/main/java/foo/Bar.java");
+ assertThat(inputFile.relativePath()).isEqualTo("src/main/java/foo/Bar.java");
+ assertThat(inputFile.lines()).isEqualTo(1);
+ assertThat(inputFile.sourceDirAbsolutePath()).isNull();
+ assertThat(inputFile.pathRelativeToSourceDir()).isNull();
+ assertThat(inputFile.deprecatedKey()).isNull();
}
@Test
when(fs.baseDir()).thenReturn(basedir);
InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
- langDetection, statusDetection, fs);
- DefaultInputFile inputFile = builder.create(srcFile, InputFile.TYPE_MAIN);
+ langDetection, statusDetection, fs, analysisMode);
+ DefaultInputFile inputFile = builder.create(srcFile, InputFile.Type.MAIN);
assertThat(inputFile).isNull();
}
FileUtils.touch(srcFile);
FileUtils.write(srcFile, "single line");
when(fs.baseDir()).thenReturn(basedir);
- when(fs.sourceCharset()).thenReturn(Charsets.UTF_8);
+ when(fs.encoding()).thenReturn(Charsets.UTF_8);
// lang
when(langDetection.language(any(InputFile.class))).thenReturn(null);
InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
- langDetection, statusDetection, fs);
- DefaultInputFile inputFile = builder.create(srcFile, InputFile.TYPE_MAIN);
+ langDetection, statusDetection, fs, analysisMode);
+ DefaultInputFile inputFile = builder.create(srcFile, InputFile.Type.MAIN);
assertThat(inputFile).isNull();
}
FileUtils.touch(srcFile);
FileUtils.write(srcFile, "single line");
when(fs.baseDir()).thenReturn(basedir);
- when(fs.sourceCharset()).thenReturn(Charsets.UTF_8);
+ when(fs.encoding()).thenReturn(Charsets.UTF_8);
File sourceDir = new File(basedir, "src/main/java");
when(fs.sourceDirs()).thenReturn(Arrays.asList(sourceDir));
when(langDetection.language(any(InputFile.class))).thenReturn("java");
// status
- when(statusDetection.status("src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a")).thenReturn(InputFile.STATUS_ADDED);
+ when(statusDetection.status("src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a"))
+ .thenReturn(InputFile.Status.ADDED);
InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
- langDetection, statusDetection, fs);
- DefaultInputFile inputFile = builder.create(srcFile, InputFile.TYPE_MAIN);
+ langDetection, statusDetection, fs, analysisMode);
+ DefaultInputFile inputFile = builder.create(srcFile, InputFile.Type.MAIN);
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH)).isEqualTo("foo/Bar.java");
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH)).isEqualTo(PathUtils.sanitize(sourceDir.getAbsolutePath()));
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_DEPRECATED_KEY)).isEqualTo("struts:foo.Bar");
+ assertThat(inputFile.pathRelativeToSourceDir()).isEqualTo("foo/Bar.java");
+ assertThat(inputFile.sourceDirAbsolutePath()).isEqualTo(PathUtils.sanitize(sourceDir.getAbsolutePath()));
+ assertThat(inputFile.deprecatedKey()).isEqualTo("struts:foo.Bar");
}
@Test
FileUtils.touch(srcFile);
FileUtils.write(srcFile, "single line");
when(fs.baseDir()).thenReturn(basedir);
- when(fs.sourceCharset()).thenReturn(Charsets.UTF_8);
+ when(fs.encoding()).thenReturn(Charsets.UTF_8);
File sourceDir = new File(basedir, "src");
when(fs.sourceDirs()).thenReturn(Arrays.asList(sourceDir));
when(langDetection.language(any(InputFile.class))).thenReturn("php");
// status
- when(statusDetection.status("src/Bar.php", "6c1d64c0b3555892fe7273e954f6fb5a")).thenReturn(InputFile.STATUS_ADDED);
+ when(statusDetection.status("src/Bar.php", "6c1d64c0b3555892fe7273e954f6fb5a"))
+ .thenReturn(InputFile.Status.ADDED);
InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
- langDetection, statusDetection, fs);
- DefaultInputFile inputFile = builder.create(srcFile, InputFile.TYPE_MAIN);
+ langDetection, statusDetection, fs, analysisMode);
+ DefaultInputFile inputFile = builder.create(srcFile, InputFile.Type.MAIN);
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_SOURCE_RELATIVE_PATH)).isEqualTo("foo/Bar.php");
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH)).isEqualTo(PathUtils.sanitize(sourceDir.getAbsolutePath()));
- assertThat(inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_DEPRECATED_KEY)).isEqualTo("struts:foo/Bar.php");
+ assertThat(inputFile.pathRelativeToSourceDir()).isEqualTo("foo/Bar.php");
+ assertThat(inputFile.sourceDirAbsolutePath()).isEqualTo(PathUtils.sanitize(sourceDir.getAbsolutePath()));
+ assertThat(inputFile.deprecatedKey()).isEqualTo("struts:foo/Bar.php");
}
}
*/
package org.sonar.batch.scan.filesystem;
-import org.sonar.api.scan.filesystem.InputFile;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.Maps;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.batch.index.Caches;
import org.sonar.batch.index.CachesTest;
+
import static org.fest.assertions.Assertions.assertThat;
public class InputFileCacheTest {
@Test
public void should_add_input_file() throws Exception {
InputFileCache cache = new InputFileCache(caches);
- cache.put("struts", DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "src/main/java/Foo.java", Maps.<String, String>newHashMap()));
- cache.put("struts-core", DefaultInputFile.create(temp.newFile(), Charsets.UTF_8, "src/main/java/Foo.java", Maps.<String, String>newHashMap()));
+ cache.put("struts", new DefaultInputFile("src/main/java/Foo.java").setFile(temp.newFile("Foo.java")));
+ cache.put("struts-core", new DefaultInputFile("src/main/java/Bar.java").setFile(temp.newFile("Bar.java")));
assertThat(cache.byModule("struts")).hasSize(1);
assertThat(cache.byModule("struts-core")).hasSize(1);
assertThat(cache.all()).hasSize(2);
for (InputFile inputFile : cache.all()) {
- assertThat(inputFile.path()).startsWith("src/main/java");
+ assertThat(inputFile.relativePath()).startsWith("src/main/java/");
}
- assertThat(cache.fileRelativePaths("struts-core")).containsOnly("src/main/java/Foo.java");
-
cache.removeModule("struts");
assertThat(cache.byModule("struts")).hasSize(0);
assertThat(cache.byModule("struts-core")).hasSize(1);
*/
package org.sonar.batch.scan.filesystem;
-import com.google.common.base.Charsets;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.internal.InputFileBuilder;
import org.sonar.api.utils.MessageException;
import java.io.File;
private InputFile newInputFile(String path) throws IOException {
File basedir = temp.newFolder();
- return new InputFileBuilder(new File(basedir, path), Charsets.UTF_8, path).build();
+ return new DefaultInputFile(path).setFile(new File(basedir, path));
}
static class MockLanguage implements Language {
import com.google.common.collect.ImmutableMap;
import org.junit.Test;
-import org.sonar.api.scan.filesystem.InputFile;
+import org.sonar.api.batch.fs.InputFile;
import static org.fest.assertions.Assertions.assertThat;
public class StatusDetectionTest {
@Test
public void detect_status() throws Exception {
- StatusDetection statusDetection = new StatusDetection(ImmutableMap.<String, String>of(
+ StatusDetection statusDetection = new StatusDetection(ImmutableMap.of(
"src/Foo.java", "ABCDE",
"src/Bar.java", "FGHIJ"
));
- assertThat(statusDetection.status("src/Foo.java", "ABCDE")).isEqualTo(InputFile.STATUS_SAME);
- assertThat(statusDetection.status("src/Foo.java", "XXXXX")).isEqualTo(InputFile.STATUS_CHANGED);
- assertThat(statusDetection.status("src/Other.java", "QWERT")).isEqualTo(InputFile.STATUS_ADDED);
+ assertThat(statusDetection.status("src/Foo.java", "ABCDE")).isEqualTo(InputFile.Status.SAME);
+ assertThat(statusDetection.status("src/Foo.java", "XXXXX")).isEqualTo(InputFile.Status.CHANGED);
+ assertThat(statusDetection.status("src/Other.java", "QWERT")).isEqualTo(InputFile.Status.ADDED);
}
}
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.skyscreamer.jsonassert.JSONAssert;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.scan.filesystem.ModuleFileSystem;
-import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.batch.bootstrap.AnalysisMode;
JsonReport jsonReport;
Resource resource = mock(Resource.class);
- ModuleFileSystem fileSystem = mock(ModuleFileSystem.class);
+ DefaultFileSystem fs = new DefaultFileSystem();
Server server = mock(Server.class);
RuleFinder ruleFinder = mock(RuleFinder.class);
- Settings settings;
+ Settings settings = new Settings();
IssueCache issueCache = mock(IssueCache.class);
private AnalysisMode mode;
private UserFinder userFinder;
@Before
- public void setUp() {
+ public void before() {
SIMPLE_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+02:00"));
when(resource.getEffectiveKey()).thenReturn("Action.java");
when(server.getVersion()).thenReturn("3.6");
-
- settings = new Settings();
mode = mock(AnalysisMode.class);
when(mode.isPreview()).thenReturn(true);
userFinder = mock(UserFinder.class);
- InputFile inputFile = mock(InputFile.class);
- when(inputFile.path()).thenReturn("src/main/java/org/apache/struts/Action.java");
- when(inputFile.attribute(DefaultInputFile.ATTRIBUTE_COMPONENT_KEY)).thenReturn("struts:src/main/java/org/apache/struts/Action.java");
- when(inputFile.attribute(InputFile.ATTRIBUTE_STATUS)).thenReturn(InputFile.STATUS_CHANGED);
+ DefaultInputFile inputFile = new DefaultInputFile("src/main/java/org/apache/struts/Action.java");
+ inputFile.setKey("struts:src/main/java/org/apache/struts/Action.java");
+ inputFile.setStatus(InputFile.Status.CHANGED);
InputFileCache fileCache = mock(InputFileCache.class);
- when(fileCache.all()).thenReturn(Arrays.asList(inputFile));
+ when(fileCache.all()).thenReturn(Arrays.<InputFile>asList(inputFile));
Project rootModule = new Project("struts");
Project moduleA = new Project("struts-core");
moduleA.setParent(rootModule).setPath("core");
Project moduleB = new Project("struts-ui");
moduleB.setParent(rootModule).setPath("ui");
- jsonReport = new JsonReport(settings, fileSystem, server, ruleFinder, issueCache, mock(EventBus.class),
+ jsonReport = new JsonReport(settings, fs, server, ruleFinder, issueCache, mock(EventBus.class),
mode, userFinder, rootModule, fileCache);
}
@Test
public void should_export_issues_to_file() throws IOException {
- File sonarDirectory = temporaryFolder.newFolder("sonar");
+ File workDir = temporaryFolder.newFolder("sonar");
+ fs.setWorkDir(workDir);
Rule rule = Rule.create("squid", "AvoidCycles").setName("Avoid Cycles");
when(ruleFinder.findByKey(RuleKey.of("squid", "AvoidCycles"))).thenReturn(rule);
when(jsonReport.getIssues()).thenReturn(Collections.<DefaultIssue>emptyList());
settings.setProperty("sonar.report.export.path", "output.json");
- when(fileSystem.workingDir()).thenReturn(sonarDirectory);
jsonReport.execute();
- assertThat(new File(sonarDirectory, "output.json")).exists();
+ assertThat(new File(workDir, "output.json")).exists();
}
}
--- /dev/null
+public class Car {
+
+ public AClaèss() {
+ }
+
+ public int explicação() {
+ return 1;
+ }
+
+ public String getS() {
+ return "";
+ }
+}
--- /dev/null
+public class Car {
+
+ public ACla\8fss() {
+ }
+
+ public int explica\8d\8bo() {
+ return 1;
+ }
+
+ public String getS() {
+ return "";
+ }
+}
+++ /dev/null
-public class Car {
-
- public AClaèss() {
- }
-
- public int explicação() {
- return 1;
- }
-
- public String getS() {
- return "";
- }
-}
+++ /dev/null
-public class Car {
-
- public ACla\8fss() {
- }
-
- public int explica\8d\8bo() {
- return 1;
- }
-
- public String getS() {
- return "";
- }
-}
Collection<String> keys();
- Collection<Language> languages();
-
}
*/
package org.sonar.api.batch;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.resources.ProjectLink;
import org.sonar.api.resources.Resource;
import org.sonar.api.rules.Violation;
-import org.sonar.api.scan.filesystem.InputFile;
import java.util.Collection;
import java.util.Date;
* Indexes a resource as a direct child of project. This method does nothing and returns true if the resource already indexed.
*
* @return false if the resource is excluded
- * @since 2.6
* @since 4.2 Resource indexing is done by the platform for all physical resources. This method should only be used to index methods/paragraphs (see SONAR-5006)
*/
boolean index(Resource resource);
* @param resource the resource to index. Not nullable
* @param parentReference a reference to the parent. If null, the the resource is indexed as a direct child of project.
* @return false if the parent is not indexed or if the resource is excluded
- * @since 2.6
* @since 4.2 Resource indexing is done by the platform for all physical resources. This method should only be used to index methods/paragraphs (see SONAR-5006)
*/
boolean index(Resource resource, Resource parentReference);
/**
* Returns true if the referenced resource is indexed and excluded.
+ *
* @since 2.6
*/
boolean isExcluded(Resource reference);
/**
* Returns true if the referenced resource is indexed.
+ *
* @since 2.6
*/
boolean isIndexed(Resource reference, boolean acceptExcluded);
*/
Measure saveMeasure(Resource resource, Metric metric, Double value);
- /**
- * Experimental.
- * Add or update a measure on an InputFile.
- * @since 4.2
- */
- Measure saveMeasure(InputFile inputFile, Metric metric, Double value);
-
/**
* Add or update a measure.
* <p>
*/
Measure saveMeasure(Resource resource, Measure measure);
- /**
- * Experimental.
- * Add or update a measure on an InputFile.
- * @since 4.2
- */
- Measure saveMeasure(InputFile inputFile, Measure measure);
-
// ----------- RULE VIOLATIONS --------------
/**
/**
* Save the source code of a file. The file must be have been indexed before.
*
- * @throws org.sonar.api.resources.DuplicatedSourceException
- * if the source has already been set on this resource
+ * @throws org.sonar.api.resources.DuplicatedSourceException if the source has already been set on this resource
* @since 1.10. Returns a boolean since 2.6.
* @deprecated since 4.2 Source import is done by the platform
*/
*/
void deleteEvent(Event event);
+ /**
+ * @since 4.2
+ */
+ Measure saveMeasure(InputFile inputFile, Metric metric, Double value);
+
+ /**
+ * @since 4.2
+ */
+ Measure saveMeasure(InputFile inputFile, Measure measure);
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import org.apache.commons.io.FilenameUtils;
+
+/**
+ * @since 4.2
+ */
+class AbsolutePathPredicate implements FilePredicate {
+
+ private final String path;
+
+ AbsolutePathPredicate(String path) {
+ this.path = FilenameUtils.normalize(path, true);
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return path.equals(f.absolutePath());
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import javax.annotation.Nullable;
+
+/**
+ * @since 4.2
+ */
+class AndPredicate implements FilePredicate {
+
+ private final Iterable<FilePredicate> predicates;
+
+ AndPredicate(@Nullable Iterable<FilePredicate> predicates) {
+ this.predicates = predicates;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ for (FilePredicate predicate : predicates) {
+ if (!predicate.apply(f)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * Determines if a file must be kept in search results. See {@link org.sonar.api.batch.fs.FileSystem}
+ * and {@link org.sonar.api.batch.fs.FilePredicates}.
+ * @since 4.2
+ */
+public interface FilePredicate {
+ boolean apply(InputFile inputFile);
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import com.google.common.collect.Lists;
+import org.sonar.api.batch.fs.internal.PathPattern;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Factory of {@link org.sonar.api.batch.fs.FilePredicate}
+ *
+ * @since 4.2
+ */
+public class FilePredicates {
+ private static final FilePredicate ALWAYS_TRUE = new AlwaysTruePredicate();
+
+ private FilePredicates() {
+ // only static stuff
+ }
+
+ /**
+ * Returns a predicate that always evaluates to true
+ */
+ public static FilePredicate all() {
+ return ALWAYS_TRUE;
+ }
+
+ /**
+ * Warning - not efficient because absolute path is not indexed yet.
+ */
+ public static FilePredicate hasAbsolutePath(String s) {
+ return new AbsolutePathPredicate(s);
+ }
+
+ /**
+ * TODO document that non-normalized path and Windows-style path are supported
+ */
+ public static FilePredicate hasRelativePath(String s) {
+ return new RelativePathPredicate(s);
+ }
+
+ public static FilePredicate matchesPathPattern(String inclusionPattern) {
+ return new PathPatternPredicate(PathPattern.create(inclusionPattern));
+ }
+
+ public static FilePredicate matchesPathPatterns(String[] inclusionPatterns) {
+ FilePredicate[] predicates = new FilePredicate[inclusionPatterns.length];
+ for (int i = 0; i < inclusionPatterns.length; i++) {
+ predicates[i] = new PathPatternPredicate(PathPattern.create(inclusionPatterns[i]));
+ }
+ return and(predicates);
+ }
+
+ public static FilePredicate doesNotMatchPathPattern(String exclusionPattern) {
+ return not(matchesPathPattern(exclusionPattern));
+ }
+
+ public static FilePredicate doesNotMatchPathPatterns(String[] exclusionPatterns) {
+ return not(matchesPathPatterns(exclusionPatterns));
+ }
+
+ public static FilePredicate hasPath(String s) {
+ File file = new File(s);
+ if (file.isAbsolute()) {
+ return hasAbsolutePath(s);
+ }
+ return hasRelativePath(s);
+ }
+
+ public static FilePredicate is(File ioFile) {
+ if (ioFile.isAbsolute()) {
+ return hasAbsolutePath(ioFile.getAbsolutePath());
+ }
+ return hasRelativePath(ioFile.getPath());
+ }
+
+ public static FilePredicate hasLanguage(String language) {
+ return new LanguagePredicate(language);
+ }
+
+ public static FilePredicate hasLanguages(Collection<String> languages) {
+ List<FilePredicate> list = Lists.newArrayList();
+ for (String language : languages) {
+ list.add(hasLanguage(language));
+ }
+ return or(list);
+ }
+
+ public static FilePredicate hasStatus(InputFile.Status status) {
+ return new StatusPredicate(status);
+ }
+
+ public static FilePredicate hasType(InputFile.Type type) {
+ return new TypePredicate(type);
+ }
+
+ public static FilePredicate not(FilePredicate p) {
+ return new NotPredicate(p);
+ }
+
+ public static FilePredicate or(Iterable<FilePredicate> or) {
+ return new OrPredicate(or);
+ }
+
+ public static FilePredicate or(FilePredicate... or) {
+ return new OrPredicate(Arrays.asList(or));
+ }
+
+ public static FilePredicate or(FilePredicate first, FilePredicate second) {
+ return new OrPredicate(Arrays.asList(first, second));
+ }
+
+ public static FilePredicate and(Iterable<FilePredicate> and) {
+ return new AndPredicate(and);
+ }
+
+ public static FilePredicate and(FilePredicate... and) {
+ return new AndPredicate(Arrays.asList(and));
+ }
+
+ public static FilePredicate and(FilePredicate first, FilePredicate second) {
+ return new AndPredicate(Arrays.asList(first, second));
+ }
+
+ private static class AlwaysTruePredicate implements FilePredicate {
+ @Override
+ public boolean apply(InputFile inputFile) {
+ return true;
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import org.sonar.api.BatchComponent;
+
+import javax.annotation.CheckForNull;
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.Set;
+
+/**
+ * <p>The unit tests needing an instance of FileSystem can use the implementation
+ * {@link org.sonar.api.batch.fs.internal.DefaultFileSystem} and the related {@link org.sonar.api.scan.filesystem.internal.DefaultInputFile}:</p>
+ * <pre>
+ * FileSystem fs = new DefaultFileSystem();
+ * fs.add(new DefaultInputFile("src/foo/bar.php"));
+ * </pre>
+ *
+ * @since 4.2
+ */
+public interface FileSystem extends BatchComponent {
+
+ /**
+ * Absolute base directory of module
+ */
+ File baseDir();
+
+ /**
+ * Default encoding of input files. If it's not defined, then
+ * the platform default encoding is returned
+ */
+ Charset encoding();
+
+ /**
+ * Absolute work directory. It can be used to
+ * store third-party analysis reports.
+ * <p/>
+ * The work directory can be located outside {@link #baseDir()}.
+ */
+ File workDir();
+
+ /**
+ * @see org.sonar.api.batch.fs.FilePredicates
+ */
+ @CheckForNull
+ InputFile inputFile(FilePredicate predicate);
+
+ /**
+ * Input files matching the given attributes. Return all the files if the parameter
+ * <code>attributes</code> is empty.
+ * @see org.sonar.api.batch.fs.FilePredicates
+ */
+ Iterable<InputFile> inputFiles(FilePredicate predicate);
+
+ /**
+ * Returns true if at least one {@link org.sonar.api.batch.fs.InputFile} matches
+ * the given attributes. This method can be faster than checking if {@link #inputFiles(org.sonar.api.batch.fs.FilePredicate...)}
+ * has elements. If the parameter <code>attributes</code> is empty, then returns true
+ * if at least one input file exists.
+ * @see org.sonar.api.batch.fs.FilePredicates
+ */
+ boolean hasFiles(FilePredicate predicate);
+
+ /**
+ * Files matching the given attributes.
+ * @see org.sonar.api.batch.fs.FilePredicates
+ */
+ Iterable<File> files(FilePredicate predicate);
+
+ /**
+ * Languages detected in all the files, whatever their type (main code or test)
+ */
+ Set<String> languages();
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * This layer over {@link java.io.File} adds information useful for code analyzers.
+ *
+ * @since 4.2
+ */
+public interface InputFile extends Serializable {
+
+ enum Type {
+ MAIN, TEST
+ }
+
+ /**
+ * Status regarding previous analysis
+ */
+ enum Status {
+ SAME, CHANGED, ADDED
+ }
+
+ /**
+ * Path relative to module base directory. Path is unique and identifies file
+ * within given <code>{@link FileSystem}</code>.
+ * File separator is the forward slash ('/'), even on Microsoft Windows.
+ * <p/>
+ * Returns <code>src/main/java/com/Foo.java</code> if module base dir is
+ * <code>/absolute/path/to/module</code> and if file is
+ * <code>/absolute/path/to/module/src/main/java/com/Foo.java</code>.
+ * <p/>
+ * Relative path is not null and is normalized ('foo/../foo' is replaced by 'foo').
+ */
+ String relativePath();
+
+ /**
+ * Normalized absolute path. File separator is forward slash ('/'), even on Microsoft Windows.
+ * <p/>
+ * This is not canonical path. Symbolic links are not resolved. For example if /project/src links
+ * to /tmp/src and basedir is /project, then this method returns /project/src/index.php. Use
+ * {@code file().getCanonicalPath()} to resolve symbolic link.
+ */
+ String absolutePath();
+
+ /**
+ * The underlying absolute {@link java.io.File}
+ */
+ File file();
+
+ /**
+ * Language, for example "java" or "php". It's automatically guessed when it is not
+ * set by project configuration.
+ */
+ String language();
+
+ /**
+ * Does it contain main or test code ?
+ */
+ Type type();
+
+ /**
+ * Status regarding previous analysis
+ */
+ Status status();
+
+ int lines();
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import org.sonar.api.BatchExtension;
+
+/**
+ * Extension point to complete the list of files to ignore during inspection
+ * @since 4.2
+ */
+public interface InputFileFilter extends BatchExtension {
+
+ // TODO requires a context (FileSystem) ?
+ boolean accept(InputFile f);
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * @since 4.2
+ */
+class LanguagePredicate implements FilePredicate {
+ private final String language;
+
+ LanguagePredicate(String language) {
+ this.language = language;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return language.equals(f.language());
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * @since 4.2
+ */
+class NotPredicate implements FilePredicate {
+
+ private final FilePredicate predicate;
+
+ NotPredicate(FilePredicate predicate) {
+ this.predicate = predicate;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return !predicate.apply(f);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import javax.annotation.Nullable;
+
+/**
+ * @since 4.2
+ */
+class OrPredicate implements FilePredicate {
+
+ private final Iterable<FilePredicate> predicates;
+
+ OrPredicate(@Nullable Iterable<FilePredicate> predicates) {
+ this.predicates = predicates;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ for (FilePredicate predicate : predicates) {
+ if (predicate.apply(f)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import org.sonar.api.batch.fs.internal.PathPattern;
+
+/**
+ * @since 4.2
+ */
+class PathPatternPredicate implements FilePredicate {
+
+ private final PathPattern pattern;
+
+ PathPatternPredicate(PathPattern pattern) {
+ this.pattern = pattern;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return pattern.match(f);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+import org.apache.commons.io.FilenameUtils;
+import org.sonar.api.batch.fs.internal.RelativePathIndex;
+
+/**
+ * @since 4.2
+ */
+class RelativePathPredicate implements FilePredicate, UniqueIndexPredicate {
+
+ private final String path;
+
+ RelativePathPredicate(String path) {
+ this.path = FilenameUtils.normalize(path, true);
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return path.equals(f.relativePath());
+ }
+
+ @Override
+ public Object value() {
+ return path;
+ }
+
+ @Override
+ public String indexId() {
+ return RelativePathIndex.ID;
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * @since 4.2
+ */
+class StatusPredicate implements FilePredicate {
+
+ private final InputFile.Status status;
+
+ StatusPredicate(InputFile.Status status) {
+ this.status = status;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return status == f.status();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * @since 4.2
+ */
+class TypePredicate implements FilePredicate {
+
+ private final InputFile.Type type;
+
+ TypePredicate(InputFile.Type type) {
+ this.type = type;
+ }
+
+ @Override
+ public boolean apply(InputFile f) {
+ return type == f.type();
+ }
+
+}
+
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs;
+
+/**
+ * @since 4.2
+ */
+public interface UniqueIndexPredicate {
+
+ String indexId();
+
+ Object value();
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.commons.io.Charsets;
+import org.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.UniqueIndexPredicate;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @since 4.2
+ */
+public class DefaultFileSystem implements FileSystem {
+
+ private final Cache cache;
+ private final Set<String> languages = Sets.newTreeSet();
+ private File baseDir, workDir;
+ private Charset encoding = Charsets.UTF_8;
+ private boolean isDefaultJvmEncoding = false;
+
+ /**
+ * Only for testing
+ */
+ public DefaultFileSystem() {
+ this.cache = new MapCache();
+ }
+
+ protected DefaultFileSystem(Cache cache) {
+ this.cache = cache;
+ }
+
+ public DefaultFileSystem setBaseDir(File d) {
+ Preconditions.checkNotNull(d, "Base directory can't be null");
+ this.baseDir = d.getAbsoluteFile();
+ return this;
+ }
+
+ /**
+ * Marked as nullable only for the tests that do not call {@link #setBaseDir(java.io.File)}
+ */
+ @Override
+ @CheckForNull
+ public File baseDir() {
+ return baseDir;
+ }
+
+ public DefaultFileSystem setEncoding(Charset e) {
+ this.encoding = e;
+ return this;
+ }
+
+ @Override
+ public Charset encoding() {
+ return encoding;
+ }
+
+ public boolean isDefaultJvmEncoding() {
+ return isDefaultJvmEncoding;
+ }
+
+ public void setIsDefaultJvmEncoding(boolean b) {
+ this.isDefaultJvmEncoding = b;
+ }
+
+ public DefaultFileSystem setWorkDir(File d) {
+ this.workDir = d.getAbsoluteFile();
+ return this;
+ }
+
+ /**
+ * Marked as nullable only for the tests that do not call {@link #setWorkDir(java.io.File)}
+ */
+ @Override
+ @CheckForNull
+ public File workDir() {
+ return workDir;
+ }
+
+ @Override
+ public InputFile inputFile(FilePredicate predicate) {
+ if (predicate instanceof UniqueIndexPredicate) {
+ return cache.inputFile((UniqueIndexPredicate) predicate);
+ }
+ try {
+ Iterable<InputFile> files = inputFiles(predicate);
+ return Iterables.getOnlyElement(files);
+ } catch (NoSuchElementException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public Iterable<InputFile> inputFiles(FilePredicate predicate) {
+ return Iterables.filter(cache.inputFiles(), new GuavaPredicate(predicate));
+ }
+
+ @Override
+ public boolean hasFiles(FilePredicate predicate) {
+ return Iterables.indexOf(cache.inputFiles(), new GuavaPredicate(predicate)) >= 0;
+ }
+
+ @Override
+ public Iterable<File> files(FilePredicate predicate) {
+ return Iterables.transform(inputFiles(predicate), new Function<InputFile, File>() {
+ @Override
+ public File apply(@Nullable InputFile input) {
+ return input == null ? null : input.file();
+ }
+ });
+ }
+
+ public void add(InputFile inputFile) {
+ cache.add(inputFile);
+ if (inputFile.language() != null) {
+ languages.add(inputFile.language());
+ }
+ }
+
+ @Override
+ public Set<String> languages() {
+ return languages;
+ }
+
+ public static abstract class Cache {
+ protected abstract Iterable<InputFile> inputFiles();
+
+ @CheckForNull
+ protected abstract InputFile inputFile(UniqueIndexPredicate predicate);
+
+ protected abstract void doAdd(InputFile inputFile);
+
+ protected abstract void doIndex(String indexId, Object value, InputFile inputFile);
+
+ final void add(InputFile inputFile) {
+ doAdd(inputFile);
+ for (FileIndex index : FileIndex.ALL) {
+ doIndex(index.id(), index.valueOf(inputFile), inputFile);
+ }
+ }
+ }
+
+ /**
+ * Used only for testing
+ */
+ private static class MapCache extends Cache {
+ private final List<InputFile> files = Lists.newArrayList();
+ private final Map<String, Map<Object, InputFile>> fileMap = Maps.newHashMap();
+
+ @Override
+ public Iterable<InputFile> inputFiles() {
+ return Lists.newArrayList(files);
+ }
+
+ @Override
+ public InputFile inputFile(UniqueIndexPredicate predicate) {
+ Map<Object, InputFile> byAttr = fileMap.get(predicate.indexId());
+ if (byAttr != null) {
+ return byAttr.get(predicate.value());
+ }
+ return null;
+ }
+
+ @Override
+ protected void doAdd(InputFile inputFile) {
+ files.add(inputFile);
+ }
+
+ @Override
+ protected void doIndex(String indexId, Object value, InputFile inputFile) {
+ Map<Object, InputFile> attrValues = fileMap.get(indexId);
+ if (attrValues == null) {
+ attrValues = Maps.newHashMap();
+ fileMap.put(indexId, attrValues);
+ }
+ attrValues.put(value, inputFile);
+ }
+ }
+
+ private static class GuavaPredicate implements Predicate<InputFile> {
+ private final FilePredicate predicate;
+
+ private GuavaPredicate(FilePredicate predicate) {
+ this.predicate = predicate;
+ }
+
+ @Override
+ public boolean apply(@Nullable InputFile input) {
+ return input != null && predicate.apply(input);
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import org.apache.commons.io.FilenameUtils;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.utils.PathUtils;
+
+import javax.annotation.CheckForNull;
+import java.io.*;
+
+/**
+ * @since 4.2
+ */
+public class DefaultInputFile implements InputFile, org.sonar.api.resources.InputFile, Serializable {
+
+ private final String relativePath;
+ private String absolutePath;
+ private String language;
+ private Type type = Type.MAIN;
+ private Status status;
+ private String hash;
+ private int lines;
+ private String key;
+ private String deprecatedKey;
+ private String sourceDirAbsolutePath;
+ private String pathRelativeToSourceDir;
+ private String basedir;
+
+ public DefaultInputFile(String relativePath) {
+ this.relativePath = FilenameUtils.normalize(relativePath, true);
+ }
+
+ @Override
+ public String relativePath() {
+ return relativePath;
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not call {@link #setFile(java.io.File)}
+ * previously.
+ */
+ @Override
+ @CheckForNull
+ public String absolutePath() {
+ return absolutePath;
+ }
+
+ @Override
+ public File file() {
+ return new File(absolutePath);
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not call {@link #setLanguage(String)}
+ * previously.
+ */
+ @CheckForNull
+ @Override
+ public String language() {
+ return language;
+ }
+
+ @Override
+ public Type type() {
+ return type;
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not previously call
+ * {@link #setStatus(org.sonar.api.batch.fs.InputFile.Status)}
+ */
+ @CheckForNull
+ @Override
+ public Status status() {
+ return status;
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not previously call
+ * {@link #setHash(String)}
+ */
+ @CheckForNull
+ public String hash() {
+ return hash;
+ }
+
+ @Override
+ public int lines() {
+ return lines;
+ }
+
+ /**
+ * Marked as nullable just for the unit tests that do not previously call
+ * {@link #setKey(String)}.
+ */
+ @CheckForNull
+ public String key() {
+ return key;
+ }
+
+ public DefaultInputFile setAbsolutePath(String s) {
+ this.absolutePath = FilenameUtils.normalize(s, true);
+ return this;
+ }
+
+ public DefaultInputFile setLanguage(String language) {
+ this.language = language;
+ return this;
+ }
+
+ public DefaultInputFile setFile(File file) {
+ setAbsolutePath(file.getAbsolutePath());
+ return this;
+ }
+
+ public DefaultInputFile setType(Type type) {
+ this.type = type;
+ return this;
+ }
+
+ public DefaultInputFile setStatus(Status status) {
+ this.status = status;
+ return this;
+ }
+
+ public DefaultInputFile setHash(String hash) {
+ this.hash = hash;
+ return this;
+ }
+
+ public DefaultInputFile setLines(int lines) {
+ this.lines = lines;
+ return this;
+ }
+
+ public DefaultInputFile setKey(String s) {
+ this.key = s;
+ return this;
+ }
+
+ /**
+ * Key used before version 4.2. It's different than {@link #key} on Java files.
+ */
+ public String deprecatedKey() {
+ return deprecatedKey;
+ }
+
+ public DefaultInputFile setDeprecatedKey(String s) {
+ this.deprecatedKey = s;
+ return this;
+ }
+
+ /**
+ * Used only for backward-compatibility. Meaningless since version 4.2.
+ */
+ public String sourceDirAbsolutePath() {
+ return sourceDirAbsolutePath;
+ }
+
+ public DefaultInputFile setSourceDirAbsolutePath(String s) {
+ this.sourceDirAbsolutePath = FilenameUtils.normalize(s, true);
+ return this;
+ }
+
+ /**
+ * Used only for backward-compatibility. Meaningless since version 4.2.
+ */
+
+ public String pathRelativeToSourceDir() {
+ return pathRelativeToSourceDir;
+ }
+
+ public DefaultInputFile setPathRelativeToSourceDir(String s) {
+ this.pathRelativeToSourceDir = FilenameUtils.normalize(s, true);
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ DefaultInputFile that = (DefaultInputFile) o;
+ return relativePath.equals(that.relativePath);
+ }
+
+ @Override
+ public int hashCode() {
+ return relativePath.hashCode();
+ }
+
+ /**
+ * @deprecated in 4.2. Use {@link org.sonar.api.batch.fs.FileSystem#baseDir()}
+ */
+ @Deprecated
+ @Override
+ public File getFileBaseDir() {
+ return new File(basedir);
+ }
+
+ public void setBasedir(File basedir) {
+ this.basedir = PathUtils.sanitize(basedir.getAbsolutePath());
+ }
+
+ /**
+ * @deprecated in 4.2. Use {@link #file()}
+ */
+ @Deprecated
+ @Override
+ public File getFile() {
+ return file();
+ }
+
+ /**
+ * @deprecated in 4.2. Use {@link #relativePath()}
+ */
+ @Deprecated
+ @Override
+ public String getRelativePath() {
+ return relativePath();
+ }
+
+ @Override
+ public InputStream getInputStream() throws FileNotFoundException {
+ return new BufferedInputStream(new FileInputStream(file()));
+ }
+}
+
+
+
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import com.google.common.collect.ImmutableList;
+import org.sonar.api.batch.fs.InputFile;
+
+import javax.annotation.CheckForNull;
+import java.util.List;
+
+// Accepted to support both InputFile and InputDir as long as indexes are on the same attributes
+public interface FileIndex {
+
+ // Currently only a single index is supported
+ List<FileIndex> ALL = ImmutableList.<FileIndex>of(new RelativePathIndex());
+
+ @CheckForNull
+ Object valueOf(InputFile f);
+
+ String id();
+
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.utils.PathUtils;
+import org.sonar.api.utils.WildcardPattern;
+
+import java.io.File;
+
+public abstract class PathPattern {
+
+ final WildcardPattern pattern;
+
+ PathPattern(String pattern) {
+ this.pattern = WildcardPattern.create(pattern);
+ }
+
+ public abstract boolean match(InputFile inputFile);
+
+ public abstract boolean match(File ioFile, String relativePathFromBasedir);
+
+ public abstract boolean match(InputFile inputFile, boolean caseSensitiveFileExtension);
+
+ public static PathPattern create(String s) {
+ String trimmed = StringUtils.trim(s);
+ if (StringUtils.startsWithIgnoreCase(trimmed, "file:")) {
+ return new AbsolutePathPattern(StringUtils.substring(trimmed, "file:".length()));
+ }
+ return new RelativePathPattern(trimmed);
+ }
+
+ public static PathPattern[] create(String[] s) {
+ PathPattern[] result = new PathPattern[s.length];
+ for (int i = 0; i < s.length; i++) {
+ result[i] = create(s[i]);
+ }
+ return result;
+ }
+
+ private static class AbsolutePathPattern extends PathPattern {
+ private AbsolutePathPattern(String pattern) {
+ super(pattern);
+ }
+
+ @Override
+ public boolean match(File ioFile, String relativePathFromBasedir) {
+ String path = PathUtils.sanitize(ioFile.getAbsolutePath());
+ return pattern.match(path);
+ }
+
+ @Override
+ public boolean match(InputFile inputFile) {
+ return match(inputFile, true);
+ }
+
+ @Override
+ public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
+ String path = inputFile.absolutePath();
+ if (!caseSensitiveFileExtension) {
+ String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
+ if (StringUtils.isNotBlank(extension)) {
+ StringUtils.removeEndIgnoreCase(path, extension);
+ path = path + extension;
+ }
+ }
+ return pattern.match(path);
+ }
+
+ @Override
+ public String toString() {
+ return "file:" + pattern.toString();
+ }
+ }
+
+ /**
+ * Path relative to module basedir
+ */
+ private static class RelativePathPattern extends PathPattern {
+ private RelativePathPattern(String pattern) {
+ super(pattern);
+ }
+
+ @Override
+ public boolean match(File ioFile, String relativePathFromBasedir) {
+ return relativePathFromBasedir != null && pattern.match(relativePathFromBasedir);
+ }
+
+ @Override
+ public boolean match(InputFile inputFile) {
+ return match(inputFile, true);
+ }
+
+ @Override
+ public boolean match(InputFile inputFile, boolean caseSensitiveFileExtension) {
+ String path = inputFile.relativePath();
+ if (!caseSensitiveFileExtension) {
+ String extension = sanitizeExtension(FilenameUtils.getExtension(inputFile.file().getName()));
+ if (StringUtils.isNotBlank(extension)) {
+ path = StringUtils.removeEndIgnoreCase(path, extension);
+ path = path + extension;
+ }
+ }
+ return path != null && pattern.match(path);
+ }
+
+ @Override
+ public String toString() {
+ return pattern.toString();
+ }
+ }
+
+ static String sanitizeExtension(String suffix) {
+ return StringUtils.lowerCase(StringUtils.removeStart(suffix, "."));
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import org.sonar.api.batch.fs.InputFile;
+
+/**
+ * @since 4.2
+ */
+public class RelativePathIndex implements FileIndex {
+ public static final String ID = "rel";
+
+ @Override
+ public Object valueOf(InputFile f) {
+ return f.relativePath();
+ }
+
+ @Override
+ public String id() {
+ return ID;
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.api.batch.fs.internal;
+
+import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.api.batch.fs;
+
+import javax.annotation.ParametersAreNonnullByDefault;
import com.google.common.annotations.Beta;
import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.resources.Resource;
-import org.sonar.api.scan.filesystem.InputFile;
/**
* <p>This interface is not intended to be implemented by clients.</p>
public static FileQuery on(FileType... types) {
FileQuery query = new FileQuery();
for (FileType type : types) {
- query.on(InputFile.ATTRIBUTE_TYPE, type.typeValue());
+ query.on("TYPE", type.typeValue());
}
return query;
}
*/
public static FileQuery onMain() {
FileQuery query = new FileQuery();
- return query.on(InputFile.ATTRIBUTE_TYPE, InputFile.TYPE_MAIN);
+ return query.on("TYPE", "MAIN");
}
public static FileQuery onTest() {
FileQuery query = new FileQuery();
- return query.on(InputFile.ATTRIBUTE_TYPE, InputFile.TYPE_TEST);
+ return query.on("TYPE", "TEST");
}
private FileQuery() {
*/
@Deprecated
public Collection<FileType> types() {
- return Collections2.transform(attributes.get(InputFile.ATTRIBUTE_TYPE), new Function<String, FileType>() {
+ return Collections2.transform(attributes.get("TYPE"), new Function<String, FileType>() {
@Override
public FileType apply(@Nullable String input) {
return input != null ? FileType.valueOf(input) : null;
}
public Collection<String> typeAttributes() {
- return attributes.get(InputFile.ATTRIBUTE_TYPE);
+ return attributes.get("TYPE");
}
public Collection<String> languages() {
- return attributes.get(InputFile.ATTRIBUTE_LANGUAGE);
+ return attributes.get("LANG");
}
public FileQuery onLanguage(String... languages) {
- return on(InputFile.ATTRIBUTE_LANGUAGE, languages);
+ return on("LANG", languages);
}
public Collection<String> inclusions() {
throw new UnsupportedOperationException("TODO");
}
- public FileQuery withFilters(FileFilter... filters) {
- throw new UnsupportedOperationException("TODO");
- }
-
@Override
public boolean equals(Object obj) {
if (obj == null) {
/**
* @since 3.5
- * @deprecated since 4.2 use {@link InputFile#TYPE_MAIN} or {@link InputFile#TYPE_TEST}
+ * @deprecated in 4.2
*/
@Deprecated
public enum FileType {
- SOURCE(InputFile.TYPE_MAIN), TEST(InputFile.TYPE_TEST);
+ SOURCE("MAIN"), TEST("TEST"), MAIN("MAIN");
private String typeValue;
this.typeValue = typeValue;
}
- String typeValue() {
+ public String typeValue() {
return typeValue;
}
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem;
-
-import javax.annotation.CheckForNull;
-
-import java.io.File;
-import java.io.Serializable;
-import java.nio.charset.Charset;
-import java.util.Map;
-
-public interface InputFile extends Serializable {
-
- /**
- * Detected language
- */
- String ATTRIBUTE_LANGUAGE = "LANG";
-
- /**
- * Number of lines in the file.
- */
- String ATTRIBUTE_LINE_COUNT = "LINE_COUNT";
-
- /**
- * Type of source file. For now only possible values are {@link #TYPE_MAIN} or {@link #TYPE_TEST}
- */
- String ATTRIBUTE_TYPE = "TYPE";
- String TYPE_MAIN = "MAIN";
- String TYPE_TEST = "TEST";
-
- String ATTRIBUTE_STATUS = "STATUS";
- String STATUS_SAME = "SAME";
- String STATUS_CHANGED = "CHANGED";
- String STATUS_ADDED = "ADDED";
-
- /**
- * Path is relative from module base directory. Path is unique and identifies file
- * within given <code>{@link org.sonar.api.scan.filesystem.ModuleFileSystem}</code>.
- * File separator is the forward slash ('/'), even on MSWindows.
- * <p/>
- * Returns <code>src/main/java/com/Foo.java</code> if module base dir is
- * <code>/absolute/path/to/module</code> and if file is
- * <code>/absolute/path/to/module/src/main/java/com/Foo.java</code>.
- * <p/>
- * Returned path is never null.
- */
- String path();
-
- /**
- * Not-null canonical path. File separator is forward slash ('/'), even on MSWindows.
- */
- String absolutePath();
-
- File file();
-
- Charset encoding();
-
- /**
- * Not-null filename, including extension
- */
- String name();
-
- /**
- * Not-null type (is it a main file or a unit test file?).
- * See constant values prefixed by <code>TYPE_</code>, for example {@link #TYPE_MAIN}.
- */
- String type();
-
- /**
- * Does the given attribute have the given value ?
- */
- boolean has(String attribute, String value);
-
- /**
- * See list of attribute keys in constants starting with ATTRIBUTE_.
- */
- @CheckForNull
- String attribute(String key);
-
- Map<String, String> attributes();
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem;
-
-import org.sonar.api.BatchExtension;
-
-/**
- * Implement this extension to limit the set of files to be analyzed. Global file inclusion/exclusion patterns
- * are already applied.
- *
- * @since 4.2
- */
-public interface InputFileFilter extends BatchExtension {
-
- boolean accept(InputFile inputFile);
-
-}
import org.sonar.api.BatchComponent;
import javax.annotation.CheckForNull;
-
import java.io.File;
import java.nio.charset.Charset;
import java.util.List;
/**
* @since 3.5
+ * @deprecated in 4.2. Replaced by {@link org.sonar.api.batch.fs.FileSystem}
*/
+@Deprecated
public interface ModuleFileSystem extends BatchComponent {
/**
* Example in Maven : ${project.basedir}/src/main/java
* @deprecated since 4.2 will always return {@link #baseDir()}
*/
- @Deprecated
List<File> sourceDirs();
/**
* Example in Maven : ${project.basedir}/src/test/java
* @deprecated since 4.2 will always return {@link #baseDir()}
*/
- @Deprecated
List<File> testDirs();
/**
* </ul>
* @deprecated since 4.2 sonar.binaries should be converted to language specific property
*/
- @Deprecated
List<File> binaryDirs();
/**
* Search for files. Never return null.
- * @deprecated since 4.2 use {@link #inputFiles(FileQuery)}
*/
- @Deprecated
List<File> files(FileQuery query);
- /**
- * Search for input files. Never return null.
- * @since 4.2
- */
- Iterable<InputFile> inputFiles(FileQuery query);
-
- /**
- * Search for input file corresponding to the given java.io.File.
- * @since 4.2
- */
- @CheckForNull
- InputFile inputFile(File ioFile);
-
/**
* Default charset for files of the module. If it's not defined, then
* return the platform default charset. When trying to read an input file it is better to rely on
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem.internal;
-
-import org.apache.commons.codec.Charsets;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.scan.filesystem.InputFile;
-import org.sonar.api.utils.PathUtils;
-
-import javax.annotation.CheckForNull;
-import java.io.File;
-import java.nio.charset.Charset;
-import java.util.Map;
-
-/**
- * PLUGINS MUST NOT USE THIS CLASS, EVEN FOR UNIT TESTING.
- *
- * @since 4.0
- */
-public class DefaultInputFile implements InputFile {
-
- /**
- * We're not sure that this is the correct way, so not in API yet.
- */
- public static final String ATTRIBUTE_COMPONENT_KEY = "CMP_KEY";
-
- public static final String ATTRIBUTE_COMPONENT_DEPRECATED_KEY = "CMP_DEPRECATED_KEY";
-
- public static final String ATTRIBUTE_HASH = "HASH";
-
- /**
- * Relative path from source directory. File separator is the forward slash ('/'),
- * even on MSWindows.
- * @deprecated since 4.2 No more sonar.sources
- */
- @Deprecated
- public static final String ATTRIBUTE_SOURCE_RELATIVE_PATH = "SRC_REL_PATH";
-
- /**
- * Canonical path of source directory.
- * Example: <code>/path/to/module/src/main/java</code> or <code>C:\path\to\module\src\main\java</code>
- * @deprecated since 4.2 No more sonar.sources
- */
- @Deprecated
- public static final String ATTRIBUTE_SOURCEDIR_PATH = "SRC_DIR_PATH";
-
- private final String absolutePath;
- private final String path;
- private final Map<String, String> attributes;
- private final String encoding;
-
- private DefaultInputFile(File file, Charset encoding, String path, Map<String, String> attributes) {
- this.encoding = encoding.name();
- this.absolutePath = PathUtils.canonicalPath(file);
- this.path = FilenameUtils.separatorsToUnix(path);
- this.attributes = attributes;
- }
-
- /**
- * Plugins must not build their own instances of {@link InputFile}.
- * {@link org.sonar.api.scan.filesystem.ModuleFileSystem} must be used to search for files to scan.
- * <p/>
- * Usage: <code>InputFile.create(file, "src/main/java/com/Foo.java", attributes)</code>
- */
- public static DefaultInputFile create(File file, Charset encoding, String path, Map<String, String> attributes) {
- return new DefaultInputFile(file, encoding, path, attributes);
- }
-
- @Override
- public String path() {
- return path;
- }
-
- @Override
- public String absolutePath() {
- return absolutePath;
- }
-
- @Override
- public File file() {
- return new File(absolutePath);
- }
-
- @Override
- public Charset encoding() {
- return Charsets.toCharset(encoding);
- }
-
- @Override
- public String name() {
- return file().getName();
- }
-
- @Override
- public String type() {
- return attribute(ATTRIBUTE_TYPE);
- }
-
- @Override
- public boolean has(String attribute, String value) {
- return StringUtils.equals(attributes.get(attribute), value);
- }
-
- @Override
- @CheckForNull
- public String attribute(String key) {
- return attributes.get(key);
- }
-
- @Override
- public Map<String, String> attributes() {
- return attributes;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- DefaultInputFile other = (DefaultInputFile) o;
- return absolutePath.equals(other.absolutePath);
- }
-
- @Override
- public int hashCode() {
- return absolutePath.hashCode();
- }
-
- public DefaultInputFile setLines(long l) {
- attributes.put(ATTRIBUTE_LINE_COUNT, String.valueOf(l));
- return this;
- }
-
- public String language() {
- return attributes.get(ATTRIBUTE_LANGUAGE);
- }
-
- public DefaultInputFile setLanguage(String s) {
- attributes.put(ATTRIBUTE_LANGUAGE, s);
- return this;
- }
-
- public DefaultInputFile setHash(String s) {
- attributes.put(ATTRIBUTE_HASH, s);
- return this;
- }
-
- public DefaultInputFile setStatus(String s) {
- attributes.put(ATTRIBUTE_STATUS, s);
- return this;
- }
-
- public DefaultInputFile setKey(String s) {
- attributes.put(ATTRIBUTE_COMPONENT_KEY, s);
- return this;
- }
-
- public DefaultInputFile setDeprecatedKey(String s) {
- attributes.put(ATTRIBUTE_COMPONENT_DEPRECATED_KEY, s);
- return this;
- }
-
- public DefaultInputFile setType(String s) {
- attributes.put(ATTRIBUTE_TYPE, s);
- return this;
- }
-
- /**
- * Used only for backward-compatibility. Meaningless since version 4.2.
- */
- public String sourceDirAbsolutePath() {
- return attributes.get(ATTRIBUTE_SOURCEDIR_PATH);
- }
-
- public DefaultInputFile setSourceDirAbsolutePath(String s) {
- attributes.put(ATTRIBUTE_SOURCEDIR_PATH, FilenameUtils.normalize(s, true));
- return this;
- }
-
- /**
- * Used only for backward-compatibility. Meaningless since version 4.2.
- */
- public String pathRelativeToSourceDir() {
- return attributes.get(ATTRIBUTE_SOURCE_RELATIVE_PATH);
- }
-
- public DefaultInputFile setPathRelativeToSourceDir(String s) {
- attributes.put(ATTRIBUTE_SOURCE_RELATIVE_PATH, FilenameUtils.normalize(s, true));
- return this;
- }
-
- @Override
- public String toString() {
- return String.format("[%s,%s]", path, type());
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem.internal;
-
-import org.sonar.api.scan.filesystem.InputFile;
-
-import org.sonar.api.utils.PathUtils;
-
-import javax.annotation.Nullable;
-
-import java.io.File;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * FOR UNIT-TESTING ONLY
- *
- * @since 4.0
- */
-public class InputFileBuilder {
-
- private final Map<String, String> attributes = new HashMap<String, String>();
- private final File file;
- private final String relativePath;
- private Charset encoding;
-
- public static void _FOR_UNIT_TESTING_ONLY_() {
- // For those who don't read javadoc
- }
-
- public InputFileBuilder(File file, Charset encoding, String relativePath) {
- this.file = file;
- this.encoding = encoding;
- this.relativePath = relativePath;
- }
-
- public InputFileBuilder attribute(String key, @Nullable String value) {
- if (value != null) {
- attributes.put(key, value);
- }
- return this;
- }
-
- public InputFileBuilder type(@Nullable String type) {
- return attribute(InputFile.ATTRIBUTE_TYPE, type);
- }
-
- public InputFileBuilder language(@Nullable String language) {
- return attribute(InputFile.ATTRIBUTE_LANGUAGE, language);
- }
-
- public InputFileBuilder hash(@Nullable String hash) {
- return attribute(DefaultInputFile.ATTRIBUTE_HASH, hash);
- }
-
- public InputFileBuilder status(@Nullable String status) {
- return attribute(InputFile.ATTRIBUTE_STATUS, status);
- }
-
- public InputFileBuilder sourceDir(File dir) {
- return attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH, PathUtils.canonicalPath(dir));
- }
-
- public InputFileBuilder sourceDir(@Nullable String path) {
- return attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH, PathUtils.sanitize(path));
- }
-
- public DefaultInputFile build() {
- return DefaultInputFile.create(file, encoding, relativePath, attributes);
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem.internal;
-
-import org.sonar.api.scan.filesystem.InputFile;
-
-import com.google.common.collect.Lists;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * @since 4.0
- */
-public class InputFiles {
- InputFiles() {
- // static methods only
- }
-
- public static List<File> toFiles(Iterable<InputFile> inputFiles) {
- List<File> files = Lists.newArrayList();
- for (InputFile inputFile : inputFiles) {
- files.add(inputFile.file());
- }
- return files;
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.api.scan.filesystem.internal;
-
-import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.batch.fs.internal;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
+
+import java.io.File;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class DefaultInputFileTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Test
+ public void test() throws Exception {
+ DefaultInputFile inputFile = new DefaultInputFile("src/Foo.php")
+ .setFile(temp.newFile("Foo.php"))
+ .setDeprecatedKey("deprecated")
+ .setKey("ABCDE")
+ .setHash("1234")
+ .setLines(42)
+ .setLanguage("php")
+ .setStatus(InputFile.Status.ADDED)
+ .setType(InputFile.Type.TEST);
+
+ assertThat(inputFile.relativePath()).isEqualTo("src/Foo.php");
+ assertThat(inputFile.getRelativePath()).isEqualTo("src/Foo.php");
+ assertThat(new File(inputFile.relativePath())).isRelative();
+ assertThat(inputFile.absolutePath()).endsWith("Foo.php");
+ assertThat(new File(inputFile.absolutePath())).isAbsolute();
+ assertThat(inputFile.language()).isEqualTo("php");
+ assertThat(inputFile.status()).isEqualTo(InputFile.Status.ADDED);
+ assertThat(inputFile.type()).isEqualTo(InputFile.Type.TEST);
+ assertThat(inputFile.lines()).isEqualTo(42);
+ assertThat(inputFile.hash()).isEqualTo("1234");
+ }
+
+ @Test
+ public void test_equals_and_hashcode() throws Exception {
+ DefaultInputFile f1 = new DefaultInputFile("src/Foo.php");
+ DefaultInputFile f1a = new DefaultInputFile("src/Foo.php");
+ DefaultInputFile f2 = new DefaultInputFile("src/Bar.php");
+
+ assertThat(f1).isEqualTo(f1);
+ assertThat(f1).isEqualTo(f1a);
+ assertThat(f1).isNotEqualTo(f2);
+ assertThat(f1.equals("foo")).isFalse();
+ assertThat(f1.equals(null)).isFalse();
+
+ assertThat(f1.hashCode()).isEqualTo(f1.hashCode());
+ assertThat(f1.hashCode()).isEqualTo(f1a.hashCode());
+ }
+}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem.internal;
-
-import org.sonar.api.scan.filesystem.InputFile;
-
-import com.google.common.base.Charsets;
-import org.apache.commons.io.FilenameUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.utils.PathUtils;
-
-import java.io.File;
-import java.io.IOException;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class DefaultInputFileTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void test_attributes() throws IOException {
- File file = temp.newFile();
- InputFile input = new InputFileBuilder(file, Charsets.UTF_8, "src/main/java/Foo.java")
- .attribute("foo", "bar")
- .type(InputFile.TYPE_TEST)
- .hash("ABC")
- .status(InputFile.STATUS_ADDED)
- .language("java")
- .build();
-
- assertThat(input.attributes()).hasSize(5);
- assertThat(input.attribute("unknown")).isNull();
- assertThat(input.attribute("foo")).isEqualTo("bar");
- assertThat(input.attribute(InputFile.ATTRIBUTE_TYPE)).isEqualTo(InputFile.TYPE_TEST);
- assertThat(input.attribute(DefaultInputFile.ATTRIBUTE_HASH)).isEqualTo("ABC");
- assertThat(input.attribute(InputFile.ATTRIBUTE_LANGUAGE)).isEqualTo("java");
- assertThat(input.attribute(InputFile.ATTRIBUTE_STATUS)).isEqualTo(InputFile.STATUS_ADDED);
-
- assertThat(input.has(InputFile.ATTRIBUTE_LANGUAGE, "java")).isTrue();
- assertThat(input.has(InputFile.ATTRIBUTE_LANGUAGE, "php")).isFalse();
- assertThat(input.has("unknown", "xxx")).isFalse();
- }
-
- @Test
- public void test_file() throws Exception {
- File sourceDir = temp.newFolder();
- File file = temp.newFile("Foo.java");
- InputFile input = new InputFileBuilder(file, Charsets.UTF_8, "src/main/java/Foo.java")
- .sourceDir(sourceDir)
- .build();
-
- assertThat(input.name()).isEqualTo("Foo.java");
- assertThat(input.file()).isEqualTo(file);
- assertThat(input.attribute(DefaultInputFile.ATTRIBUTE_SOURCEDIR_PATH)).isEqualTo(FilenameUtils.separatorsToUnix(sourceDir.getAbsolutePath()));
- assertThat(input.path()).isEqualTo("src/main/java/Foo.java");
- assertThat(input.absolutePath()).isEqualTo(PathUtils.canonicalPath(file));
- }
-
- @Test
- public void test_equals_and_hashCode() throws Exception {
- File file1 = temp.newFile();
- InputFile input1 = new InputFileBuilder(file1, Charsets.UTF_8, "src/main/java/Foo.java").build();
- InputFile input1a = new InputFileBuilder(file1, Charsets.UTF_8, "src/main/java/Foo.java").build();
- InputFile input2 = new InputFileBuilder(temp.newFile(), Charsets.UTF_8, "src/main/java/Bar.java").build();
-
- assertThat(input1.equals(input1)).isTrue();
- assertThat(input1.equals(input1a)).isTrue();
- assertThat(input1.equals(input2)).isFalse();
- assertThat(input1.hashCode()).isEqualTo(input1.hashCode());
- assertThat(input1.hashCode()).isEqualTo(input1a.hashCode());
- }
-
- @Test
- public void test_toString() throws Exception {
- File file1 = temp.newFile();
- InputFile input = new InputFileBuilder(file1, Charsets.UTF_8, "src/main/java/Foo.java").type(InputFile.TYPE_TEST).build();
- assertThat(input.toString()).isEqualTo("[src/main/java/Foo.java,TEST]");
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem.internal;
-
-import org.junit.Test;
-
-public class InputFileBuilderTest {
- @Test
- public void just_for_coverage() throws Exception {
- InputFileBuilder._FOR_UNIT_TESTING_ONLY_();
- // do not fail
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.scan.filesystem.internal;
-
-import org.sonar.api.scan.filesystem.InputFile;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.Lists;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.File;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class InputFilesTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void test_toFiles() throws Exception {
- File file1 = temp.newFile();
- File file2 = temp.newFile();
- InputFile input1 = new InputFileBuilder(file1, Charsets.UTF_8, "src/main/java/Foo.java").build();
- InputFile input2 = new InputFileBuilder(file2, Charsets.UTF_8, "src/main/java/Bar.java").build();
-
- assertThat(InputFiles.toFiles(Lists.newArrayList(input1, input2))).containsOnly(file1, file2);
- }
-}
*/
package org.sonar.server.rule.ws;
-import org.sonar.api.server.ws.Request;
-import org.sonar.api.server.ws.RequestHandler;
-import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
public class RulesWs implements WebService {
NewController controller = context.newController("api/rules")
.setDescription("Coding rules");
- controller.newAction("list")
- .setDescription("List coding rules")
- .setSince("4.2")
- .setHandler(new RequestHandler() {
- @Override
- public void handle(Request request, Response response) {
- list(request, response);
- }
- });
-
controller.newAction("show")
.setDescription("Detail of rule")
.setSince("4.2")
controller.done();
}
- void list(Request request, Response response) {
- response.newJsonWriter().beginObject()
- .prop("TODO", true)
- .endObject()
- .close();
- }
-
private void addTagParams(final NewAction action) {
action.newParam("key", "Full key of the rule");
action.newParam("tags", "Comma separated list of tags");
assertThat(controller).isNotNull();
assertThat(controller.path()).isEqualTo("api/rules");
assertThat(controller.description()).isNotEmpty();
- assertThat(controller.actions()).hasSize(4);
-
- WebService.Action search = controller.action("list");
- assertThat(search).isNotNull();
- assertThat(search.handler()).isNotNull();
- assertThat(search.since()).isEqualTo("4.2");
- assertThat(search.isPost()).isFalse();
- assertThat(search.isPrivate()).isFalse();
+ assertThat(controller.actions()).hasSize(3);
WebService.Action show = controller.action("show");
assertThat(show).isNotNull();
assertThat(removeTags.isPrivate()).isFalse();
assertThat(removeTags.params()).hasSize(2);
}
-
- @Test
- public void search_for_rules() throws Exception {
- tester.newRequest("list").execute().assertJson(getClass(), "list.json");
- }
-
}
+++ /dev/null
-{
- "TODO": true
-}