Skip to content

Commit

Permalink
Merge pull request #721 from redpen-cc/embedded-javascript
Browse files Browse the repository at this point in the history
make JS validators visible to Web UI
  • Loading branch information
takahi-i authored Oct 25, 2016
2 parents 06b4504 + 46f62a2 commit 1de3376
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 19 deletions.
62 changes: 43 additions & 19 deletions redpen-core/src/main/java/cc/redpen/validator/ValidatorFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import cc.redpen.config.Configuration;
import cc.redpen.config.ValidatorConfiguration;
import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;

import java.io.BufferedReader;
import java.io.IOException;
Expand All @@ -31,6 +34,7 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
Expand All @@ -42,8 +46,8 @@
public class ValidatorFactory {
private static final String validatorPackage = Validator.class.getPackage().getName();
private static final List<String> VALIDATOR_PACKAGES = asList(validatorPackage, validatorPackage + ".sentence", validatorPackage + ".section");
private static final List<String> JS_VALIDATOR_DIRECTORIES = VALIDATOR_PACKAGES.stream().map(e -> "/" + e.replaceAll("\\.", "/") + "/").collect(toList());
static final Map<String, Validator> validators = new LinkedHashMap<>();
private static final Map<String, String> jsValidators = new LinkedHashMap<>();

static void registerValidator(Class<? extends Validator> clazz) {
validators.put(clazz.getSimpleName().replace("Validator", ""), createValidator(clazz));
Expand All @@ -61,13 +65,45 @@ static void registerValidator(Class<? extends Validator> clazz) {
// the validator doesn't implement default constructor
}
});
Reflections jsReflections = new Reflections(
new ConfigurationBuilder()
.setScanners(new ResourcesScanner())
.setUrls(ClasspathHelper.forPackage("cc.redpen.validator")));
jsReflections.getResources(Pattern.compile(".*js"))
.forEach(e -> {
InputStream inputStream = ValidatorFactory.class.getResourceAsStream("/" + e);
try (InputStreamReader isr = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader br = new BufferedReader(isr)) {
StringBuilder sb = new StringBuilder(1024);
String str;
while ((str = br.readLine()) != null) {
sb.append(str);
}
String validatorName = e.replaceFirst(".*/", "").replaceFirst("\\.js$", "");
jsValidators.put(validatorName, sb.toString());
} catch (IOException ignored) {
}

});
}

public static List<ValidatorConfiguration> getConfigurations(String lang) {
return validators.entrySet().stream().filter(e -> {
List<ValidatorConfiguration> configurations = validators.entrySet().stream().filter(e -> {
List<String> supportedLanguages = e.getValue().getSupportedLanguages();
return supportedLanguages.isEmpty() || supportedLanguages.contains(lang);
}).map(e -> new ValidatorConfiguration(e.getKey(), toStrings(e.getValue().getProperties()))).collect(toList());
Map<String, String> emptyMap = new LinkedHashMap<>();
for (String jsValidator : jsValidators.keySet()) {
try {
Validator jsValidatorInstance = getInstance(jsValidator);
List<String> supportedLanguages = jsValidatorInstance.getSupportedLanguages();
if (supportedLanguages.isEmpty() || supportedLanguages.contains(lang)) {
configurations.add(new ValidatorConfiguration(jsValidator, emptyMap));
}
} catch (RedPenException ignored) {
}
}
return configurations;
}

@SuppressWarnings("unchecked")
Expand All @@ -90,23 +126,11 @@ public static Validator getInstance(String validatorName) throws RedPenException
public static Validator getInstance(ValidatorConfiguration config, Configuration globalConfig) throws RedPenException {
String validatorName = config.getConfigurationName();
// lookup JavaScript validators
for (String p : JS_VALIDATOR_DIRECTORIES) {
InputStream inputStream = ValidatorFactory.class.getResourceAsStream(p + validatorName + ".js");
if (inputStream != null) {
try (InputStreamReader isr = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader br = new BufferedReader(isr)) {
StringBuilder sb = new StringBuilder(1024);
String str;
while ((str = br.readLine()) != null) {
sb.append(str);
}
JavaScriptLoader javaScriptValidator = new JavaScriptLoader(validatorName, sb.toString());
javaScriptValidator.preInit(config, globalConfig);
return javaScriptValidator;
} catch (IOException ignored) {
}

}
String script = jsValidators.get(validatorName);
if(script != null){
JavaScriptLoader javaScriptValidator = new JavaScriptLoader(validatorName, script);
javaScriptValidator.preInit(config, globalConfig);
return javaScriptValidator;
}

// fallback to Java validators
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.io.File;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.util.Arrays.asList;
Expand All @@ -47,6 +48,15 @@ public void validatorPluginsAreCreatedAndRegistered() throws RedPenException {
Configuration conf = Configuration.builder().addValidatorConfig(new ValidatorConfiguration("Custom")).build();
assertEquals(CustomValidator.class, ValidatorFactory.getInstance(conf.getValidatorConfigs().get(0), conf).getClass());
assertTrue(ValidatorFactory.getConfigurations("en").contains(new ValidatorConfiguration("Custom")));
List<ValidatorConfiguration> en = ValidatorFactory.getConfigurations("");
boolean foundEmbeddedJSValidator = false;
for (ValidatorConfiguration configuration : en) {
if (configuration.getConfigurationName().equals("MyEmbeddedJS")) {
foundEmbeddedJSValidator = true;
break;
}
}
assertTrue(foundEmbeddedJSValidator);
}

@Test(expected = RedPenException.class)
Expand Down

0 comments on commit 1de3376

Please sign in to comment.