From: Evgeny Mandrikov Date: Wed, 26 Jan 2011 17:59:13 +0000 (+0300) Subject: SONAR-2126: Change API to work with file system of a project X-Git-Tag: 2.6~98 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c2f90c84e3fef821bfdee686351375a2732ac06e;p=sonarqube.git SONAR-2126: Change API to work with file system of a project * Use language keys instead of objects. * ProjectFileSystem now BatchComponent, so DefaultProjectFileSystem uses benefits from injections and some old code was removed from it to improve immutability. * Small performance improvement for DefaultInputFile. --- diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java index 0e7a1c1e3f4..23bcd777f59 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/JavaSourceImporter.java @@ -50,8 +50,8 @@ public final class JavaSourceImporter implements Sensor { } void analyse(ProjectFileSystem fileSystem, SensorContext context) { - parseDirs(context, fileSystem.mainFiles(Java.INSTANCE), false, fileSystem.getSourceCharset()); - parseDirs(context, fileSystem.testFiles(Java.INSTANCE), true, fileSystem.getSourceCharset()); + parseDirs(context, fileSystem.mainFiles(Java.KEY), false, fileSystem.getSourceCharset()); + parseDirs(context, fileSystem.testFiles(Java.KEY), true, fileSystem.getSourceCharset()); } void parseDirs(SensorContext context, List inputFiles, boolean unitTest, Charset sourcesEncoding) { diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java index c79a60d2559..56245cd153b 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java @@ -83,7 +83,7 @@ public class SquidSensor implements Sensor { } private void browseTestSources(Project project, SensorContext context) { - for (InputFile testFile : project.getFileSystem().testFiles(Java.INSTANCE)) { + for (InputFile testFile : project.getFileSystem().testFiles(Java.KEY)) { context.index(JavaFile.fromRelativePath(testFile.getRelativePath(), true)); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java index c0c519f05a8..4e138e5cfec 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectBuilder.java @@ -27,7 +27,6 @@ import org.sonar.api.batch.maven.MavenUtils; 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.DefaultProjectFileSystem; import org.sonar.api.resources.Java; import org.sonar.api.resources.Project; import org.sonar.api.utils.SonarException; @@ -76,15 +75,8 @@ public class MavenProjectBuilder { void configure(Project project, Configuration projectConfiguration) { Date analysisDate = loadAnalysisDate(projectConfiguration); - DefaultProjectFileSystem fs = new DefaultProjectFileSystem(project); MavenProject pom = project.getPom(); if (pom != null) { - fs.setBaseDir(pom.getBasedir()); - fs.setBuildDir(pom.getBuild().getDirectory()); - projectConfiguration.setProperty("project.build.outputDirectory", pom.getBuild().getOutputDirectory()); - if (pom.getReporting() != null) { - projectConfiguration.setProperty("project.reporting.outputDirectory", pom.getReporting().getOutputDirectory()); - } projectConfiguration.setProperty("sonar.java.sourceVersion", MavenUtils.getJavaSourceVersion(pom)); projectConfiguration.setProperty("sonar.java.targetVersion", MavenUtils.getJavaVersion(pom)); } @@ -94,8 +86,7 @@ public class MavenProjectBuilder { .setLatestAnalysis(isLatestAnalysis(project.getKey(), analysisDate)) .setAnalysisVersion(loadAnalysisVersion(projectConfiguration, pom)) .setAnalysisType(loadAnalysisType(projectConfiguration)) - .setLanguageKey(loadLanguageKey(projectConfiguration)) - .setFileSystem(fs); + .setLanguageKey(loadLanguageKey(projectConfiguration)); } static String[] loadExclusionPatterns(Configuration configuration) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java index 6bc1ac2862c..a0bb1c58dce 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java @@ -22,16 +22,12 @@ package org.sonar.batch; import org.picocontainer.Characteristics; import org.picocontainer.MutablePicoContainer; import org.sonar.api.batch.BatchExtensionDictionnary; -import org.sonar.api.batch.FileFilter; import org.sonar.api.batch.ProjectClasspath; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; import org.sonar.api.measures.Metrics; import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.resources.DefaultProjectFileSystem; -import org.sonar.api.resources.Language; -import org.sonar.api.resources.Languages; -import org.sonar.api.resources.Project; +import org.sonar.api.resources.*; import org.sonar.api.rules.DefaultRulesManager; import org.sonar.api.utils.IocContainer; import org.sonar.api.utils.SonarException; @@ -44,8 +40,6 @@ import org.sonar.batch.phases.Phases; import org.sonar.core.components.DefaultModelFinder; import org.sonar.jpa.dao.*; -import java.util.List; - public class ProjectBatch { private MutablePicoContainer globalContainer; @@ -71,6 +65,7 @@ public class ProjectBatch { batchContainer.as(Characteristics.CACHE).addComponent(project); batchContainer.as(Characteristics.CACHE).addComponent(project.getPom()); batchContainer.as(Characteristics.CACHE).addComponent(ProjectClasspath.class); + batchContainer.as(Characteristics.CACHE).addComponent(DefaultProjectFileSystem.class); batchContainer.as(Characteristics.CACHE).addComponent(project.getConfiguration()); // need to be registered after the Configuration @@ -80,7 +75,8 @@ public class ProjectBatch { batchContainer.as(Characteristics.CACHE).addComponent(RulesDao.class); // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor) - batchContainer.as(Characteristics.CACHE).addComponent(globalContainer.getComponent(DefaultResourcePersister.class).getSnapshot(project)); + batchContainer.as(Characteristics.CACHE) + .addComponent(globalContainer.getComponent(DefaultResourcePersister.class).getSnapshot(project)); batchContainer.as(Characteristics.CACHE).addComponent(org.sonar.api.database.daos.RulesDao.class); batchContainer.as(Characteristics.CACHE).addComponent(org.sonar.api.database.daos.MeasuresDao.class); @@ -113,10 +109,15 @@ public class ProjectBatch { throw new SonarException("Language with key '" + project.getLanguageKey() + "' not found"); } project.setLanguage(language); - index.setCurrentProject(project, getComponent(ResourceFilters.class), getComponent(ViolationFilters.class), getComponent(RulesProfile.class)); - List fileFilters = batchContainer.getComponents(FileFilter.class); - ((DefaultProjectFileSystem) project.getFileSystem()).addFileFilters(fileFilters); + index.setCurrentProject(project, + getComponent(ResourceFilters.class), + getComponent(ViolationFilters.class), + getComponent(RulesProfile.class)); + + // TODO See http://jira.codehaus.org/browse/SONAR-2126 + // previously MavenProjectBuilder was responsible for creation of ProjectFileSystem + project.setFileSystem(getComponent(ProjectFileSystem.class)); } private void loadCoreComponents(MutablePicoContainer container) { @@ -146,7 +147,6 @@ public class ProjectBatch { } } - public T getComponent(Class clazz) { if (batchContainer != null) { return batchContainer.getComponent(clazz); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java index 85a47eb8945..8252b60bf87 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java @@ -42,19 +42,24 @@ import java.util.List; * For internal use only. * * @since 1.10 - * @TODO inject into container + * @TODO in fact this class should not be located in sonar-plugin-api */ public class DefaultProjectFileSystem implements ProjectFileSystem { private Project project; + private Languages languages; private List filters = Lists.newArrayList(); - private File basedir; - private File buildDir; - private List testDirs = Lists.newArrayList(); - - public DefaultProjectFileSystem(Project project) { + public DefaultProjectFileSystem(Project project, Languages languages) { this.project = project; + this.languages = languages; + } + + public DefaultProjectFileSystem(Project project, Languages languages, FileFilter... fileFilters) { + this(project, languages); + for (FileFilter fileFilter : fileFilters) { + filters.add(new DelegateFileFilter(fileFilter)); + } } public Charset getSourceCharset() { @@ -70,31 +75,16 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { return Charset.defaultCharset(); } - public DefaultProjectFileSystem addFileFilters(List l) { - for (FileFilter fileFilter : l) { - addFileFilter(fileFilter); - } - return this; - } - - public DefaultProjectFileSystem addFileFilter(FileFilter fileFilter) { - filters.add(new DelegateFileFilter(fileFilter)); - return this; - } - public File getBasedir() { - // TODO was return project.getPom().getBasedir(); - return basedir; + return project.getPom().getBasedir(); } public File getBuildDir() { - // TODO was return resolvePath(project.getPom().getBuild().getDirectory()); - return buildDir; + return resolvePath(project.getPom().getBuild().getDirectory()); } public File getBuildOutputDir() { - // TODO was return resolvePath(project.getPom().getBuild().getOutputDirectory()); - return resolvePath(project.getConfiguration().getString("project.build.outputDirectory")); + return resolvePath(project.getPom().getBuild().getOutputDirectory()); } /** @@ -104,6 +94,10 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { return resolvePaths(project.getPom().getCompileSourceRoots()); } + /** + * @deprecated since 2.6, because should be immutable + */ + @Deprecated public DefaultProjectFileSystem addSourceDir(File dir) { if (dir == null) { throw new IllegalArgumentException("Can not add null to project source dirs"); @@ -119,6 +113,10 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { return resolvePaths(project.getPom().getTestCompileSourceRoots()); } + /** + * @deprecated since 2.6, because should be immutable + */ + @Deprecated public DefaultProjectFileSystem addTestDir(File dir) { if (dir == null) { throw new IllegalArgumentException("Can not add null to project test dirs"); @@ -128,8 +126,7 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { } public File getReportOutputDir() { - // TODO was return resolvePath(project.getPom().getReporting().getOutputDirectory()); - return resolvePath(project.getConfiguration().getString("project.reporting.outputDirectory")); + return resolvePath(project.getPom().getReporting().getOutputDirectory()); } public File getSonarWorkingDirectory() { @@ -151,8 +148,7 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { return file; } - // TODO was private - public List resolvePaths(List paths) { + private List resolvePaths(List paths) { List result = Lists.newArrayList(); if (paths != null) { for (String path : paths) { @@ -164,7 +160,7 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { @Deprecated public List getSourceFiles(Language... langs) { - return toFiles(mainFiles(langs)); + return toFiles(mainFiles(getLanguageKeys(langs))); } @Deprecated @@ -173,19 +169,20 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { } public boolean hasJavaSourceFiles() { - return !mainFiles(Java.INSTANCE).isEmpty(); + return !mainFiles(Java.KEY).isEmpty(); } @Deprecated public List getTestFiles(Language... langs) { - return toFiles(testFiles(langs)); + return toFiles(testFiles(getLanguageKeys(langs))); } + @Deprecated public boolean hasTestFiles(Language lang) { - return !testFiles(lang).isEmpty(); + return !testFiles(lang.getKey()).isEmpty(); } - private List getFiles(List directories, boolean applyExclusionPatterns, Language... langs) { + private List getFiles(List directories, boolean applyExclusionPatterns, String... langs) { List result = Lists.newArrayList(); if (directories == null) { return result; @@ -202,7 +199,8 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { dirFilters.addAll(this.filters); List files = (List) FileUtils.listFiles(dir, new AndFileFilter(dirFilters), HiddenFileFilter.VISIBLE); for (File file : files) { - result.add(new DefaultInputFile(dir, file)); + String relativePath = DefaultProjectFileSystem.getRelativePath(file, dir); + result.add(new DefaultInputFile(dir, relativePath)); } } } @@ -219,20 +217,14 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { return exclusionPatterns; } - private IOFileFilter getFileSuffixFilter(Language... langs) { + private IOFileFilter getFileSuffixFilter(String... langKeys) { IOFileFilter suffixFilter = FileFilterUtils.trueFileFilter(); - if (langs != null && langs.length > 0) { - List suffixes = new ArrayList(); - for (Language lang : langs) { - if (lang.getFileSuffixes() != null) { - suffixes.addAll(Arrays.asList(lang.getFileSuffixes())); - } - } + if (langKeys != null && langKeys.length > 0) { + List suffixes = Arrays.asList(languages.getSuffixes(langKeys)); if (!suffixes.isEmpty()) { suffixFilter = new SuffixFileFilter(suffixes); } } - return suffixFilter; } @@ -331,6 +323,20 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { return false; } + /** + * Conversion from Language to key. Allows to provide backward compatibility. + */ + private String[] getLanguageKeys(Language[] langs) { + String[] keys = new String[langs.length]; + for (int i = 0; i < langs.length; i++) { + keys[i] = langs[i].getKey(); + } + return keys; + } + + /** + * Conversion from InputFile to File. Allows to provide backward compatibility. + */ private static List toFiles(List files) { List result = Lists.newArrayList(); for (InputFile file : files) { @@ -342,24 +348,24 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { /** * @since 2.6 */ - public List mainFiles(Language... langs) { + public List mainFiles(String... langs) { return getFiles(getSourceDirs(), true, langs); } /** * @since 2.6 */ - public List testFiles(Language... langs) { + public List testFiles(String... langs) { return getFiles(getTestDirs(), false /* FIXME should be true? */, langs); } private static final class DefaultInputFile implements InputFile { private File basedir; - private File file; + private String relativePath; - DefaultInputFile(File basedir, File file) { + DefaultInputFile(File basedir, String relativePath) { this.basedir = basedir; - this.file = file; + this.relativePath = relativePath; } public File getFileBaseDir() { @@ -367,25 +373,11 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { } public File getFile() { - return file; + return new File(basedir, relativePath); } public String getRelativePath() { - return DefaultProjectFileSystem.getRelativePath(file, basedir); + return relativePath; } } - - /** - * @since 2.6 - */ - public void setBaseDir(File basedir) { - this.basedir = basedir; - } - - /** - * @since 2.6 - */ - public void setBuildDir(String path) { - this.buildDir = path == null ? resolvePath("target") : resolvePath(path); - } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java index bfecdbd3eba..5737d3da5f6 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java @@ -367,6 +367,7 @@ public class Project extends Resource { /** * @deprecated since 2.6. See http://jira.codehaus.org/browse/SONAR-2126 + * ProjectFileSystem can be retrieved as an IoC dependency */ public ProjectFileSystem getFileSystem() { return fileSystem; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectFileSystem.java index f64f98d4f9a..a670714ecb0 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectFileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/ProjectFileSystem.java @@ -19,7 +19,7 @@ */ package org.sonar.api.resources; -import org.sonar.api.BatchExtension; +import org.sonar.api.BatchComponent; import java.io.File; import java.io.IOException; @@ -29,7 +29,7 @@ import java.util.List; /** * @since 1.10 */ -public interface ProjectFileSystem extends BatchExtension { +public interface ProjectFileSystem extends BatchComponent { /** * Source encoding. * Never null, it returns the default platform charset if it is not defined in project. @@ -61,6 +61,8 @@ public interface ProjectFileSystem extends BatchExtension { * Adds a source directory * * @return the current object + * @deprecated since 2.6 - ProjectFileSystem should be immutable + * See http://jira.codehaus.org/browse/SONAR-2126 */ ProjectFileSystem addSourceDir(File dir); @@ -73,6 +75,8 @@ public interface ProjectFileSystem extends BatchExtension { * Adds a test directory * * @return the current object + * @deprecated since 2.6 - ProjectFileSystem should be immutable + * See http://jira.codehaus.org/browse/SONAR-2126 */ ProjectFileSystem addTestDir(File dir); @@ -113,7 +117,10 @@ public interface ProjectFileSystem extends BatchExtension { /** * Check if the project has Java files, excluding unit tests and files matching project exclusion patterns. + * + * @deprecated since 2.6 - API should be language agnostic */ + @Deprecated boolean hasJavaSourceFiles(); /** @@ -127,7 +134,10 @@ public interface ProjectFileSystem extends BatchExtension { /** * Check if the project has unit test files, excluding files matching project exclusion patterns. + * + * @deprecated since 2.6 - use language key instead of Language object */ + @Deprecated boolean hasTestFiles(Language lang); /** @@ -147,7 +157,7 @@ public interface ProjectFileSystem extends BatchExtension { * @param langs language filter. If null or empty, will return empty list * @since 2.6 */ - List mainFiles(Language... langs); + List mainFiles(String... langs); /** * TODO comment me @@ -155,6 +165,6 @@ public interface ProjectFileSystem extends BatchExtension { * @param langs language filter. If null or empty, will return empty list * @since 2.6 */ - List testFiles(Language... langs); + List testFiles(String... langs); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java index 52840b4a7ee..64733907b85 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java @@ -160,18 +160,19 @@ public class DefaultProjectFileSystemTest { } @Test - public void shouldAddExtendedFilters() { - DefaultProjectFileSystem fs = newDefaultProjectFileSystem(project); - assertThat(fs.getSourceFiles().size(), is(2)); - assertThat(fs.getSourceFiles(), hasItem(named("Bar.java"))); + public void shouldUseExtendedFilters() { + DefaultProjectFileSystem fsWithoutFilter = newDefaultProjectFileSystem(project); + assertThat(fsWithoutFilter.getSourceFiles().size(), is(2)); + assertThat(fsWithoutFilter.getSourceFiles(), hasItem(named("Bar.java"))); - fs.addFileFilter(new FileFilter() { + FileFilter filter = new FileFilter() { public boolean accept(File file) { return !StringUtils.equals(file.getName(), "Bar.java"); } - }); - assertThat(fs.getSourceFiles().size(), is(1)); - assertThat(fs.getSourceFiles(), not(hasItem(named("Bar.java")))); + }; + DefaultProjectFileSystem fsWithFilter = new DefaultProjectFileSystem(project, new Languages(Java.INSTANCE), filter); + assertThat(fsWithFilter.getSourceFiles().size(), is(1)); + assertThat(fsWithFilter.getSourceFiles(), not(hasItem(named("Bar.java")))); } private DefaultProjectFileSystem newDefaultProjectFileSystem(Project project) { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/test/MavenTestUtils.java b/sonar-plugin-api/src/test/java/org/sonar/api/test/MavenTestUtils.java index cd193541562..7ab0604e223 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/test/MavenTestUtils.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/test/MavenTestUtils.java @@ -25,6 +25,8 @@ import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.project.MavenProject; import org.sonar.api.resources.DefaultProjectFileSystem; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.Languages; import org.sonar.api.resources.Project; import org.sonar.api.utils.SonarException; @@ -67,14 +69,8 @@ public final class MavenTestUtils { Project project = new Project(pom.getGroupId() + ":" + pom.getArtifactId()) .setPom(pom) .setConfiguration(new MapConfiguration(pom.getProperties())); - DefaultProjectFileSystem fs = new DefaultProjectFileSystem(project); + DefaultProjectFileSystem fs = new DefaultProjectFileSystem(project, new Languages(Java.INSTANCE)); project.setFileSystem(fs); - project.getConfiguration().setProperty("project.build.outputDirectory", pom.getBuild().getOutputDirectory()); - if (pom.getReporting() != null) { - project.getConfiguration().setProperty("project.reporting.outputDirectory", pom.getReporting().getOutputDirectory()); - } - fs.setBaseDir(project.getPom().getBasedir()); - fs.setBuildDir(project.getPom().getBuild().getDirectory()); return project; } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/test/SimpleProjectFileSystem.java b/sonar-plugin-api/src/test/java/org/sonar/api/test/SimpleProjectFileSystem.java index 6bf7acad63a..32e7670176a 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/test/SimpleProjectFileSystem.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/test/SimpleProjectFileSystem.java @@ -19,11 +19,10 @@ */ package org.sonar.api.test; -import org.sonar.api.resources.InputFile; - import org.apache.commons.io.FileUtils; import org.apache.commons.lang.CharEncoding; import org.apache.commons.lang.NotImplementedException; +import org.sonar.api.resources.InputFile; import org.sonar.api.resources.Language; import org.sonar.api.resources.ProjectFileSystem; import org.sonar.api.resources.Resource; @@ -135,14 +134,15 @@ public class SimpleProjectFileSystem implements ProjectFileSystem { /** * @since 2.6 */ - public List mainFiles(Language... lang) { + public List mainFiles(String... lang) { return null; } /** * @since 2.6 */ - public List testFiles(Language... lang) { + public List testFiles(String... lang) { return null; } + }