@Override public void initialize() throws RuleException { try { tempDir = Files.createTempDirectory("jQA").toFile(); } catch (IOException e) { throw new RuleException("Cannot create temporary directory."); } }
private JavaRule getJavaRule(String className) throws RuleException { try { Class<?> javaRuleClass = Class.forName(className); if (!JavaRule.class.isAssignableFrom(JavaRule.class)) { throw new RuleException("Java '" + javaRuleClass.getName() + "' does not implement interface '" + JavaRule.class.getName() + "'."); } return JavaRule.class.cast(javaRuleClass.newInstance()); } catch (ReflectiveOperationException e) { throw new RuleException("Cannot create instance of '" + className + "'.", e); } } }
@Override public <T extends ExecutableRule<?>> Result.Status verify(T executable, List<String> columnNames, List<Map<String, Object>> rows, Verification verification) throws RuleException { VerificationStrategy strategy = verificationStrategies.get(verification.getClass()); if (strategy == null) { throw new RuleException("Result verification not supported: " + verification.getClass().getName()); } return strategy.verify(executable, verification, columnNames, rows); }
@Override public void destroy() throws RuleException { if (asciidoctor != null) { asciidoctor.shutdown(); } try { FileUtils.deleteDirectory(tempDir); } catch (IOException e) { throw new RuleException("Cannot delete temporary directory: " + tempDir); } }
/** * Retrieves severity based on string representation. * * @param value * string representation; {@code null} if no matching severity * found. * @return {@link Severity} */ public static Severity fromValue(String value) throws RuleException { if (value == null) { return null; } for (Severity severity : EnumSet.allOf(Severity.class)) { if (severity.value.equals(value.toLowerCase())) { return severity; } } throw new RuleException("Unknown severity '" + value + "'"); }
private Type toType(String value, RuleContext context) throws RuleException { try { return Type.valueOf(value.toUpperCase()); } catch (IllegalArgumentException e) { throw new RuleException("'" + value + "' is not a supported type for a parameter"); } }
@Override public boolean accepts(RuleSource ruleSource) throws RuleException { try { boolean acceptable = ruleSource.getURL().toExternalForm().toLowerCase().endsWith(YAML_EXTENSION_LONG) || ruleSource.getURL().toExternalForm().toLowerCase().endsWith(YAML_EXTENSION_SHORT); return acceptable; } catch (IOException e) { throw new RuleException("Unable to get the URL of the rule source.", e); } }
private void marshal(Writer writer, JqassistantRules rules) throws RuleException { XMLOutputFactory xof = XMLOutputFactory.newInstance(); XMLStreamWriter streamWriter; try { streamWriter = xof.createXMLStreamWriter(writer); } catch (XMLStreamException e) { throw new RuleException("Cannot create stream writer.", e); } XMLStreamWriter indentingStreamWriter = new IndentingXMLStreamWriter(new CDataXMLStreamWriter(streamWriter)); try { Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.marshal(rules, indentingStreamWriter); } catch (JAXBException e) { throw new RuleException("Cannot write rules to " + writer, e); } }
public Object parse(String value) throws RuleException { try { return value != null ? parseString(value) : null; } catch (NumberFormatException e) { throw new RuleException("Cannot parse value " + value + " for type " + name()); } };
private Map<String, Object> getRuleParameters(ExecutableRule executableRule) throws RuleException { Map<String, Object> ruleParameters = new HashMap<>(); Map<String, Parameter> parameters = executableRule.getParameters(); for (Map.Entry<String, Parameter> entry : parameters.entrySet()) { String parameterName = entry.getKey(); Parameter parameter = entry.getValue(); Object parameterValue; String parameterValueAsString = this.ruleParameters.get(parameterName); if (parameterValueAsString != null) { try { parameterValue = parameter.getType().parse(parameterValueAsString); } catch (RuleException e) { throw new RuleException("Cannot determine value for parameter " + parameterName + "' of rule '" + executableRule + "'."); } } else { parameterValue = parameter.getDefaultValue(); } if (parameterValue == null) { throw new RuleException("No value or default value defined for required parameter '" + parameterName + "' of rule '" + executableRule + "'."); } ruleParameters.put(parameterName, parameterValue); } return ruleParameters; }
throw new RuleException("Result contains no columns, at least one with a numeric value is expected."); Object value = row.get(column); if (value == null) { throw new RuleException("The result does not contain a column '" + column); } else if (!Number.class.isAssignableFrom(value.getClass())) { throw new RuleException("The value in column '" + column + "' must be a numeric value but was '" + value + "'");
private <T extends ExecutableRule> Result<T> execute(T executableRule, Severity severity) throws RuleException { Map<String, Object> ruleParameters = getRuleParameters(executableRule); Executable<?> executable = executableRule.getExecutable(); Collection<RuleInterpreterPlugin> languagePlugins = ruleInterpreterPlugins.get(executable.getLanguage()); if (languagePlugins == null) { throw new RuleException("Could not determine plugin to execute " + executableRule); } for (RuleInterpreterPlugin languagePlugin : languagePlugins) { if (languagePlugin.accepts(executableRule)) { Result<T> result = languagePlugin.execute(executableRule, ruleParameters, severity, analyzerContext); if (result != null) { return result; } } } throw new RuleException("No plugin for language '" + executable.getLanguage() + "' returned a result for " + executableRule); }
protected void doParse(RuleSource ruleSource, RuleSetBuilder ruleSetBuilder) throws RuleException { RuleContext context = new RuleContext(ruleSource, ruleSetBuilder); try (InputStream inputStream = ruleSource.getInputStream(); Reader reader = new YamlUnicodeReader(inputStream)) { LoadSettings settings = new LoadSettingsBuilder().build(); Load load = new Load(settings); Iterable<Object> objects = load.loadAllFromReader(reader); for (Object object : objects) { // if read document is empty, object might be null if (null == object) { continue; } if (Map.class.isAssignableFrom(object.getClass())) { processDocument((Map<String, Object>)object, context); } else { throw new RuleException("Cannot process rules from '" + ruleSource.getId() + "'."); } } } catch (IOException e) { throw new RuleException("Cannot read rules from '" + ruleSource.getId() + "'.", e); } catch (ClassCastException e) { throw new RuleException("Cannot process rules from '" + ruleSource.getId() + "' " + "because of an invalid YAML datastructure"); } }
protected <T extends ExecutableRule<?>> Result<T> execute(String cypher, T executableRule, Map<String, Object> parameters, Severity severity, AnalyzerContext context) throws RuleException { List<Map<String, Object>> rows = new ArrayList<>(); context.getLogger().debug("Executing query '" + cypher + "' with parameters [" + parameters + "]"); List<String> columnNames = null; try (Query.Result<Query.Result.CompositeRowObject> compositeRowObjects = context.getStore().executeQuery(cypher, parameters)) { for (Query.Result.CompositeRowObject rowObject : compositeRowObjects) { if (columnNames == null) { columnNames = new ArrayList<>(rowObject.getColumns()); } Map<String, Object> row = new LinkedHashMap<>(); for (String columnName : columnNames) { row.put(columnName, rowObject.get(columnName, Object.class)); } rows.add(row); } } catch (Exception e) { throw new RuleException("Cannot execute query for rule '" + executableRule + "'.", e); } Status status = getStatus(executableRule, columnNames, rows, context); return Result.<T>builder().rule(executableRule).status(status).severity(severity).columnNames(columnNames).rows(rows).build(); }
@Override public <T extends ExecutableRule<?>> Result<T> execute(T executableRule, Map<String, Object> ruleParameters, Severity severity, AnalyzerContext context) throws RuleException { SourceExecutable<String> executable = (SourceExecutable<String>) executableRule.getExecutable(); String source = executable.getSource(); Constructor c = new Constructor(YamlRuleSource.class); c.setPropertyUtils(new PropertyUtils() { @Override public Property getProperty(Class<? extends Object> type, String name) { return super.getProperty(type, LOWER_HYPHEN.to(LOWER_CAMEL, name)); } }); YamlRuleSource yamlRuleSource = new Yaml(c).loadAs(source, YamlRuleSource.class); String javaRuleClass = yamlRuleSource.getJavaRule(); if (javaRuleClass == null) { throw new RuleException("'java-rule-class' is required."); } JavaRule javaRule = getJavaRule(javaRuleClass); return javaRule.execute(executableRule, yamlRuleSource.getConfiguration(), ruleParameters, severity, context); }
private Executable<?> createExecutable(ExecutableRuleType executableRuleType) throws RuleException { SourceType source = executableRuleType.getSource(); if (source != null) { return new SourceExecutable<>(source.getLanguage().toLowerCase(), source.getValue(), String.class); } // for compatibility String cypher = executableRuleType.getCypher(); if (cypher != null) { return new CypherExecutable(cypher); } SourceType scriptType = executableRuleType.getScript(); if (scriptType != null) { return new ScriptExecutable(scriptType.getLanguage().toLowerCase(), scriptType.getValue()); } throw new RuleException("Cannot determine executable for " + executableRuleType.getId()); }
@Override protected void doParse(RuleSource source, RuleSetBuilder ruleSetBuilder) throws RuleException { String content; try (InputStream stream = source.getInputStream()) { content = IOUtils.toString(stream); } catch (IOException e) { throw new RuleException("Cannot parse AsciiDoc document from " + source.getId(), e); } OptionsBuilder optionsBuilder = options().mkDirs(true).safe(SafeMode.UNSAFE).baseDir(tempDir) .attributes(attributes().attribute(AsciidoctorFactory.ATTRIBUTE_IMAGES_OUT_DIR, tempDir.getAbsolutePath()).experimental(true)); getAsciidoctor().load(content, optionsBuilder.asMap()); extractRules(source, singletonList(treeprocessor.getDocument()), ruleSetBuilder); }
@Override public void visitConstraint(Constraint constraint, Severity effectiveSeverity) throws RuleException { analyzerContext.getLogger() .info("Validating constraint '" + constraint.getId() + "' with severity: '" + constraint.getSeverity().getInfo(effectiveSeverity) + "'."); try { analyzerContext.getStore().beginTransaction(); reportPlugin.beginConstraint(constraint); reportPlugin.setResult(execute(constraint, effectiveSeverity)); reportPlugin.endConstraint(); analyzerContext.getStore().commitTransaction(); } catch (XOException e) { analyzerContext.getStore().rollbackTransaction(); throw new RuleException("Cannot validate constraint " + constraint.getId(), e); } }
/** * Read the verification definition. */ private Verification getVerification(VerificationType verificationType) throws RuleException { if (verificationType != null) { RowCountVerificationType rowCountVerificationType = verificationType.getRowCount(); AggregationVerificationType aggregationVerificationType = verificationType.getAggregation(); if (aggregationVerificationType != null) { return AggregationVerification.builder().column(aggregationVerificationType.getColumn()).min(aggregationVerificationType.getMin()) .max(aggregationVerificationType.getMax()).build(); } else if (rowCountVerificationType != null) { return RowCountVerification.builder().min(rowCountVerificationType.getMin()).max(rowCountVerificationType.getMax()).build(); } else { throw new RuleException("Unsupported verification " + verificationType); } } return null; }
@Override public boolean visitConcept(Concept concept, Severity effectiveSeverity) throws RuleException { try { analyzerContext.getStore().beginTransaction(); ConceptDescriptor conceptDescriptor = analyzerContext.getStore().find(ConceptDescriptor.class, concept.getId()); Result.Status status; if (conceptDescriptor == null || configuration.isExecuteAppliedConcepts()) { analyzerContext.getLogger() .info("Applying concept '" + concept.getId() + "' with severity: '" + concept.getSeverity().getInfo(effectiveSeverity) + "'."); reportPlugin.beginConcept(concept); Result<Concept> result = execute(concept, effectiveSeverity); reportPlugin.setResult(result); status = result.getStatus(); if (conceptDescriptor == null) { conceptDescriptor = analyzerContext.getStore().create(ConceptDescriptor.class); conceptDescriptor.setId(concept.getId()); conceptDescriptor.setStatus(status); } reportPlugin.endConcept(); } else { status = conceptDescriptor.getStatus(); } analyzerContext.getStore().commitTransaction(); return Result.Status.SUCCESS.equals(status); } catch (XOException e) { analyzerContext.getStore().rollbackTransaction(); throw new RuleException("Cannot apply concept " + concept.getId(), e); } }