diff --git a/jar-exclude-corpus-services.xml b/jar-exclude-corpus-services.xml new file mode 100644 index 0000000000000000000000000000000000000000..6e805119460cb8147405d528495871c3572fbdc0 --- /dev/null +++ b/jar-exclude-corpus-services.xml @@ -0,0 +1,27 @@ + <?xml version="1.0" encoding="UTF-8"?> + <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd"> + <id>bundle</id> + <formats> + <format>jar</format> + </formats> + <includeBaseDirectory>false</includeBaseDirectory> + <dependencySets> + <dependencySet> + <outputDirectory>/</outputDirectory> + <useProjectArtifact>false</useProjectArtifact> + <unpack>true</unpack> + <scope>runtime</scope> + <excludes> + <exclude>de.uni_hamburg.corpora:corpus-services</exclude> + </excludes> + </dependencySet> + </dependencySets> + <fileSets> + <fileSet> + <outputDirectory>/</outputDirectory> + <directory>${project.build.outputDirectory}</directory> + </fileSet> + </fileSets> + </assembly> \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..fe8f5387dac7ca86181dbdcede871564c8ae8840 --- /dev/null +++ b/pom.xml @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>de.uni_hamburg.corpora</groupId> + <artifactId>corpus-service-gui</artifactId> + <version>1.0-SNAPSHOT</version> + + <name>corpus-service-gui</name> + <!-- FIXME change it to the project's website --> + <url>http://www.example.com</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>11</maven.compiler.source> + <maven.compiler.target>11</maven.compiler.target> + <mainClass>de.uni_hamburg.corpora.gui.GUIApp</mainClass> + </properties> + + <dependencies> + <dependency> + <groupId>de.uni_hamburg.corpora</groupId> + <artifactId>corpus-services</artifactId> + <version>1.0</version> + <type>jar</type> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.11</version> + <scope>test</scope> + </dependency> + <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml --> + <dependency> + <groupId>com.fasterxml.jackson.dataformat</groupId> + <artifactId>jackson-dataformat-yaml</artifactId> + <version>2.13.3</version> + </dependency> + <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <version>2.13.3</version> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>31.0.1-jre</version> + </dependency> + </dependencies> + + <build> + <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> + <plugins> + <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --> + <plugin> + <artifactId>maven-clean-plugin</artifactId> + <version>3.1.0</version> + </plugin> + <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>3.0.2</version> + </plugin> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.8.0</version> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.22.1</version> + </plugin> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>3.0.2</version> + <configuration> + <!-- archive> + <manifestEntries> + <Class-Path>corpus-services.jar</Class-Path> + <Main-Class>${mainClass}</Main-Class> + </manifestEntries> + </archive --> + </configuration> + </plugin> + <plugin> + <artifactId>maven-install-plugin</artifactId> + <version>2.5.2</version> + </plugin> + <plugin> + <artifactId>maven-deploy-plugin</artifactId> + <version>2.8.2</version> + </plugin> + <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --> + <plugin> + <artifactId>maven-site-plugin</artifactId> + <version>3.7.1</version> + </plugin> + <plugin> + <artifactId>maven-project-info-reports-plugin</artifactId> + <version>3.0.0</version> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <version>1.2.1</version> + <executions> + <execution> + <goals> + <goal>java</goal> + </goals> + </execution> + </executions> + <configuration> + <mainClass>${mainClass}</mainClass> + </configuration> + </plugin> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <archive> + <manifest> + <addClasspath>true</addClasspath> + <mainClass>${mainClass}</mainClass> + </manifest> + <!-- manifestEntries> + <Class-Path>corpus-services.jar</Class-Path> + </manifestEntries --> + </archive> + <descriptors> + <descriptor>jar-exclude-corpus-services.xml</descriptor> + </descriptors> + <!-- descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs --> + <appendAssemblyId>true</appendAssemblyId> + </configuration> + </plugin> + </plugins> + </pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>11</source> + <target>11</target> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/run-linux.sh b/run-linux.sh new file mode 100644 index 0000000000000000000000000000000000000000..361784bc810ca1463f8834c8d593e23edd37fb2e --- /dev/null +++ b/run-linux.sh @@ -0,0 +1,2 @@ +#!/bin/bash +java -cp corpus-services.jar:target/corpus-service-gui-1.0-SNAPSHOT-jar-with-dependencies.jar de.uni_hamburg.corpora.gui.GUIApp diff --git a/src/main/java/de/uni_hamburg/corpora/gui/Config.java b/src/main/java/de/uni_hamburg/corpora/gui/Config.java new file mode 100644 index 0000000000000000000000000000000000000000..814c37bba09beb67c986d204d1574705e0818665 --- /dev/null +++ b/src/main/java/de/uni_hamburg/corpora/gui/Config.java @@ -0,0 +1,101 @@ +package de.uni_hamburg.corpora.gui; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * Class representing the YAML config created by the web interface + */ +public class Config { + @JsonProperty("corpus") + String name; + @JsonProperty("checker") + List<String> functions = new ArrayList<>(); + // Properties parameters = new Properties(); + @JsonProperty("parameters") + Map<String,String> parameters = new HashMap<>(); + + public Config() { + } + + /** + * Reads a config file + * @param fileName the config file + * @return the configuration + * @throws IOException if reading fails + */ + public static Config read(String fileName) throws IOException { + // Instantiating a new ObjectMapper as a YAMLFactory + ObjectMapper om = new YAMLMapper() + // Don't expect quotes around strings when not necessary + .configure(YAMLGenerator.Feature.MINIMIZE_QUOTES,true) + // Don't fail if more information than expected + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .findAndRegisterModules(); + return om.readValue(new File(fileName), Config.class); + } + + /** + * Writes a configuration back as a YAML string + * @return the resulting YAML + * @throws JsonProcessingException if conversion fails + */ + public String write() throws JsonProcessingException { + ObjectMapper om = new YAMLMapper() + .configure(YAMLGenerator.Feature.MINIMIZE_QUOTES,true); + return om.writeValueAsString(this); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + public List<String> getFunctions() { + return functions; + } + + public void setFunctions(List<String> functions) { + this.functions = functions; + } + + @JsonAnyGetter + public Map<String,String> getParameters() { + return parameters; + } + + @JsonAnySetter + public void setParameters(Map<String,String> parameters) { + this.parameters = parameters; + } + + public Properties getParametersAsProperties() { + Properties props = new Properties(); + props.putAll(this.parameters); + return props; + } + + @Override + public String toString() { + return "Config{" + + "name='" + name + '\'' + + ", functions=" + String.join(",", functions) + + ", params=" + parameters + + '}'; + } +} diff --git a/src/main/java/de/uni_hamburg/corpora/gui/CorpusServices.java b/src/main/java/de/uni_hamburg/corpora/gui/CorpusServices.java new file mode 100644 index 0000000000000000000000000000000000000000..12c657d0c7de2c2de3a5b108b639cb0f089977d4 --- /dev/null +++ b/src/main/java/de/uni_hamburg/corpora/gui/CorpusServices.java @@ -0,0 +1,65 @@ +package de.uni_hamburg.corpora.gui; + +import de.uni_hamburg.corpora.CorpusData; +import de.uni_hamburg.corpora.CorpusFunction; +import de.uni_hamburg.corpora.Report; +import de.uni_hamburg.corpora.ReportItem; +import org.reflections.Reflections; + +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author bba1792 Dr. Herbert Lange + * @version 20220404 + * Class encapsulating some corpus services functionality + */ +public class CorpusServices { + /** + * Gets the names of all corpus functions, ie all classes implementing CorpusFunction, defined in de.uni_hamburg.corpora. + * + * @return the list of corpus functions + */ + public static Set<String> getCorpusFunctions() { + // Get all classes implementing the interface via reflections + Reflections reflections = new Reflections("de.uni_hamburg.corpora"); + Set<Class<? extends CorpusFunction>> classes = reflections.getSubTypesOf(CorpusFunction.class); + // Convert classes to class names + return classes.stream() + .filter((c) -> Modifier.isPublic(c.getModifiers()) && !Modifier.isAbstract(c.getModifiers())) + .map(Class::getCanonicalName) + .collect(Collectors.toSet()); + } + + /** + * Gets the class names of all corpus types, ie all classes derived from CorpusData, defined in de.uni_hamburg.corpora. + * + * @return the list of corpus types + */ + public static Set<String> getCorpusTypes () { + Reflections reflections = new Reflections("de.uni_hamburg.corpora"); + HashSet<String> classNames = new HashSet<>(); + Set<Class<? extends CorpusData>> classes = reflections.getSubTypesOf(CorpusData.class); + for (Class<? extends CorpusData> c : classes) { + classNames.add(c.getCanonicalName()); + } + return classNames ; + } + + /** + * Generate the summary of a report returning the count of items for each severity level. + * + * @param report the report + * @return the hash map + */ + public static HashMap<ReportItem.Severity,Integer> generateSummary(Report report) { + HashMap<ReportItem.Severity,Integer> results = new HashMap<>(); + for (ReportItem item : report.getRawStatistics()) { + results.compute(item.getSeverity(),(k,v) -> (v==null) ? 1 : v + 1) ; + } + return results; + } +} diff --git a/src/main/java/de/uni_hamburg/corpora/gui/CorpusThread.java b/src/main/java/de/uni_hamburg/corpora/gui/CorpusThread.java new file mode 100644 index 0000000000000000000000000000000000000000..7237305c5921ac32e1ef153bfbad38a255b3d248 --- /dev/null +++ b/src/main/java/de/uni_hamburg/corpora/gui/CorpusThread.java @@ -0,0 +1,143 @@ +package de.uni_hamburg.corpora.gui; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import de.uni_hamburg.corpora.*; +import org.exmaralda.partitureditor.jexmaralda.JexmaraldaException; +import org.xml.sax.SAXException; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URISyntaxException; +import java.net.URL; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.function.Function; +import java.util.logging.Logger; + +class CorpusThread extends Thread { + + private final Logger logger = Logger.getLogger(this.getClass().getName()); + + de.uni_hamburg.corpora.Report report = new de.uni_hamburg.corpora.Report(); + String corpusName; + String inFile ; + List<String> functionNames; + String outFile; + Properties props; // The properties for the function calls + Function<String,Void> callbackFunction; + + CorpusThread(String name, String infile, String outfile, List<String> functions, Properties properties, + Function<String, Void> callback) { + this.corpusName=name; + if (infile.equals("tmp")) + this.inFile = System.getProperty("java.io.tmpdir") + "/corpus-files"; + else + this.inFile = infile; + this.functionNames = functions ; + this.props = properties; + if (outfile.equals("tmp")) { + File tmpDir = new File(System.getProperty("java.io.tmpdir") + "/" + corpusName); + // Create parent directory if it is missing + if (!tmpDir.exists()) + tmpDir.mkdirs(); + this.outFile = tmpDir + "/checker-report.html"; + } + else + this.outFile = outfile; + callbackFunction = callback; + logger.info("Input: " + this.inFile + " output: " + this.outFile + " functions: " + functions + " params: " + + this.props); + } + + public void run() { + Set<String> allFunctions = CorpusServices.getCorpusFunctions() ; + CorpusIO cio = new CorpusIO(); + report.addNote("CorpusWebServices","Starting run at " + + DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").format(LocalDateTime.now())); + try { + // Create corpus from given input file/folder + Corpus corpus; + if (corpusName != null && !corpusName.isEmpty()) { + URL baseUrl = new File(inFile).toURI().toURL(); + corpus = new Corpus(corpusName,baseUrl,cio.read(baseUrl,report)) ; + } + else + corpus = new Corpus(cio.read(new File(inFile).toURI().toURL(),report)) ; + logger.info("Loaded " + corpus.getCorpusData().size() + " corpus files"); + logger.info("Got report: " + report.getFullReports()); + // For all functions to be applied, get their canonical name and create an object for them + Set<CorpusFunction> functions = new HashSet<>() ; + for (String function : functionNames) { + // Indicator if we encountered the function + boolean found = false ; + for (String canonical : allFunctions) { + if (canonical.toLowerCase(Locale.ROOT).endsWith("." + function.toLowerCase(Locale.ROOT))) { + // Create an object from canonical name. calls the constructor with thr constructor setting hasfixingoption to false + try { + functions.add((CorpusFunction) Class.forName(canonical).getDeclaredConstructor(Properties.class).newInstance(props)); + found = true ; + } + catch (IllegalArgumentException | NoSuchMethodException | InstantiationException | InvocationTargetException | IllegalAccessException e) { + logger.severe(String.format("Error creating %s", canonical)); + report.addWarning("CorpusWebServices", "Test " + function + " cannot be created"); +// e.printStackTrace(); + } + } + } + if (!found) { + // Warn if we could not find the function + report.addWarning("CorpusWebServices", "Test " + function + " is not available"); + logger.severe(String.format("Function %s is not available in corpus services", function)); + + } + } + for (CorpusFunction f : functions) { + logger.severe(String.format("Running function %s", f.getFunction())); + report.addNote("CorpusWebServices", "Run test " + f.getFunction()); + de.uni_hamburg.corpora.Report result = f.execute(corpus); + report.merge(result); + report.addNote("CorpusWebServices", "Finish test " + f.getFunction()); + logger.severe(String.format("Done with function %s", f.getFunction())); + } + } catch (URISyntaxException | ClassNotFoundException | IOException | SAXException | JexmaraldaException e) { + e.printStackTrace(); + } + + logger.info("Done with all functions"); + report.addNote("CorpusWebServices","Finished all tests at " + + DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").format(LocalDateTime.now())); + logger.info("Creating report"); + // Get summary + HashMap<ReportItem.Severity,Integer> summary = CorpusServices.generateSummary(report); + // try to convert to JSON + String jsonSummary = "{}"; + try { + jsonSummary = new ObjectMapper().writeValueAsString(summary); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + // Generate HTML report + Collection<ReportItem> rawStatistics = report.getRawStatistics(); + String reportOutput = ReportItem.generateDataTableHTML(new ArrayList<>(rawStatistics), + report.getSummaryLines()); + // Alternative: Generate XML + //XStream xstream = new XStream(); + //String reportOutput = xstream.toXML(rawStatistics); + + logger.info("Writing report to " + outFile); + try { + BufferedWriter out = new BufferedWriter(new FileWriter(outFile)); + out.write(reportOutput); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + logger.info("Done with report"); + callbackFunction.apply(outFile); + } +} \ No newline at end of file diff --git a/src/main/java/de/uni_hamburg/corpora/gui/GUI.java b/src/main/java/de/uni_hamburg/corpora/gui/GUI.java new file mode 100644 index 0000000000000000000000000000000000000000..cafc5dea16f3b0b4aba8d18bebd16bd5c893a2f1 --- /dev/null +++ b/src/main/java/de/uni_hamburg/corpora/gui/GUI.java @@ -0,0 +1,171 @@ +package de.uni_hamburg.corpora.gui; + +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.awt.*; +import java.io.*; +import java.net.URL; +import java.util.function.Function; + +/** + * The definition of the GUI + * @author bba1792, Dr. Herbert Lange + * @version 20220802 + */ +public class GUI { + + // Information on how to download the corpus-services + private final String BRANCH = "develop-quest"; + private final String FILE_URL = "https://gitlab.rrz.uni-hamburg.de/corpus-services/corpus-services/-/jobs/artifacts/" + + BRANCH + "/raw/target/corpus-services-1.0.jar?job=compile_withmaven"; + // The main window + JFrame window; + // The path to the report created by the checkers + String reportFile; + + /** + * Constructor setting up the GUI + */ + public GUI() { + window = new JFrame("Corpus-Services GUI"); + window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + JPanel mainPanel = new JPanel(new GridLayout(5,1)); + JPanel corpusFiles = new JPanel(new GridLayout(1,3)); + mainPanel.add(new JLabel("Corpus directory")); + final JTextField corpusPath = new JTextField(); + corpusFiles.add(corpusPath); + final JButton corpusButton = new JButton("Select"); + corpusButton.addActionListener(actionEvent -> { + JFileChooser chooser = new JFileChooser(); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + int result = chooser.showOpenDialog(corpusButton); + if (result == JFileChooser.APPROVE_OPTION) + corpusPath.setText(chooser.getSelectedFile().toString()); + }); + corpusFiles.add(corpusButton); + mainPanel.add(corpusFiles); + mainPanel.add(new JLabel("Configuration file")); + JPanel configFile = new JPanel(new GridLayout(1,3)); + final JTextField configPath = new JTextField(); + configFile.add(configPath); + final JButton configButton = new JButton("Select"); + configButton.addActionListener(actionEvent -> { + JFileChooser chooser = new JFileChooser(); + chooser.setFileFilter(new FileNameExtensionFilter( + "YAML configurations", "yaml", "yml")); + int result = chooser.showOpenDialog(configButton); + if (result == JFileChooser.APPROVE_OPTION) + configPath.setText(chooser.getSelectedFile().toString()); + }); + configFile.add(configButton); + mainPanel.add(configFile); + JPanel buttonPanel = new JPanel(new GridLayout(1,4)); + JButton checkButton = new JButton("Check corpus"); + buttonPanel.add(checkButton); + JButton reportButton = new JButton("Show report"); + reportButton.setEnabled(false); + buttonPanel.add(reportButton); + JButton updateButton = new JButton("Update corpus services"); + buttonPanel.add(updateButton); + JButton exitButton = new JButton("Exit"); + buttonPanel.add(exitButton); + // Handle check + // Create callback for after the check + Function<String, Void> callback = + (outFile) -> { + reportFile = outFile; + reportButton.setEnabled(true); + JOptionPane.showMessageDialog(window, + "Checks executed successfully. You can now check the report.", + "Success", + JOptionPane.INFORMATION_MESSAGE); + checkButton.setEnabled(true); + updateButton.setEnabled(true); + return null ; + }; + checkButton.addActionListener(actionEvent -> { + checkButton.setEnabled(false); + updateButton.setEnabled(false); + // Do the checking + try { + Config config = Config.read(configPath.getText()); + JOptionPane.showMessageDialog(window, + "Starting checks now. Depending on the corpus and the checks selected this can take" + + "a while", + "Info", + JOptionPane.INFORMATION_MESSAGE); + CorpusThread worker = new CorpusThread( + config.getName() + , corpusPath.getText() + , "tmp" // write report to tmp + , config.getFunctions() + , config.getParametersAsProperties() + , callback); + worker.start(); + } catch (IOException e) { + JOptionPane.showMessageDialog(window, + "Problem loading configuration file", + "Error", + JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + checkButton.setEnabled(true); + updateButton.setEnabled(true); + } + }); + // Handle update + updateButton.addActionListener(actionEvent -> { + checkButton.setEnabled(false); + updateButton.setEnabled(false); + exitButton.setEnabled(false); + JOptionPane.showMessageDialog(window, + "Download started. Depending on the internet connection this can take a few minutes", + "Info", + JOptionPane.INFORMATION_MESSAGE); + try { + BufferedInputStream in = new BufferedInputStream(new URL(FILE_URL).openStream()); + BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("corpus-services.jar")); + in.transferTo(out); + in.close(); + out.close(); + JOptionPane.showMessageDialog(window, + "Download successful. You now have to restart the application.", + "Success", + JOptionPane.INFORMATION_MESSAGE); + } catch (IOException e) { + //custom title, error icon + JOptionPane.showMessageDialog(window, + "Error downloading file.", + "Error", + JOptionPane.ERROR_MESSAGE); + } + checkButton.setEnabled(true); + updateButton.setEnabled(true); + exitButton.setEnabled(true); + }); + reportButton.addActionListener(actionEvent -> { + Desktop dt = Desktop.getDesktop(); + try { + dt.open(new File(reportFile)); + } catch (Exception e) { + JOptionPane.showMessageDialog(window, + "Error opening report file " + reportFile + ".", + "Error", + JOptionPane.ERROR_MESSAGE); + } + }); + // Handle exit + exitButton.addActionListener(actionEvent -> { + // Close window + window.dispose(); + }); + mainPanel.add(buttonPanel); + window.getContentPane().add(mainPanel); + } + + /** + * Shows the window + */ + public void show() { + window.setVisible(true); + } +} diff --git a/src/main/java/de/uni_hamburg/corpora/gui/GUIApp.java b/src/main/java/de/uni_hamburg/corpora/gui/GUIApp.java new file mode 100644 index 0000000000000000000000000000000000000000..b7ca134f2a3aa44b479bd93b796fcb6ec09c72fd --- /dev/null +++ b/src/main/java/de/uni_hamburg/corpora/gui/GUIApp.java @@ -0,0 +1,18 @@ +package de.uni_hamburg.corpora.gui; + +/** + * Simple GUI for the corpus services + * @author bba1792, Dr. Herbert Lange + * @version 20220802 + */ +public class GUIApp +{ + public static void main( String[] args ) + { + // Create window + GUI gui = new GUI(); + // Show window + gui.show(); + // This app will continue running until the window is closed + } +} diff --git a/src/test/java/de/uni_hamburg/corpora/AppTest.java b/src/test/java/de/uni_hamburg/corpora/AppTest.java new file mode 100644 index 0000000000000000000000000000000000000000..883599a4af48727af47bc974b4f30c574ac2bbd4 --- /dev/null +++ b/src/test/java/de/uni_hamburg/corpora/AppTest.java @@ -0,0 +1,20 @@ +package de.uni_hamburg.corpora; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class AppTest +{ + /** + * Rigorous Test :-) + */ + @Test + public void shouldAnswerWithTrue() + { + assertTrue( true ); + } +}