All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cogroo.tools.checker.rules.CogrooHtml Maven / Gradle / Ivy

There is a newer version: 4.3.1
Show newest version
/**
 * Copyright (C) 2012 cogroo 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cogroo.tools.checker.rules;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import org.cogroo.analyzer.ComponentFactory;
import org.cogroo.checker.CheckDocument;
import org.cogroo.checker.GrammarChecker;
import org.cogroo.entities.Mistake;
import org.cogroo.entities.impl.MistakeImpl;
import org.cogroo.text.Sentence;
import org.cogroo.tools.checker.rules.applier.RulesProvider;
import org.cogroo.tools.checker.rules.applier.RulesXmlAccess;
import org.cogroo.tools.checker.rules.model.Example;
import org.cogroo.tools.checker.rules.model.Rule;
import org.cogroo.tools.checker.rules.model.Rules;
import org.cogroo.tools.checker.rules.util.RuleUtils;
import org.cogroo.tools.checker.rules.util.RuleUtils.RuleInfo;

/**
 * This class grammar checks all examples from the rules file and prints an html report
 * showing which rules are working.
 * 
 * @author Marcelo Suzumura
 */
public class CogrooHtml {
    
    /**
     * The file in which the report will be written.
     */
    private Writer out;
    
    /**
     * The rules.
     */
    private Rules rules;
    
    /**
     * The grammar checker.
     */
    private GrammarChecker cogroo;
    
    /**
     * Examples that were not matched by any rule at all.
     */
    private List no = new ArrayList();
    
    /**
     * Examples matched by the correct rule.
     */
    private List ok = new ArrayList();
    
    /**
     * Examples matched by the correct rule, but matched by other rules too.
     */
    private List partial = new ArrayList();
    
    /**
     * Examples matched only by other rules.
     */
    private List wrong = new ArrayList();
    
    /**
     * List of rules that does not have any suggestion.
     */
    private List noSuggestions = new ArrayList();
    
    /**
     * List of rules that does have bad suggestion.
     */
    private List badSuggestion = new ArrayList();
    
    /**
     * Maps rules ids and the sentences that caused an exception.
     */
    private Map> exceptions = new LinkedHashMap>();
    
    private Map rulesInfo = new HashMap();

    private String path;

    public CogrooHtml(File f, GrammarChecker cogroo) throws Exception {
      path = f.getAbsolutePath();
      
      out = new BufferedWriter(new OutputStreamWriter(
          new FileOutputStream(f), StandardCharsets.UTF_8
      ));

      this.cogroo = cogroo;
      
//      TagDictionary td = new TagDictionary(new FSALexicalDictionary(), false,
//          new FlorestaTagInterpreter());
//      
//      converter = new TextEntitiesConverter(td);
      
      this.rules = getRules();
    }
    
    
    
    private Rules getRules() {
      // Create XML rules applier
      RulesProvider xmlProvider = new RulesProvider(RulesXmlAccess.getInstance(),
          false);
      return xmlProvider.getRules();
    }
    
    public void evaluate() throws Exception {
        this.printHtmlHeader();
        
        int totalRules = 0;
        for (Rule rule : this.rules.getRule()) {
            // Only active rules will be considered.
            if (rule.isActive()) {
                // Consolidates rule information.
                this.prepareRuleInfo(rule);
                
                totalRules++;
                this.printRuleHeader(rule);
                
                // Each position contains the mistakes for each example.
                List> sentencesMistakes = new ArrayList>(rule.getExample().size());
                List sentences = new ArrayList(rule.getExample().size());
                
                // Checks each incorrect example of the rule.
                for (Example example : rule.getExample()) {
                    // Check sentence for mistakes.
                    try {
                        CheckDocument d = new CheckDocument();
                        d.setText(example.getIncorrect());
                        
                        this.cogroo.analyze(d);
                        
                        sentencesMistakes.add(d.getMistakes());
                        sentences.add(d.getSentences().get(0));
                    } catch (RuntimeException e) {
                      e.printStackTrace();
                        sentencesMistakes.add(null);
                        sentences.add(null);
                        this.logException(Long.valueOf(rule.getId()), example.getIncorrect());
                    }
                }
                this.evaluateMistakes(sentencesMistakes, sentences, rule);
                this.printRuleFooter(rule);
            }
            this.storeNoSuggestionRule(rule);
        }
        
        this.printReport("ok", this.ok, totalRules, "00ff00");
        this.printReport("partial", this.partial, totalRules, "ffff00");
        this.printReport("no", this.no, totalRules, "ff8000");
        this.printReport("wrong", this.wrong, totalRules, "ff0000");
        
        this.printNoSuggestion();
        this.printBadSuggestion();
        this.printExceptionReport();
        this.printHtmlFooter();
        
        this.out.close();
        
        System.out.println("Finished. Report file: " + path);
    }
    
    private void prepareRuleInfo(Rule rule) {
        Map mapInfo = RuleUtils.getRuleAsString(rule);
        StringBuilder sb = new StringBuilder();
        sb.append("");
        sb.append("");
        sb.append("");
        sb.append("");
        sb.append("");
        sb.append("");
        sb.append("");
        sb.append("");
        sb.append("");
        sb.append("
Method").append(mapInfo.get(RuleInfo.METHOD)).append("
Type").append(mapInfo.get(RuleInfo.TYPE)).append("
Group").append(mapInfo.get(RuleInfo.GROUP)).append("
Message").append(mapInfo.get(RuleInfo.MESSAGE)).append("
ShortMessage").append(mapInfo.get(RuleInfo.SHORTMESSAGE)).append("
Pattern").append(mapInfo.get(RuleInfo.PATTERN)).append("
Boundaries").append(mapInfo.get(RuleInfo.BOUNDARIES)).append("
Suggestions").append(mapInfo.get(RuleInfo.SUGGESTIONS)).append("
"); String escapedHtml = this.escapeHtmlChars(sb.toString()); String newLineToBr = this.newLineToBr(escapedHtml); this.rulesInfo.put(Long.valueOf(rule.getId()), newLineToBr); } private String prepareOverlib(Rule rule, String text) { StringBuilder sb = new StringBuilder(); sb.append(""); sb.append(text != null ? text + " " : ""); sb.append(Long.toString(rule.getId())); sb.append(""); return sb.toString(); } private void printHtmlHeader() throws Exception { this.out.append("\n"); this.out.append("\n"); // Imports the tooltip javascript. this.out.append(" \n"); this.out.append(" \n"); this.out.append("\n"); this.out.append("\n"); this.out.append("\n"); } private void printHtmlFooter() throws Exception { this.out.append("\n"); this.out.append("\n"); } private void printRuleHeader(Rule rule) throws Exception { this.out.append("\n"); this.out.append(" \n"); // this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); } private void printExamples(Example example, Sentence incorrectSentence) throws Exception { this.out.append(" \n"); this.out.append(" \n"); // this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); } private String prepareAnalysisOverlib(String incorrect, Sentence incorrectSentence) { StringBuilder sb = new StringBuilder(); sb.append(""); sb.append(incorrect); sb.append(""); return sb.toString(); } private String prepareAnalysisTable(Sentence incorrectSentence) { StringBuilder sb = new StringBuilder(); sb.append("
Rule ").append(Long.toString(rule.getId())).append(""); this.out.append(this.prepareOverlib(rule, "Rule")); this.out.append("
Incorrect").append(example.getIncorrect()).append("").append(this.prepareAnalysisOverlib(example.getIncorrect(), incorrectSentence)).append("
Correct").append(example.getCorrect()).append("
"); sb.append(""); for (List row : getAnalysisAsTable(incorrectSentence)) { sb.append(""); for (String column : row) { if(column == null) { column = "null"; } sb.append(""); } sb.append(""); } sb.append("
SyntTagChunkTagLexemePrimitiveMorphoTag
").append(column.equals("") ? " " : column).append("
"); return this.escapeHtmlChars(sb.toString()); } public List> getAnalysisAsTable(Sentence sentence) { if (sentence.getTokens().size() > 0 && sentence.getTokens().get(0).getPOSTag() == null) { throw new IllegalStateException("The sentence was not analyzed yet."); } List> analysis = new ArrayList>(5); for (int i = 0; i < sentence.getTokens().size(); i++) { List row = new ArrayList(); row.add(sentence.getTokens().get(i).getSyntacticTag()); row.add(sentence.getTokens().get(i).getChunkTag()); row.add(sentence.getTokens().get(i).getLexeme()); row.add(Arrays.toString(sentence.getTokens().get(i).getLemmas())); row.add(sentence.getTokens().get(i).getPOSTag() + "=" + sentence.getTokens().get(i).getFeatures()); analysis.add(row); } return analysis; } private void evaluateMistakes(List> sentencesMistakes, List sentences, Rule rule) throws Exception { int zeroMatches = 0; int wrongMatches = 0; int correctMatches = 0; // sentencesMistakes.size() equals to the number of examples. int sentence = 0; for (List mistakes : sentencesMistakes) { Example example = rule.getExample().get(sentence); // Prints the incorrect and correct examples. this.printExamples(example, sentences.get(sentence)); // Checks for null in case an exception occurred. if (mistakes != null) { if (mistakes.isEmpty()) { zeroMatches++; } else { // There were mistakes. for (Mistake mistake : mistakes) { if (((MistakeImpl) mistake).getRuleIdentifier().equals(appendPrefix(rule.getId()))) { correctMatches++; if(isValidSuggestion(example, mistake)) { this.out.append(" \n"); } else { this.out.append(" \n"); } } else { wrongMatches++; this.out.append(" "); } StringBuilder markedIncorrect = new StringBuilder(example.getIncorrect()); try { markedIncorrect.insert(mistake.getStart(), ">>>"); markedIncorrect.insert(mistake.getEnd() + 3, "<<<"); } catch (RuntimeException e) { this.logException(Long.valueOf(rule.getId()), example.getIncorrect()); } // Incorrect sentence with the mistake between >>> and <<<. this.out.append(" "); this.out.append(mistake.getRuleIdentifier()); this.out.append("\n"); this.out.append(" ").append(markedIncorrect); for (String suggestion : mistake.getSuggestions()) { this.out.append(" ["); this.out.append(escapeHtmlSpaces(suggestion)); this.out.append("]"); } this.out.append("\n"); this.out.append(" \n"); } } } sentence++; } if (zeroMatches > 0 && correctMatches == 0 && wrongMatches == 0) { this.no.add(rule); } else if (zeroMatches > 0 && correctMatches == 0 && wrongMatches > 0) { this.wrong.add(rule); } else if (zeroMatches > 0 && correctMatches > 0 && wrongMatches == 0) { this.partial.add(rule); } else if (zeroMatches > 0 && correctMatches > 0 && wrongMatches > 0) { this.partial.add(rule); } else if (zeroMatches == 0 && correctMatches == 0 && wrongMatches == 0) { // An exception occurred. } else if (zeroMatches == 0 && correctMatches == 0 && wrongMatches > 0) { this.wrong.add(rule); } else if (zeroMatches == 0 && correctMatches > 0 && wrongMatches == 0) { this.ok.add(rule); // point to try the suggestion checkSuggestion(rule, sentencesMistakes, sentences); } else if (zeroMatches == 0 && correctMatches > 0 && wrongMatches > 0) { this.partial.add(rule); } } private boolean isValidSuggestion(Example example, Mistake mistake) { if(mistake.getSuggestions() == null || mistake.getSuggestions().length == 0) return true; String incorrect = example.getIncorrect(); List applied = applySuggestions(incorrect, mistake); boolean isValid = false; for (String fixed : applied) { if(example.getCorrect().contains(fixed)) { isValid = true; } } return isValid; } private List applySuggestions(String incorrect, Mistake mistake) { List resp = new ArrayList(); for (String suggestion : mistake.getSuggestions()) { String a = incorrect.substring(0, mistake.getStart()) + suggestion + incorrect.substring(mistake.getEnd()); resp.add(a); } return resp; } private String appendPrefix(long id) { return "xml:" + Long.toString(id); } private void checkSuggestion(Rule rule, List> mistakesList, List sentences) { for (int i = 0; i < sentences.size(); i++) { Sentence s = sentences.get(i); List ml = mistakesList.get(i); for (Mistake mistake : ml) { String[] suggestions = mistake.getSuggestions(); // at least one suggestion should fit boolean suggestionIsOk = false; for (String suggestion : suggestions) { StringBuffer sb = new StringBuffer(s.getText()); sb.replace(mistake.getStart(), mistake.getEnd(), suggestion); for (Example example : rule.getExample()) { if(example.getIncorrect().contains(s.getText())) { if(example.getCorrect().contains(sb)) { suggestionIsOk = true; } } } } if(suggestionIsOk == false && suggestions.length > 0) { this.badSuggestion.add(rule); } } } } private void printRuleFooter(Rule rule) throws Exception { this.out.append(" \n"); this.out.append(" Status\n"); if (this.no.contains(rule)) { this.out.append(" \n"); // orange. } else if (this.ok.contains(rule)) { this.out.append(" \n"); // green. } else if (this.wrong.contains(rule)) { this.out.append(" \n"); // red. } else if (this.partial.contains(rule)) { this.out.append(" \n"); // yellow. } this.out.append(" \n"); this.out.append("\n"); this.out.append("
\n"); } private void printReport(String type, List rulesStatus, int totalRules, String color) throws Exception { this.out.append("\n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append("
").append(type).append(" = "); this.out.append(rulesStatus.size() + "/" + totalRules); this.out.append(" = "); this.out.append(Double.toString((double) rulesStatus.size() / totalRules * 100)); this.out.append("%
"); StringBuilder sb = new StringBuilder(); for (Rule rule : rulesStatus) { sb.append(this.prepareOverlib(rule, null) + ", "); } if (sb.toString().endsWith(", ")) { sb.delete(sb.length() - 2, sb.length()); // Removes the extra ", " at the end. } this.out.append(sb); this.out.append("
\n"); this.out.append("
\n"); } private void printNoSuggestion() throws Exception { StringBuilder sb = new StringBuilder(); for (Rule rule : this.noSuggestions) { sb.append(this.prepareOverlib(rule, null) + ", "); } if (sb.toString().endsWith(", ")) { sb.delete(sb.length() - 2, sb.length()); // Removes the extra ", " at the end. } this.out.append("\n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append("
no suggestions = "); this.out.append(Integer.toString(this.noSuggestions.size()) + "/" + this.rules.getRule().size()); this.out.append(" = "); this.out.append(Double.toString((double) this.noSuggestions.size() / this.rules.getRule().size() * 100)); this.out.append("%
").append(sb.toString()).append("
\n"); } private void printBadSuggestion() throws Exception { StringBuilder sb = new StringBuilder(); for (Rule rule : this.badSuggestion) { sb.append(this.prepareOverlib(rule, null) + ", "); } if (sb.toString().endsWith(", ")) { sb.delete(sb.length() - 2, sb.length()); // Removes the extra ", " at the end. } this.out.append("\n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append(" \n"); this.out.append("
bad suggestions = "); this.out.append(Integer.toString(this.badSuggestion.size()) + "/" + this.rules.getRule().size()); this.out.append(" = "); this.out.append(Double.toString((double) this.badSuggestion.size() / this.rules.getRule().size() * 100)); this.out.append("%
").append(sb.toString()).append("
\n"); } private void printExceptionReport() throws Exception { this.out.append("\n"); this.out.append(" \n"); boolean first = true; for (Entry> entry : this.exceptions.entrySet()) { Long id = entry.getKey(); List causes = entry.getValue(); for (String cause : entry.getValue()) { if (first) { this.out.append(" "); this.out.append(" "); this.out.append(" "); } else { this.out.append(" "); this.out.append(" "); } } } this.out.append(" \n"); this.out.append("
\n"); this.out.append(id.toString()); this.out.append(" "); this.out.append(cause); this.out.append("
"); this.out.append(cause); this.out.append("
"); } private void storeNoSuggestionRule(Rule rule) { if (rule.getSuggestion().isEmpty()) { this.noSuggestions.add(rule); } } private void logException(Long ruleId, String incorrectExample) { // Stores the sentence that generated the exception. if (this.exceptions.get(ruleId) == null) { List cause = new ArrayList(); cause.add(incorrectExample); this.exceptions.put(ruleId, cause); } else { this.exceptions.get(ruleId).add(incorrectExample); } } private String escapeHtmlSpaces(String string) { String escaped = string; escaped = escaped.replaceAll(" ", " "); return escaped; } private String escapeHtmlChars(String string) { String escaped = string; escaped = escaped.replaceAll("\\\"", """); escaped = escaped.replaceAll("<", "<"); escaped = escaped.replaceAll(">", ">"); return escaped; } private String newLineToBr(String string) { return string.replaceAll("\\n", "
"); } public static void main(String[] args) throws Exception { ComponentFactory factory = ComponentFactory.create(new Locale("pt", "BR")); CogrooHtml testCogrooHtml = new CogrooHtml(new File("reports/rules_status.html"), new GrammarChecker(factory.createPipe())); testCogrooHtml.evaluate(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy