Skip to content

Commit

Permalink
Merge branch 'develop' into feature/avoidProgressBarOverlap
Browse files Browse the repository at this point in the history
  • Loading branch information
Kr0nox authored Jul 18, 2024
2 parents c2ac195 + b318832 commit ad7ec40
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 184 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ Subsequence Match Merging
--neighbor-length=<minimumNeighborLength>
Minimal length of neighboring matches to be merged (between 1 and minTokenMatch, default: 2).
Subcommands (supported languages):
Languages:
c
cpp
csharp
Expand Down
6 changes: 5 additions & 1 deletion cli/src/main/java/de/jplag/cli/JPlagRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ public static void runInternalServer(File zipFile, int port) throws IOException
ReportViewer reportViewer = new ReportViewer(zipFile, port);
int actualPort = reportViewer.start();
logger.info("ReportViewer started on port http://localhost:{}", actualPort);
Desktop.getDesktop().browse(URI.create("http://localhost:" + actualPort + "/"));
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
Desktop.getDesktop().browse(URI.create("http://localhost:" + actualPort + "/"));
} else {
logger.info("Could not open browser. You can open the Report Viewer here: http://localhost:{}/", actualPort);
}

System.out.println("Press Enter key to exit...");
System.in.read();
Expand Down
2 changes: 2 additions & 0 deletions cli/src/main/java/de/jplag/cli/picocli/CliInputHandler.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.jplag.cli.picocli;

import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_COMMAND_LIST_HEADING;
import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_DESCRIPTION_HEADING;
import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_OPTION_LIST;
import static picocli.CommandLine.Model.UsageMessageSpec.SECTION_KEY_SYNOPSIS;
Expand Down Expand Up @@ -70,6 +71,7 @@ private CommandLine buildCommandLine() {
}
return it;
}).collect(Collectors.joining(System.lineSeparator())) + System.lineSeparator());
cli.getHelpSectionMap().put(SECTION_KEY_COMMAND_LIST_HEADING, help -> "Languages:" + System.lineSeparator());

buildSubcommands().forEach(cli::addSubcommand);

Expand Down
4 changes: 3 additions & 1 deletion cli/src/main/java/de/jplag/cli/server/ReportViewer.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@ public int start() throws IOException {
throw new IllegalStateException("Server already started");
}

System.setProperty("java.net.preferIPv4Stack", "true");

int currentPort = this.port;
int remainingLookups = MAX_PORT_LOOKUPS;
BindException lastException = new BindException("Could not create server. Probably due to no free port found.");
while (server == null && remainingLookups-- > 0) {
try {
server = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress(), currentPort), 0);
server = HttpServer.create(new InetSocketAddress(InetAddress.getByAddress(new byte[] {127, 0, 0, 1}), currentPort), 0);
} catch (BindException e) {
logger.info("Port {} is not available. Trying to find a different one.", currentPort);
lastException = e;
Expand Down
16 changes: 16 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@
<version>${revision}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder-processor</artifactId>
<version>42</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -46,5 +52,15 @@
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<sourcepath>src/main/java;target/generated-sources/annotations</sourcepath>
</configuration>
</plugin>
</plugins>
</build>
</project>
107 changes: 13 additions & 94 deletions core/src/main/java/de/jplag/options/JPlagOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
Expand All @@ -25,6 +23,7 @@

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.soabase.recordbuilder.core.RecordBuilder;

/**
* This record defines the options to configure {@link JPlag}.
Expand All @@ -49,22 +48,32 @@
* @param clusteringOptions Clustering options
* @param debugParser If true, submissions that cannot be parsed will be stored in a separate directory.
*/
@RecordBuilder()
public record JPlagOptions(@JsonSerialize(using = LanguageSerializer.class) Language language,
@JsonProperty("min_token_match") Integer minimumTokenMatch, @JsonProperty("submission_directories") Set<File> submissionDirectories,
@JsonProperty("old_directories") Set<File> oldSubmissionDirectories, @JsonProperty("base_directory") File baseCodeSubmissionDirectory,
@JsonProperty("subdirectory_name") String subdirectoryName, @JsonProperty("file_suffixes") List<String> fileSuffixes,
@JsonProperty("exclusion_file_name") String exclusionFileName, @JsonProperty("similarity_metric") SimilarityMetric similarityMetric,
@JsonProperty("similarity_threshold") double similarityThreshold, @JsonProperty("max_comparisons") int maximumNumberOfComparisons,
@JsonProperty("cluster") ClusteringOptions clusteringOptions, boolean debugParser, @JsonProperty("merging") MergingOptions mergingOptions,
@JsonProperty("normalize") boolean normalize) {
@JsonProperty("normalize") boolean normalize) implements JPlagOptionsBuilder.With {

public static final double DEFAULT_SIMILARITY_THRESHOLD = 0;
public static final int DEFAULT_SHOWN_COMPARISONS = 500;
public static final int SHOW_ALL_COMPARISONS = 0;
public static final SimilarityMetric DEFAULT_SIMILARITY_METRIC = SimilarityMetric.AVG;
public static final Charset CHARSET = StandardCharsets.UTF_8;
public static final String ERROR_FOLDER = "errors";

/**
* @param lang The new language
* @return The modified options
* @deprecated Use withLanguage instead
*/
@Deprecated(forRemoval = true)
public JPlagOptions withLanguageOption(Language lang) {
return this.withLanguage(lang);
}

private static final Logger logger = LoggerFactory.getLogger(JPlagOptions.class);

public JPlagOptions(Language language, Set<File> submissionDirectories, Set<File> oldSubmissionDirectories) {
Expand Down Expand Up @@ -93,96 +102,6 @@ public JPlagOptions(Language language, Integer minimumTokenMatch, Set<File> subm
this.normalize = normalize;
}

public JPlagOptions withLanguageOption(Language language) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withDebugParser(boolean debugParser) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withFileSuffixes(List<String> fileSuffixes) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withSimilarityThreshold(double similarityThreshold) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withMaximumNumberOfComparisons(int maximumNumberOfComparisons) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withSimilarityMetric(SimilarityMetric similarityMetric) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withMinimumTokenMatch(Integer minimumTokenMatch) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withExclusionFileName(String exclusionFileName) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withSubmissionDirectories(Set<File> submissionDirectories) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withOldSubmissionDirectories(Set<File> oldSubmissionDirectories) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withBaseCodeSubmissionDirectory(File baseCodeSubmissionDirectory) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withSubdirectoryName(String subdirectoryName) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withClusteringOptions(ClusteringOptions clusteringOptions) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withMergingOptions(MergingOptions mergingOptions) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public JPlagOptions withNormalize(boolean normalize) {
return new JPlagOptions(language, minimumTokenMatch, submissionDirectories, oldSubmissionDirectories, baseCodeSubmissionDirectory,
subdirectoryName, fileSuffixes, exclusionFileName, similarityMetric, similarityThreshold, maximumNumberOfComparisons,
clusteringOptions, debugParser, mergingOptions, normalize);
}

public boolean hasBaseCode() {
return baseCodeSubmissionDirectory != null;
}
Expand Down
20 changes: 20 additions & 0 deletions core/src/test/java/de/jplag/options/JPlagOptionsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package de.jplag.options;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.Set;

import org.junit.jupiter.api.Test;

import de.jplag.java.JavaLanguage;

class JPlagOptionsTest {
@Test
void testWithLanguageOption() {
JavaLanguage lang = new JavaLanguage();
JPlagOptions options = new JPlagOptions(null, Set.of(), Set.of());
options = options.withLanguageOption(lang);

assertEquals(lang, options.language());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ private void parseFile(File file, TokenCollector collector) throws ParsingExcept
Lexer lexer = this.createLexer(CharStreams.fromReader(reader));
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
T parser = this.createParser(tokenStream);
parser.removeErrorListeners();
parser.addErrorListener(new AntlrLoggerErrorListener());
ParserRuleContext entryContext = this.getEntryContext(parser);
ParseTreeWalker treeWalker = new ParseTreeWalker();
InternalListener listener = new InternalListener(this.getListener(), collector);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.jplag.antlr;

import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Writes error messages from ANTLR to a logger
*/
public class AntlrLoggerErrorListener extends BaseErrorListener {
private static final Logger logger = LoggerFactory.getLogger(AntlrLoggerErrorListener.class);
private static final String ERROR_TEMPLATE = "ANTLR error - line {}:{} {}";

@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg,
RecognitionException e) {
logger.error(ERROR_TEMPLATE, line, charPositionInLine, msg);
}
}
Loading

0 comments on commit ad7ec40

Please sign in to comment.