diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2014-01-09 11:51:49 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2014-01-09 14:14:07 +0100 |
commit | a8fea85fe5d509d2c895286edd31d6ca3cebbcfe (patch) | |
tree | c828bf04637e0cc5e4f95fa0b6aa01872d78fab3 /sonar-plugin-api | |
parent | ac40c604939422e059f4957f6006acab60de39cd (diff) | |
download | sonarqube-a8fea85fe5d509d2c895286edd31d6ca3cebbcfe.tar.gz sonarqube-a8fea85fe5d509d2c895286edd31d6ca3cebbcfe.zip |
SONAR-4783 API - drop the extension point SourceImporter
Diffstat (limited to 'sonar-plugin-api')
10 files changed, 45 insertions, 289 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java index 760c693e8bf..3d3000cbef8 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AbstractSourceImporter.java @@ -19,51 +19,36 @@ */ package org.sonar.api.batch; -import com.google.common.base.CharMatcher; -import com.google.common.io.Files; -import org.sonar.api.CoreProperties; import org.sonar.api.resources.Language; import org.sonar.api.resources.Project; import org.sonar.api.resources.ProjectFileSystem; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Resource; -import org.sonar.api.utils.SonarException; import java.io.File; import java.nio.charset.Charset; import java.util.List; /** - * A pre-implementation for a sensor that imports sources. - * It became too much ugly because of extensability. Methods can't be - * refactored because they are heavily overridden in plugins. - * * @since 1.10 + * @deprecated since 4.2 Resource indexing/source import is done by the core and this extension will not be used. */ +@Deprecated @Phase(name = Phase.Name.PRE) public abstract class AbstractSourceImporter implements Sensor { private Language language; - private boolean enabled = false; public AbstractSourceImporter(Language language) { this.language = language; } - /** - * Generally this method should not be overridden in subclasses, but if it is, then it should be executed anyway (see SONAR-3419). - */ public boolean shouldExecuteOnProject(Project project) { - enabled = isEnabled(project); - return language.equals(project.getLanguage()); + return false; } - /** - * {@inheritDoc} - */ public void analyse(Project project, SensorContext context) { - analyse(project.getFileSystem(), context); - onFinished(); + // Do not remove for backward compatibility } protected void onFinished() { @@ -71,28 +56,11 @@ public abstract class AbstractSourceImporter implements Sensor { } protected void analyse(ProjectFileSystem fileSystem, SensorContext context) { - parseDirs(context, fileSystem.getSourceFiles(language), fileSystem.getSourceDirs(), false, fileSystem.getSourceCharset()); - parseDirs(context, fileSystem.getTestFiles(language), fileSystem.getTestDirs(), true, fileSystem.getSourceCharset()); + // Do not remove for backward compatibility } protected void parseDirs(SensorContext context, List<File> files, List<File> sourceDirs, boolean unitTest, Charset sourcesEncoding) { - for (File file : files) { - Resource resource = createResource(file, sourceDirs, unitTest); - if (resource != null) { - try { - context.index(resource); - if (enabled) { - String source = Files.toString(file, Charset.forName(sourcesEncoding.name())); - // SONAR-3860 Remove BOM character from source - source = CharMatcher.anyOf("\uFEFF").removeFrom(source); - context.saveSource(resource, source); - } - } catch (Exception e) { - throw new SonarException("Unable to read and import the source file : '" + file.getAbsolutePath() + "' with the charset : '" - + sourcesEncoding.name() + "'.", e); - } - } - } + // Do not remove for backward compatibility } protected Resource createResource(File file, List<File> sourceDirs, boolean unitTest) { @@ -107,13 +75,9 @@ public abstract class AbstractSourceImporter implements Sensor { } protected boolean isEnabled(Project project) { - return project.getConfiguration().getBoolean(CoreProperties.CORE_IMPORT_SOURCES_PROPERTY, - CoreProperties.CORE_IMPORT_SOURCES_DEFAULT_VALUE); + return false; } - /** - * @return the language - */ public Language getLanguage() { return language; } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java index 3e459fce6ad..4616772b17f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java @@ -42,10 +42,11 @@ public interface SensorContext { * * @return false if the resource is excluded * @since 2.6 + * @deprecated since 4.2 Resource indexing is done by the platform */ + @Deprecated boolean index(Resource resource); - /** * Indexes a resource. This method does nothing if the resource is already indexed. * @@ -53,7 +54,9 @@ public interface SensorContext { * @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 + * @deprecated since 4.2 Resource indexing is done by the platform */ + @Deprecated boolean index(Resource resource, Resource parentReference); /** @@ -126,7 +129,6 @@ public interface SensorContext { @Deprecated String saveResource(Resource resource); - /** * Find all measures for this project. Never return null. */ @@ -191,7 +193,9 @@ public interface SensorContext { * @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 */ + @Deprecated void saveSource(Resource reference, String source); // ----------- LINKS -------------- diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/DefaultInputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/DefaultInputFile.java index 6aa3df03215..cade6314655 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/DefaultInputFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/DefaultInputFile.java @@ -19,6 +19,7 @@ */ 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.utils.PathUtils; @@ -26,6 +27,7 @@ import org.sonar.api.utils.PathUtils; import javax.annotation.CheckForNull; import java.io.File; +import java.nio.charset.Charset; import java.util.Map; /** @@ -43,8 +45,10 @@ public class DefaultInputFile implements InputFile { private final String absolutePath; private final String path; private final Map<String, String> attributes; + private final String encoding; - private DefaultInputFile(File file, String path, Map<String, String> attributes) { + 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; @@ -56,8 +60,8 @@ public class DefaultInputFile implements InputFile { * <p/> * Usage: <code>InputFile.create(file, "src/main/java/com/Foo.java", attributes)</code> */ - public static DefaultInputFile create(File file, String path, Map<String, String> attributes) { - return new DefaultInputFile(file, path, attributes); + public static DefaultInputFile create(File file, Charset encoding, String path, Map<String, String> attributes) { + return new DefaultInputFile(file, encoding, path, attributes); } @Override @@ -76,6 +80,11 @@ public class DefaultInputFile implements InputFile { } @Override + public Charset encoding() { + return Charsets.toCharset(encoding); + } + + @Override public String name() { return file().getName(); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFile.java index b8484fb7fc6..d2679f3e89a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFile.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFile.java @@ -20,8 +20,10 @@ package org.sonar.api.scan.filesystem.internal; 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 { @@ -57,7 +59,6 @@ public interface InputFile extends Serializable { String ATTRIBUTE_HASH = "HASH"; - /** * Path is relative from module base directory. Path is unique and identifies file * within given <code>{@link org.sonar.api.scan.filesystem.ModuleFileSystem}</code>. @@ -78,6 +79,8 @@ public interface InputFile extends Serializable { File file(); + Charset encoding(); + /** * Not-null filename, including extension */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFileBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFileBuilder.java index 042958fb8f4..0c57f806285 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFileBuilder.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/scan/filesystem/internal/InputFileBuilder.java @@ -22,7 +22,9 @@ package org.sonar.api.scan.filesystem.internal; 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; @@ -36,13 +38,15 @@ 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, String relativePath) { + public InputFileBuilder(File file, Charset encoding, String relativePath) { this.file = file; + this.encoding = encoding; this.relativePath = relativePath; } @@ -78,6 +82,6 @@ public class InputFileBuilder { } public DefaultInputFile build() { - return DefaultInputFile.create(file, relativePath, attributes); + return DefaultInputFile.create(file, encoding, relativePath, attributes); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/AbstractSourceImporterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/AbstractSourceImporterTest.java deleted file mode 100644 index c62b732cdcd..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/AbstractSourceImporterTest.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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; - -import com.google.common.io.Files; -import org.apache.commons.configuration.MapConfiguration; -import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.commons.lang.CharEncoding; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentMatcher; -import org.mockito.exceptions.verification.junit.ArgumentsAreDifferent; -import org.sonar.api.resources.Java; -import org.sonar.api.resources.JavaFile; -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 java.io.File; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.List; - -import static com.google.common.collect.Lists.newArrayList; -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class AbstractSourceImporterTest { - - private String aClaess; - private String explicacao; - private FakeSourceImporter importer; - - @Before - public void setup() throws UnsupportedEncodingException { - aClaess = new String(new byte[] {65, 67, 108, 97, -61, -88, 115, 115, 40, 41}, CharEncoding.UTF_8); - explicacao = new String(new byte[] {101, 120, 112, 108, 105, 99, 97, -61, -89, -61, -93, 111, 40, 41}, CharEncoding.UTF_8); - importer = new FakeSourceImporter(); - } - - @Test - public void shouldBeEnabledByDefault() { - Project pom = mock(Project.class); - when(pom.getConfiguration()).thenReturn(new PropertiesConfiguration()); - assertThat(importer.isEnabled(pom)).isTrue(); - } - - @Test - public void do_not_save_source_if_null_resource() { - AbstractSourceImporter nullImporter = new AbstractSourceImporter(Java.INSTANCE) { - @Override - protected Resource createResource(File file, List<File> sourceDirs, boolean unitTest) { - return null; - } - }; - - SensorContext context = mock(SensorContext.class); - ProjectFileSystem fileSystem = mock(ProjectFileSystem.class); - when(fileSystem.getSourceFiles(Java.INSTANCE)).thenReturn(newArrayList(new File("Foo.java"), new File("Bar.java"))); - nullImporter.analyse(fileSystem, context); - - verify(context, never()).saveSource(any(Resource.class), anyString()); - } - - @Test - public void should_use_mac_roman_charset_forR_reading_source_files() throws Exception { - Project project = mock(Project.class); - SensorContext context = mock(SensorContext.class); - - String encoding = "MacRoman"; - String testFile = "MacRomanEncoding.java"; - fileEncodingTest(project, context, encoding, testFile); - } - - @Test - public void should_use_CP1252_charset_for_reading_source_files() throws Exception { - Project project = mock(Project.class); - SensorContext context = mock(SensorContext.class); - - String encoding = "CP1252"; - String testFile = "CP1252Encoding.java"; - fileEncodingTest(project, context, encoding, testFile); - } - - @Test(expected = ArgumentsAreDifferent.class) - public void should_fail_with_wrong_charset_for_reading_source_files() throws Exception { - Project project = mock(Project.class); - SensorContext context = mock(SensorContext.class); - - String encoding = CharEncoding.UTF_8; - String testFile = "CP1252Encoding.java"; - fileEncodingTest(project, context, encoding, testFile); - } - - @Test - public void should_remove_byte_order_mark_character() throws Exception { - Project project = mock(Project.class); - SensorContext context = mock(SensorContext.class); - - ProjectFileSystem fileSystem = mock(ProjectFileSystem.class); - when(project.getFileSystem()).thenReturn(fileSystem); - when(fileSystem.getSourceCharset()).thenReturn(Charset.forName(CharEncoding.UTF_8)); - when(project.getConfiguration()).thenReturn(new MapConfiguration(new HashMap<String, String>())); - - File file = new File(Files.createTempDir(), "Test.java"); - Files.write("\uFEFFpublic class Test", file, Charset.defaultCharset()); - when(fileSystem.getSourceFiles(any(Language.class))).thenReturn(newArrayList(file)); - - importer.shouldExecuteOnProject(project); - importer.analyse(project, context); - - verify(context).saveSource(eq(FakeSourceImporter.TEST_RESOURCE), argThat(new ArgumentMatcher<String>() { - @Override - public boolean matches(Object arg0) { - String source = (String) arg0; - return !source.contains("\uFEFF"); - } - })); - } - - private void fileEncodingTest(Project project, SensorContext context, String encoding, String testFile) throws Exception { - ProjectFileSystem fileSystem = mock(ProjectFileSystem.class); - when(project.getFileSystem()).thenReturn(fileSystem); - when(fileSystem.getSourceCharset()).thenReturn(Charset.forName(encoding)); - when(project.getConfiguration()).thenReturn(new MapConfiguration(new HashMap<String, String>())); - when(fileSystem.getSourceFiles(any(Language.class))).thenReturn(newArrayList(getFile(testFile))); - - importer.shouldExecuteOnProject(project); - importer.analyse(project, context); - - verify(context).saveSource(eq(FakeSourceImporter.TEST_RESOURCE), argThat(new ArgumentMatcher<String>() { - @Override - public boolean matches(Object arg0) { - String source = (String) arg0; - return source.contains(aClaess) && source.contains(explicacao); - } - })); - } - - @Test - public void test_create_unit_test_resource() { - AbstractSourceImporter importer = new AbstractSourceImporter(Java.INSTANCE) { - }; - - File unitTestFile = new File("test/UnitTest.java"); - File unitTestDir = new File("test"); - List<File> unitTestDirs = newArrayList(); - unitTestDirs.add(unitTestDir); - - Resource unitTest = importer.createResource(unitTestFile, unitTestDirs, true); - assertThat(unitTest.getQualifier()).isEqualTo("UTS"); - - Resource srcTest = importer.createResource(unitTestFile, unitTestDirs, false); - assertThat(srcTest.getQualifier()).isEqualTo("FIL"); - } - - private static class FakeSourceImporter extends AbstractSourceImporter { - - private final static Resource TEST_RESOURCE = new JavaFile("Test"); - - private FakeSourceImporter() { - super(Java.INSTANCE); - } - - @Override - protected Resource createResource(File file, List<File> sourceDirs, boolean unitTest) { - return TEST_RESOURCE; - } - } - - private File getFile(String testFile){ - return new File("test-resources/org/sonar/api/batch/AbstractSourceImporterTest/encoding/" + testFile); - } - -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/DefaultInputFileTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/DefaultInputFileTest.java index 166d5660e3e..d62a24aab72 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/DefaultInputFileTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/DefaultInputFileTest.java @@ -19,6 +19,7 @@ */ package org.sonar.api.scan.filesystem.internal; +import com.google.common.base.Charsets; import org.apache.commons.io.FilenameUtils; import org.junit.Rule; import org.junit.Test; @@ -38,7 +39,7 @@ public class DefaultInputFileTest { @Test public void test_attributes() throws IOException { File file = temp.newFile(); - InputFile input = new InputFileBuilder(file, "src/main/java/Foo.java") + InputFile input = new InputFileBuilder(file, Charsets.UTF_8, "src/main/java/Foo.java") .attribute("foo", "bar") .type(InputFile.TYPE_TEST) .hash("ABC") @@ -63,7 +64,7 @@ public class DefaultInputFileTest { public void test_file() throws Exception { File sourceDir = temp.newFolder(); File file = temp.newFile("Foo.java"); - InputFile input = new InputFileBuilder(file, "src/main/java/Foo.java") + InputFile input = new InputFileBuilder(file, Charsets.UTF_8, "src/main/java/Foo.java") .sourceDir(sourceDir) .build(); @@ -77,9 +78,9 @@ public class DefaultInputFileTest { @Test public void test_equals_and_hashCode() throws Exception { File file1 = temp.newFile(); - InputFile input1 = new InputFileBuilder(file1, "src/main/java/Foo.java").build(); - InputFile input1a = new InputFileBuilder(file1, "src/main/java/Foo.java").build(); - InputFile input2 = new InputFileBuilder(temp.newFile(), "src/main/java/Bar.java").build(); + 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(); @@ -91,7 +92,7 @@ public class DefaultInputFileTest { @Test public void test_toString() throws Exception { File file1 = temp.newFile(); - InputFile input = new InputFileBuilder(file1, "src/main/java/Foo.java").type(InputFile.TYPE_TEST).build(); + 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]"); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFilesTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFilesTest.java index ba1c25eb1fb..c56dc617721 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFilesTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/internal/InputFilesTest.java @@ -19,13 +19,11 @@ */ package org.sonar.api.scan.filesystem.internal; +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 org.sonar.api.scan.filesystem.internal.InputFile; -import org.sonar.api.scan.filesystem.internal.InputFileBuilder; -import org.sonar.api.scan.filesystem.internal.InputFiles; import java.io.File; @@ -40,8 +38,8 @@ public class InputFilesTest { public void test_toFiles() throws Exception { File file1 = temp.newFile(); File file2 = temp.newFile(); - InputFile input1 = new InputFileBuilder(file1, "src/main/java/Foo.java").build(); - InputFile input2 = new InputFileBuilder(file2, "src/main/java/Bar.java").build(); + 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); } diff --git a/sonar-plugin-api/test-resources/org/sonar/api/batch/AbstractSourceImporterTest/encoding/CP1252Encoding.java b/sonar-plugin-api/test-resources/org/sonar/api/batch/AbstractSourceImporterTest/encoding/CP1252Encoding.java deleted file mode 100644 index 5f80ef59765..00000000000 --- a/sonar-plugin-api/test-resources/org/sonar/api/batch/AbstractSourceImporterTest/encoding/CP1252Encoding.java +++ /dev/null @@ -1,13 +0,0 @@ -public class Car { - - public AClaèss() { - } - - public int explicação() { - return 1; - } - - public String getS() { - return ""; - } -} diff --git a/sonar-plugin-api/test-resources/org/sonar/api/batch/AbstractSourceImporterTest/encoding/MacRomanEncoding.java b/sonar-plugin-api/test-resources/org/sonar/api/batch/AbstractSourceImporterTest/encoding/MacRomanEncoding.java deleted file mode 100644 index 30e52000eaf..00000000000 --- a/sonar-plugin-api/test-resources/org/sonar/api/batch/AbstractSourceImporterTest/encoding/MacRomanEncoding.java +++ /dev/null @@ -1,13 +0,0 @@ -public class Car { - - public AClass() { - } - - public int explica‹o() { - return 1; - } - - public String getS() { - return ""; - } -} |