...
 
Commits (60)
......@@ -4,6 +4,10 @@
- Upgrade DKPro Core to 1.10.0
- Upgrade dependencies
## nlp-sonarqube-plugin
- Add SonarQube plugin. Fixes #12.
## nlp-machen-plugin
- Fixes #31
......
......@@ -318,6 +318,17 @@ If you want to run the acceptance tests, use following command:
mvn test -P acceptance-tests
```
If you want to run Sonarqube plugin locally, use following commands (requires running Docker environment):
```bash
cd nlp-sonarqube-plugin
mvn clean package
docker run --rm -it \
-p 9000:9000 -p 9092:9092 \
-v $(pwd)/target/nlp-sonarqube-plugin-<NLPf version>.jar:/opt/sonarqube/extensions/plugins/nlp-sonarqube-plugin.jar \
sonarqube:6.7-alpine
```
# How to Cite?
<p>M. Schreiber, B. Kraft, and A. Zündorf. (2018).
......
......@@ -143,6 +143,12 @@
<version>20130624.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>io-odt</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
......
......@@ -23,8 +23,8 @@ package de.schrieveslaach.nlpf.maven.plugin;
*/
import com.fasterxml.jackson.databind.ObjectMapper;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.maven.plugin.models.TestResult;
import de.schrieveslaach.nlpf.testing.annotators.MyPosTagger;
import org.apache.maven.plugin.testing.MojoRule;
import org.junit.Rule;
import org.junit.Test;
......
......@@ -29,6 +29,7 @@ import de.schrieveslaach.nlpf.maven.plugin.service.AnalysisEngineDescriptionServ
import de.schrieveslaach.nlpf.maven.plugin.service.ClassLoaderService;
import de.schrieveslaach.nlpf.maven.plugin.service.CollectionReaderDescriptionService;
import de.schrieveslaach.nlpf.maven.plugin.service.DirectoryService;
import de.schrieveslaach.nlpf.plumbing.util.Uima;
import de.tudarmstadt.ukp.dkpro.core.api.lexmorph.type.pos.POS;
import de.tudarmstadt.ukp.dkpro.core.api.metadata.type.DocumentMetaData;
import de.tudarmstadt.ukp.dkpro.core.api.ner.type.NamedEntity;
......@@ -49,7 +50,6 @@ import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;
import org.apache.uima.util.XMLParser;
import org.springframework.core.annotation.AnnotationUtils;
import javax.inject.Inject;
import java.io.File;
......@@ -60,16 +60,13 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.stream.Collectors;
import static de.schrieveslaach.nlpf.maven.plugin.MojoUtil.swallowDkproLogging;
import static org.apache.uima.fit.util.JCasUtil.select;
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
......@@ -137,7 +134,7 @@ public abstract class AbstractTestMojo extends AbstractMojo {
@Override
public void execute() throws MojoExecutionException {
swallowDkproLogging();
Uima.swallowLogging();
ClassLoader previousContextClassLoader = initContextClassLoader();
executeWithUimaClassLoader();
......
......@@ -25,6 +25,7 @@ package de.schrieveslaach.nlpf.maven.plugin;
import com.google.common.reflect.ClassPath;
import de.schrieveslaach.nlpf.maven.plugin.service.ClassLoaderService;
import de.schrieveslaach.nlpf.maven.plugin.service.DirectoryService;
import de.schrieveslaach.nlpf.plumbing.util.Uima;
import lombok.SneakyThrows;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
......@@ -50,8 +51,6 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static de.schrieveslaach.nlpf.maven.plugin.MojoUtil.swallowDkproLogging;
@Mojo(name = "execute-engine-factories", requiresDependencyResolution = ResolutionScope.TEST)
public class ExecuteEngineFactoryMojo extends AbstractMojo {
......@@ -67,7 +66,7 @@ public class ExecuteEngineFactoryMojo extends AbstractMojo {
@Override
@SneakyThrows({IOException.class})
public void execute() throws MojoExecutionException, MojoFailureException {
swallowDkproLogging();
Uima.swallowLogging();
ClassLoader classLoader = getTestClasspathLoader();
......
......@@ -10,12 +10,12 @@ package de.schrieveslaach.nlpf.maven.plugin;
* 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.
*
*
* This program 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 General Lesser Public License for more details.
*
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
......@@ -38,7 +38,6 @@ import org.apache.uima.collection.CollectionReaderDescription;
import org.apache.uima.fit.descriptor.ResourceMetaData;
import org.apache.uima.fit.descriptor.TypeCapability;
import org.apache.uima.jcas.JCas;
import org.springframework.core.annotation.AnnotationUtils;
import java.io.File;
import java.io.FileOutputStream;
......@@ -46,8 +45,8 @@ import java.io.IOException;
import java.util.List;
import java.util.Objects;
import static de.schrieveslaach.nlpf.maven.plugin.EngineDescriptionUtil.hash;
import static de.schrieveslaach.nlpf.maven.plugin.JCasDataUtil.loadJCas;
import static de.schrieveslaach.nlpf.plumbing.util.AnalysisEngineDescriptionUtil.hash;
import static org.apache.uima.fit.pipeline.SimplePipeline.runPipeline;
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
......
......@@ -25,6 +25,7 @@ package de.schrieveslaach.nlpf.maven.plugin;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.schrieveslaach.nlpf.maven.plugin.models.TestResult;
import de.schrieveslaach.nlpf.maven.plugin.service.DirectoryService;
import de.schrieveslaach.nlpf.plumbing.util.Uima;
import org.apache.commons.io.FileUtils;
import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.archiver.MavenArchiver;
......@@ -48,8 +49,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import static de.schrieveslaach.nlpf.maven.plugin.MojoUtil.swallowDkproLogging;
@Mojo(name = "package", defaultPhase = LifecyclePhase.PACKAGE)
public class PackageMojo extends AbstractMojo {
......@@ -80,7 +79,7 @@ public class PackageMojo extends AbstractMojo {
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
swallowDkproLogging();
Uima.swallowLogging();
directoryService.setLanguage(language);
getLog().debug("Archive for language: " + language);
......
......@@ -42,14 +42,12 @@ import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.uima.UIMAException;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
import org.apache.uima.collection.CollectionReaderDescription;
import org.apache.uima.fit.descriptor.TypeCapability;
import org.apache.uima.jcas.JCas;
import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.util.CasCopier;
import org.springframework.core.annotation.AnnotationUtils;
import java.io.File;
import java.io.FileOutputStream;
......@@ -456,7 +454,7 @@ public class PipelinesTestMojo extends AbstractTestMojo {
}
@SuppressWarnings("squid:S2445")
private void runOrCopyPipelineData(JCas copiedJCas, AnalysisEngineDescriptionNode node) throws AnalysisEngineProcessException, ResourceInitializationException {
private void runOrCopyPipelineData(JCas copiedJCas, AnalysisEngineDescriptionNode node) throws UIMAException {
DocumentMetaData documentMetaData = DocumentMetaData.get(copiedJCas);
String documentUri = documentMetaData.getDocumentUri();
......
......@@ -26,6 +26,7 @@ import de.schrieveslaach.nlpf.maven.plugin.service.AnalysisEngineDescriptionServ
import de.schrieveslaach.nlpf.maven.plugin.service.ClassLoaderService;
import de.schrieveslaach.nlpf.maven.plugin.service.CollectionReaderDescriptionService;
import de.schrieveslaach.nlpf.maven.plugin.service.DirectoryService;
import de.schrieveslaach.nlpf.plumbing.util.Uima;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
......@@ -55,7 +56,6 @@ import java.util.stream.Collectors;
import static de.schrieveslaach.nlpf.maven.plugin.JCasDataUtil.copyJCas;
import static de.schrieveslaach.nlpf.maven.plugin.JCasDataUtil.loadJCas;
import static de.schrieveslaach.nlpf.maven.plugin.MojoUtil.swallowDkproLogging;
import static org.apache.uima.fit.factory.AnalysisEngineFactory.createEngineDescription;
@Mojo(name = "train", requiresDependencyResolution = ResolutionScope.COMPILE)
......@@ -81,7 +81,7 @@ public class TrainMojo extends AbstractMojo {
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
swallowDkproLogging();
Uima.swallowLogging();
analysisEngineService.setLanguage(language);
collectionReaderService.setLanguage(language);
......
......@@ -24,6 +24,7 @@ package de.schrieveslaach.nlpf.maven.plugin;
import de.schrieveslaach.nlpf.maven.plugin.service.ClassLoaderService;
import de.schrieveslaach.nlpf.maven.plugin.service.CollectionReaderDescriptionService;
import de.schrieveslaach.nlpf.plumbing.util.Uima;
import de.tudarmstadt.ukp.dkpro.core.api.metadata.type.DocumentMetaData;
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Sentence;
import de.tudarmstadt.ukp.dkpro.core.api.segmentation.type.Token;
......@@ -41,7 +42,6 @@ import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import static de.schrieveslaach.nlpf.maven.plugin.MojoUtil.swallowDkproLogging;
import static org.apache.uima.fit.pipeline.SimplePipeline.iteratePipeline;
import static org.apache.uima.fit.util.JCasUtil.select;
import static org.apache.uima.fit.util.JCasUtil.selectCovering;
......@@ -63,7 +63,7 @@ public class ValidationMojo extends AbstractMojo {
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
swallowDkproLogging();
Uima.swallowLogging();
collectionReaderService.setLanguage(language);
......
......@@ -46,7 +46,7 @@ import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collectors;
import static de.schrieveslaach.nlpf.maven.plugin.EngineDescriptionUtil.hash;
import static de.schrieveslaach.nlpf.plumbing.util.AnalysisEngineDescriptionUtil.hash;
import static java.util.Arrays.asList;
@JsonDeserialize(using = TestResult.TestResultDeserializer.class)
......@@ -86,7 +86,7 @@ public class TestResult implements Comparable<TestResult> {
@Override
public String toString() {
return measures.stream()
.map(measure -> measure.getAnalysisEngineName())
.map(Measure::getAnalysisEngineName)
.distinct()
.collect(Collectors.joining(", "));
}
......
......@@ -35,7 +35,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import static de.schrieveslaach.nlpf.maven.plugin.EngineDescriptionUtil.hash;
import static de.schrieveslaach.nlpf.plumbing.util.AnalysisEngineDescriptionUtil.hash;
@Singleton
public class DirectoryService {
......
......@@ -49,7 +49,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import static de.schrieveslaach.nlpf.maven.plugin.EngineDescriptionUtil.hash;
import static de.schrieveslaach.nlpf.plumbing.util.AnalysisEngineDescriptionUtil.hash;
import static de.schrieveslaach.nlpf.testing.JCasTestFactory.createOpenNlpExample;
import static de.schrieveslaach.nlpf.testing.JCasTestFactory.createSatyaNadellaExample;
import static de.schrieveslaach.nlpf.testing.JCasTestFactory.createTorwaldsExampleWithPosTags;
......
......@@ -22,11 +22,11 @@ package de.schrieveslaach.nlpf.maven.plugin;
* =========================LICENSE_END==================================
*/
import de.schrieveslaach.nlpf.maven.plugin.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MySegmenter;
import de.schrieveslaach.nlpf.maven.plugin.factories.CustomEngineFactory;
import de.schrieveslaach.nlpf.maven.plugin.service.ClassLoaderService;
import de.schrieveslaach.nlpf.maven.plugin.service.DirectoryService;
import de.schrieveslaach.nlpf.testing.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.testing.annotators.MySegmenter;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.MojoExecutionException;
......
......@@ -22,8 +22,8 @@ package de.schrieveslaach.nlpf.maven.plugin;
* =========================LICENSE_END==================================
*/
import de.schrieveslaach.nlpf.maven.plugin.annotators.MyNamedEntityRecognizer;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.testing.annotators.MyNamedEntityRecognizer;
import de.schrieveslaach.nlpf.testing.annotators.MyPosTagger;
import de.tudarmstadt.ukp.dkpro.core.api.parameter.ComponentParameters;
import de.tudarmstadt.ukp.dkpro.core.opennlp.OpenNlpNamedEntityRecognizer;
import org.apache.commons.io.FileUtils;
......@@ -39,7 +39,7 @@ import org.mockito.junit.MockitoJUnitRunner;
import java.io.File;
import java.nio.charset.Charset;
import static de.schrieveslaach.nlpf.maven.plugin.EngineDescriptionUtil.hash;
import static de.schrieveslaach.nlpf.plumbing.util.AnalysisEngineDescriptionUtil.hash;
import static java.util.Arrays.asList;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
import static org.apache.uima.fit.factory.AnalysisEngineFactory.createEngineDescription;
......
......@@ -22,15 +22,16 @@ package de.schrieveslaach.nlpf.maven.plugin;
* =========================LICENSE_END==================================
*/
import de.schrieveslaach.nlpf.maven.plugin.annotators.FailingSegmenter;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MyNamedEntityRecognizer;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MySegmenter;
import de.schrieveslaach.nlpf.maven.plugin.annotators.RelationExtractor;
import de.schrieveslaach.nlpf.testing.annotators.FailingSegmenter;
import de.schrieveslaach.nlpf.testing.annotators.MyNamedEntityRecognizer;
import de.schrieveslaach.nlpf.testing.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.testing.annotators.MySegmenter;
import de.tudarmstadt.ukp.dkpro.core.api.parameter.ComponentParameters;
import de.tudarmstadt.ukp.dkpro.core.opennlp.OpenNlpNamedEntityRecognizer;
import de.tudarmstadt.ukp.dkpro.core.opennlp.OpenNlpPosTagger;
import de.tudarmstadt.ukp.dkpro.core.opennlp.OpenNlpSegmenter;
import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
......@@ -46,8 +47,10 @@ import java.io.File;
import java.nio.charset.Charset;
import java.util.List;
import static de.schrieveslaach.nlpf.maven.plugin.EngineDescriptionUtil.hash;
import static de.schrieveslaach.nlpf.plumbing.util.AnalysisEngineDescriptionUtil.hash;
import static de.schrieveslaach.nlpf.testing.AnalysisEngineDescriptionMatchers.hasConfigurationParameter;
import static de.schrieveslaach.nlpf.testing.JsonDataFactory.createNlpToolTestResultOfMySegmenterAndMyPosTagger;
import static de.schrieveslaach.nlpf.testing.JsonDataFactory.createNlpToolTestResultOfOpenNlpSegmenterAndOpenNlpNamedEntityRecognizerWithPersonAndModelVariant;
import static de.schrieveslaach.nlpf.testing.ResourceCreationSpecifierMatchers.hasImplementationName;
import static java.util.Arrays.asList;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
......@@ -88,11 +91,12 @@ public class PipelinesTestMojoPipelinesTest extends AbstractTestMojoTest {
@InjectMocks
private PipelinesTestMojo mojo;
@SneakyThrows(ResourceInitializationException.class)
public static String jsonTestResult() {
return new JSONObject()
.put("descriptors", asList(
MySegmenter.DEFAULT_HASH_CODE + ".xml",
MyPosTagger.DEFAULT_HASH_CODE + ".xml"
hash(createEngineDescription(MySegmenter.class)) + ".xml",
hash(createEngineDescription(MyPosTagger.class)) + ".xml"
))
.put("measures", asList(
new JSONObject()
......@@ -206,7 +210,8 @@ public class PipelinesTestMojoPipelinesTest extends AbstractTestMojoTest {
* - whitespace tokens
* - nine NOUN pos tags
*/
assertThat(json, jsonEquals(jsonTestResult()).withTolerance(0.001));
assertThat(json, jsonEquals(createNlpToolTestResultOfMySegmenterAndMyPosTagger())
.withTolerance(0.001));
}
@Test
......@@ -226,7 +231,8 @@ public class PipelinesTestMojoPipelinesTest extends AbstractTestMojoTest {
assertThat(testResult, is(anExistingFile()));
String json = FileUtils.readFileToString(testResult, Charset.defaultCharset());
assertThat(json, jsonEquals(jsonTestResultWithNerVariant()).withTolerance(0.001));
assertThat(json, jsonEquals(createNlpToolTestResultOfOpenNlpSegmenterAndOpenNlpNamedEntityRecognizerWithPersonAndModelVariant())
.withTolerance(0.001));
}
@Test
......
......@@ -10,12 +10,12 @@ package de.schrieveslaach.nlpf.maven.plugin.factories;
* 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.
*
*
* This program 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 General Lesser Public License for more details.
*
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
......@@ -23,8 +23,8 @@ package de.schrieveslaach.nlpf.maven.plugin.factories;
*/
import de.schrieveslaach.nlpf.maven.plugin.PipelinesTestMojoPipelinesTest;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MySegmenter;
import de.schrieveslaach.nlpf.testing.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.testing.annotators.MySegmenter;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
import static org.apache.uima.fit.factory.AnalysisEngineFactory.createEngineDescription;
......
......@@ -23,9 +23,9 @@ package de.schrieveslaach.nlpf.maven.plugin.models;
*/
import com.fasterxml.jackson.databind.ObjectMapper;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MyNamedEntityRecognizer;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.maven.plugin.annotators.MySegmenter;
import de.schrieveslaach.nlpf.testing.annotators.MyNamedEntityRecognizer;
import de.schrieveslaach.nlpf.testing.annotators.MyPosTagger;
import de.schrieveslaach.nlpf.testing.annotators.MySegmenter;
import de.tudarmstadt.ukp.dkpro.core.eval.measure.FMeasure;
import de.tudarmstadt.ukp.dkpro.core.opennlp.OpenNlpNamedEntityRecognizer;
import de.tudarmstadt.ukp.dkpro.core.opennlp.OpenNlpPosTagger;
......@@ -67,7 +67,7 @@ public class TestResultTest {
MyPosTagger.DEFAULT_HASH_CODE + ".xml"
))
.put("measures", asList(new JSONObject()
.put("analysisEngineName", "de.schrieveslaach.nlpf.maven.plugin.annotators.MySegmenter")
.put("analysisEngineName", MySegmenter.class.getCanonicalName())
.put("outputType", "de.tudarmstadt.ukp.dkpro.core.api.lexmorph.type.pos.POS")
.put("variant", JSONObject.NULL)
.put("measure", new JSONObject()
......
......@@ -10,19 +10,19 @@ package de.schrieveslaach.nlpf.maven.plugin.service;
* 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.
*
*
* This program 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 General Lesser Public License for more details.
*
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* =========================LICENSE_END==================================
*/
import de.schrieveslaach.nlpf.maven.plugin.annotators.MySegmenter;
import de.schrieveslaach.nlpf.testing.annotators.MySegmenter;
import org.apache.maven.model.Build;
import org.apache.maven.project.MavenProject;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
......
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Dependency directories
node_modules/
package-lock.json
jspm_packages/
node/
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Optional npm cache directory
.npm
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# Autogenerated
yarn.lock
const REACT_APP = /^REACT_APP_/i;
function getClientEnvironment() {
return Object.keys(process.env).filter(key => REACT_APP.test(key)).reduce((env, key) => {
env['process.env.' + key] = JSON.stringify(process.env[key]);
return env;
}, {
// Useful for determining whether we’re running in production mode.
// Most importantly, it switches React into the correct mode.
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
});
}
module.exports = getClientEnvironment;
\ No newline at end of file
const webpack = require('webpack');
const config = require('./webpack.config');
config.devtool = 'eval';
config.output.publicPath = '/static/example/';
config.output.pathinfo = true;
Object.keys(config.entry).forEach(key => {
config.entry[key].unshift(require.resolve('react-dev-utils/webpackHotDevClient'));
});
config.plugins = [new webpack.HotModuleReplacementPlugin()];
module.exports = config;
\ No newline at end of file
const path = require('path');
const autoprefixer = require('autoprefixer');
const autoprefixerOptions = {
browsers: [
'last 3 Chrome versions',
'last 3 Firefox versions',
'Safari >= 8',
'Edge >= 12',
'IE 11'
]
};
const output = path.join(__dirname, '../../target/classes/static');
module.exports = {
entry: {
'nlp_page_react': ['./src/main/js/nlp_page_react.js']
},
output: {
path: output,
filename: '[name].js'
},
resolve: {
root: path.join(__dirname, 'src/main/js')
},
externals: {
lodash: '_',
react: 'React',
'react-dom': 'ReactDOM',
'react-redux': 'ReactRedux',
'react-router': 'ReactRouter',
'sonar-request': 'SonarRequest',
'sonar-measures': 'SonarMeasures',
'sonar-components': 'SonarComponents'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /(node_modules)/
},
{
test: /\.css/,
loader: 'style-loader!css-loader!postcss-loader'
},
{ test: /\.json$/, loader: 'json' }
]
},
postcss() {
return [autoprefixer(autoprefixerOptions)];
}
};
const webpack = require('webpack');
const config = require('./webpack.config');
const getClientEnvironment = require('../env');
// Get environment variables to inject into our app.
const env = getClientEnvironment();
// Assert this just to be safe.
// Development builds of React are slow and not intended for production.
if (env['process.env.NODE_ENV'] !== '"production"') {
throw new Error('Production builds must have NODE_ENV=production.');
}
const noUglify = process.argv.some(arg => arg.indexOf('--no-uglify') > -1);
// Don't attempt to continue if there are any errors.
config.bail = true;
config.plugins = [
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env),
// This helps ensure the builds are consistent if source hasn't changed:
new webpack.optimize.OccurrenceOrderPlugin(),
// Try to dedupe duplicated modules, if any:
new webpack.optimize.DedupePlugin()
];
if (!noUglify) {
config.plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true, // React doesn't support IE8
warnings: false
},
mangle: {
screw_ie8: true
},
output: {
comments: false,
screw_ie8: true
}
})
);
}
module.exports = config;
\ No newline at end of file
{
"name": "nlp-sonarqube-plugin",
"license" : "LGPL-3.0-only",
"version": "0.0.1",
"devDependencies": {
"autoprefixer": "6.2.2",
"babel-core": "6.14.0",
"babel-loader": "6.2.5",
"babel-preset-react-app": "0.2.1",
"cross-env": "2.0.0",
"cross-spawn": "4.0.0",
"css-loader": "0.23.1",
"detect-port": "1.0.0",
"dotenv": "2.0.0",
"enzyme": "2.6.0",
"enzyme-to-json": "1.4.5",
"expose-loader": "0.7.1",
"express": "4.13.4",
"express-http-proxy": "0.6.0",
"filesize": "3.3.0",
"find-cache-dir": "0.1.1",
"gzip-size": "3.0.0",
"imports-loader": "0.6.5",
"json-loader": "0.5.4",
"path-exists": "2.1.0",
"postcss-loader": "0.8.0",
"prettier": "0.22.0",
"react": "15.6.2",
"react-addons-shallow-compare": "15.6.2",
"react-addons-test-utils": "15.6.2",
"react-dev-utils": "0.2.1",
"react-dom": "15.6.2",
"react-router": "3.0.2",
"react-transform-hmr": "1.0.4",
"recursive-readdir": "2.1.0",
"rimraf": "2.5.4",
"script-loader": "0.6.1",
"strip-ansi": "3.0.1",
"style-loader": "0.13.0",
"webpack": "1.13.2",
"webpack-dev-server": "1.16.1"
},
"scripts": {
"build": "node scripts/build.js",
"start": "node scripts/start.js",
"test": "node scripts/test.js"
},
"babel": {
"presets": [
"react-app"
]
},
"dependencies": {
"chart.js": "^2.7.1",
"react-chartjs-2": "^2.7.0",
"color": "^3.0.0",
"d3-hierarchy": "^1.1.5",
"d3-selection": "^1.3.0"
}
}
<?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>
<parent>
<groupId>de.schrieveslaach.nlpf</groupId>
<artifactId>nlpf-parent</artifactId>
<version>1.1.0-SNAPSHOT</version>
</parent>
<artifactId>nlp-sonarqube-plugin</artifactId>
<packaging>sonar-plugin</packaging>
<properties>
<sonar.sources>src/main/java,src/main/js</sonar.sources>
</properties>
<dependencies>
<dependency>
<groupId>org.sonarsource.sonarqube</groupId>
<artifactId>sonar-plugin-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- DKPro Core Typesystem dependencies -->
<dependency>
<groupId>de.tudarmstadt.ukp.dkpro.core</groupId>
<artifactId>de.tudarmstadt.ukp.dkpro.core.api.ner-asl</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>io-odt</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging-api</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>plumbing</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging-api</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>testing</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging-api</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.tudarmstadt.ukp.dkpro.core</groupId>
<artifactId>de.tudarmstadt.ukp.dkpro.core.opennlp-asl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.javacrumbs.json-unit</groupId>
<artifactId>json-unit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
<artifactId>sonar-packaging-maven-plugin</artifactId>
<version>1.17</version>
<extensions>true</extensions>
<configuration>
<pluginClass>de.schrieveslaach.nlpf.sonarqube.plugin.NlpfPlugin</pluginClass>
<pluginUrl>${project.parent.url}</pluginUrl>
<pluginSourcesUrl>${project.parent.url}</pluginSourcesUrl>
<pluginDescription>no</pluginDescription>
</configuration>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>generate-resources</phase>
<id>install node and yarn</id>
<goals>
<goal>install-node-and-yarn</goal>
</goals>
<configuration>
<nodeVersion>v8.5.0</nodeVersion>
<yarnVersion>v1.1.0</yarnVersion>
</configuration>
</execution>
<execution>
<id>yarn install</id>
<goals>
<goal>yarn</goal>
</goals>
</execution>
<execution>
<phase>generate-resources</phase>
<id>yarn run script</id>
<goals>
<goal>yarn</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
process.env.NODE_ENV = 'production';
const chalk = require('chalk');
const webpack = require('webpack');
const config = require('../conf/webpack/webpack.config.prod.js');
function formatSize(bytes) {
if (bytes === 0) {
return '0';
}
const k = 1000; // or 1024 for binary
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}
function build() {
console.log(chalk.cyan.bold('Creating optimized production build...'));
console.log();
webpack(config, (err, stats) => {
if (err) {
console.log(chalk.red.bold('Failed to create a production build!'));
console.log(chalk.red(err.message || err));
process.exit(1);
}
if (stats.compilation.errors && stats.compilation.errors.length) {
console.log(chalk.red.bold('Failed to create a production build!'));
stats.compilation.errors.forEach(err => console.log(chalk.red(err.message || err)));
process.exit(1);
}
const jsonStats = stats.toJson();
console.log('Assets:');
const assets = jsonStats.assets.slice();
assets.sort((a, b) => b.size - a.size);
assets.forEach(asset => {
let sizeLabel = formatSize(asset.size);
const leftPadding = ' '.repeat(Math.max(0, 8 - sizeLabel.length));
sizeLabel = leftPadding + sizeLabel;
console.log('', chalk.yellow(sizeLabel), asset.name);
});
console.log();
const seconds = jsonStats.time / 1000;
console.log('Duration: ' + seconds.toFixed(2) + 's');
console.log();
console.log(chalk.green.bold('Compiled successfully!'));
});
}
build();
\ No newline at end of file
process.env.NODE_ENV = 'production';
const chalk = require('chalk');
const webpack = require('webpack');
const config = require('../conf/webpack/webpack.config.prod.js');
function formatSize(bytes) {
if (bytes === 0) {
return '0';
}
const k = 1000; // or 1024 for binary
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}
function build() {
console.log(chalk.cyan.bold('Creating optimized production build...'));
console.log();
webpack(config, (err, stats) => {
if (err) {
console.log(chalk.red.bold('Failed to create a production build!'));
console.log(chalk.red(err.message || err));
process.exit(1);
}
if (stats.compilation.errors && stats.compilation.errors.length) {
console.log(chalk.red.bold('Failed to create a production build!'));
stats.compilation.errors.forEach(err => console.log(chalk.red(err.message || err)));
process.exit(1);
}
const jsonStats = stats.toJson();
console.log('Assets:');
const assets = jsonStats.assets.slice();
assets.sort((a, b) => b.size - a.size);
assets.forEach(asset => {
let sizeLabel = formatSize(asset.size);
const leftPadding = ' '.repeat(Math.max(0, 8 - sizeLabel.length));
sizeLabel = leftPadding + sizeLabel;
console.log('', chalk.yellow(sizeLabel), asset.name);
});
console.log();
const seconds = jsonStats.time / 1000;
console.log('Duration: ' + seconds.toFixed(2) + 's');
console.log();
console.log(chalk.green.bold('Compiled successfully!'));
});
}
build();
\ No newline at end of file
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';
// Load environment variables from .env file. Surpress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set.
// https://github.com/motdotla/dotenv
require('dotenv').config({ silent: true });
const jest = require('jest');
const argv = process.argv.slice(2);
// Watch unless on CI
if (!process.env.CI) {
argv.push('--watch');
}
argv.push('--coverage');
jest.run(argv);
\ No newline at end of file
package de.schrieveslaach.nlpf.sonarqube.plugin;
/*-
* ========================LICENSE_START=================================
* nlp-sonarqube-plugin
* %%
* Copyright (C) 2017 - 2018 Schrieveslaach
* %%
* This program 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.
*
* This program 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 General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* =========================LICENSE_END==================================
*/
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.AnnotatedCorpusMetrics;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.AnnotationsComputer;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.AnnotationsSensor;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.IsolatedToolsTestSensor;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.NerHeatmapComputer;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.NerHeatmapSensor;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.NlpToolMetrics;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.NumbersMeasureComputer;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.NumbersSensor;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.PipelineDescriptionSensor;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.PipelineMeasuresSensor;
import de.schrieveslaach.nlpf.sonarqube.plugin.measures.PipelineMetrics;
import de.schrieveslaach.nlpf.sonarqube.plugin.web.NaturalLanguageProcessingPageDefinition;
import org.sonar.api.Plugin;
public class NlpfPlugin implements Plugin {
@Override
public void define(Context context) {
// Corpus related measures
context.addExtension(AnnotatedCorpusMetrics.class);
context.addExtensions(NumbersSensor.class, NumbersMeasureComputer.class);
context.addExtensions(AnnotationsSensor.class, AnnotationsComputer.class);
context.addExtensions(NerHeatmapSensor.class, NerHeatmapComputer.class);
context.addExtensions(NlpToolMetrics.class, IsolatedToolsTestSensor.class);
// Pipeline related measures
context.addExtensions(PipelineMetrics.class, PipelineMeasuresSensor.class, PipelineDescriptionSensor.class);
// Web
context.addExtension(NaturalLanguageProcessingPageDefinition.class);
}
}
package de.schrieveslaach.nlpf.sonarqube.plugin.data;
/*-
* ========================LICENSE_START=================================
* nlp-sonarqube-plugin
* %%
* Copyright (C) 2017 - 2018 Schrieveslaach
* %%
* This program 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.
*
* This program 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 General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* =========================LICENSE_END==================================
*/
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.NonNull;
public class NerHeatmapData {
@Getter
@JsonProperty
private final String variant;
@JsonProperty
private int quantity;
public NerHeatmapData(@NonNull String variant) {
this.variant = variant;
}
@JsonCreator
public NerHeatmapData(@JsonProperty("variant") String variant, @JsonProperty("quantity") int quantity) {
this(variant);
this.quantity = quantity;
}
public void increment() {
++quantity;
}
public NerHeatmapData join(NerHeatmapData data) {
return new NerHeatmapData(variant, quantity + data.quantity);
}
}
package de.schrieveslaach.nlpf.sonarqube.plugin.data;
/*-
* ========================LICENSE_START=================================
* nlp-sonarqube-plugin
* %%
* Copyright (C) 2017 - 2018 Schrieveslaach
* %%
* This program 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.
*
* This program 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 General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* =========================LICENSE_END==================================
*/
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
import java.util.ArrayList;
import java.util.List;
public class NlpPipelineDescription {
@JsonProperty
private List<NlpTool> tools;
public NlpPipelineDescription(List<AnalysisEngineDescription> aeds) {
tools = new ArrayList<>(aeds.size());
for (AnalysisEngineDescription aed : aeds) {
tools.add(new NlpTool(aed));
}
}
}
package de.schrieveslaach.nlpf.sonarqube.plugin.data;
/*-
* ========================LICENSE_START=================================
* nlp-sonarqube-plugin
* %%
* Copyright (C) 2017 - 2018 Schrieveslaach
* %%
* This program 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.
*
* This program 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 General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* =========================LICENSE_END==================================
*/
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import lombok.Cleanup;
import lombok.Getter;
import org.apache.uima.UIMAException;
import org.apache.uima.UIMAFramework;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;
import org.apache.uima.util.XMLParser;
import org.sonar.api.measures.Metric;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class NlpPipelineTestResult {
@Getter
@JsonProperty
private List<String> descriptors;
@JsonProperty
private List<NlpToolMeasure> measures;
public Multimap<Metric, NlpToolMeasure> mapNlpToolMeasuresToMetrics(List<Metric> metrics) {
Multimap<Metric, NlpToolMeasure> mapping = LinkedHashMultimap.create();
for (NlpToolMeasure measure : measures) {
for (Metric m : metrics) {
if (measure.matches(m)) {
mapping.put(m, measure);
}
}
}
return mapping;
}
public NlpPipelineDescription createPipelineDescription(File descriptorsDirectory) throws UIMAException {
List<AnalysisEngineDescription> aeds = new ArrayList<>();
for (String engineHash : descriptors) {
File engineDescriptionFile = new File(descriptorsDirectory, engineHash);
aeds.add(readEngineDescription(engineDescriptionFile));
}
return new NlpPipelineDescription(aeds);
}
private AnalysisEngineDescription readEngineDescription(File engineDescriptionFile