in languagetool-core/src/main/java/org/languagetool/rules/patterns/PatternRuleHandler.java [124:486]
public void startElement(String namespaceURI, String lName,
String qName, Attributes attrs) throws SAXException {
switch (qName) {
case "category":
String catName = attrs.getValue(NAME);
premiumCategoryAttribute = attrs.getValue(PREMIUM); //check if all rules should be premium by default in this category
String catId = attrs.getValue(ID);
Category.Location location = YES.equals(attrs.getValue(EXTERNAL)) ?
Category.Location.EXTERNAL : Category.Location.INTERNAL;
boolean onByDefault = !OFF.equals(attrs.getValue(DEFAULT));
String tabName = attrs.getValue(TABNAME);
category = new Category(new CategoryId(catId), catName, location, onByDefault, tabName);
if (attrs.getValue(TYPE) != null) {
categoryIssueType = attrs.getValue(TYPE);
}
if (attrs.getValue("tags") != null) {
categoryTags.addAll(Arrays.asList(attrs.getValue("tags").split(" ")));
}
if (attrs.getValue("tone_tags") != null) {
categoryToneTags.addAll(Arrays.asList(attrs.getValue("tone_tags").split(" ")));
}
isGoalSpecificCategoryAttribute = attrs.getValue(GOAL_SPECIFIC);
String prioCategoryAttributeValue = attrs.getValue(PRIO);
if (prioCategoryAttributeValue != null) {
prioCategoryAttribute = Integer.parseInt(prioCategoryAttributeValue);
}
break;
case "rules":
String languageStr = attrs.getValue("lang");
premiumFileAttribute = attrs.getValue(PREMIUM); //check if all rules should be premium by default in this file
idPrefix = attrs.getValue("idprefix");
if (language == null) {
language = Languages.getLanguageForShortCode(languageStr);
}
messages = ResourceBundleTools.getMessageBundle(language);
break;
case "regexp":
inRegex = true;
regexMode = "exact".equals(attrs.getValue("type")) ? RegexpMode.EXACT : RegexpMode.SMART;
regexCaseSensitive = attrs.getValue(CASE_SENSITIVE) != null && YES.equals(attrs.getValue(CASE_SENSITIVE));
regexpMark = attrs.getValue(MARK) != null ? Integer.parseInt(attrs.getValue(MARK)) : 0;
break;
case RULE:
xmlLineNumber = pLocator.getLineNumber();
regex = new StringBuilder();
inRule = true;
shortMessage = new StringBuilder();
message = new StringBuilder();
suggestionsOutMsg = new StringBuilder();
url = new StringBuilder();
id = attrs.getValue(ID);
name = attrs.getValue(NAME);
String minPrevMatchesStr = attrs.getValue(MINPREVMATCHES);
if (minPrevMatchesStr != null) {
if (inRuleGroup && ruleGroupMinPrevMatches > 0) {
throw new RuntimeException("Rule group " + ruleGroupId + " has " + MINPREVMATCHES + "=" + ruleGroupMinPrevMatches
+ ", thus rule " + id + " cannot specify " + MINPREVMATCHES);
}
minPrevMatches = Integer.parseInt(minPrevMatchesStr);
} else {
minPrevMatches = ruleGroupMinPrevMatches;
}
String distanceTokensStr = attrs.getValue(DISTANCETOKENS);
if (distanceTokensStr != null) {
if (inRuleGroup && ruleGroupDistanceTokens > 0) {
throw new RuntimeException("Rule group " + ruleGroupId + " has " + DISTANCETOKENS + "=" + ruleGroupDistanceTokens
+ ", thus rule " + id + " cannot specify " + DISTANCETOKENS);
}
distanceTokens = Integer.parseInt(distanceTokensStr);
} else {
distanceTokens = ruleGroupDistanceTokens;
}
String premiumRule = attrs.getValue(PREMIUM);
//check if this rule is premium
if (premiumRule != null) {
if (YES.equals(premiumRule)) {
isPremiumRule = true;
} else if (NO.equals(premiumRule)) {
isPremiumRule = false;
}
} else if (premiumRuleGroupAttribute != null){
if (YES.equals(premiumRuleGroupAttribute)) {
isPremiumRule = true;
} else if (NO.equals(premiumRuleGroupAttribute)) {
isPremiumRule = false;
}
} else if (premiumCategoryAttribute != null) {
if (YES.equals(premiumCategoryAttribute)) {
isPremiumRule = true;
} else if (NO.equals(premiumCategoryAttribute)) {
isPremiumRule = false;
}
} else if (premiumFileAttribute != null){
if (YES.equals(premiumFileAttribute)) {
isPremiumRule = true;
} else if (NO.equals(premiumFileAttribute)) {
isPremiumRule = false;
}
} else {
isPremiumRule = false;
}
if (inRuleGroup) {
subId++;
if (id == null) {
id = ruleGroupId;
}
if (name == null) {
name = ruleGroupDescription;
}
}
if (id == null && !relaxedMode) {
throw new RuntimeException("id is null for rule with name '" + name + "'");
}
id = idPrefix != null ? idPrefix + id : id;
if (inRuleGroup && ruleGroupDefaultOff && attrs.getValue(DEFAULT) != null) {
throw new RuntimeException("Rule group " + ruleGroupId + " is off by default, thus a subrule of " + id + " cannot specify 'default=...'. \033[1m Remove 'default=...' from rule group or subrule level in " + ruleGroupId + "!\033[0m");
}
if (inRuleGroup && ruleGroupDefaultTempOff && attrs.getValue(DEFAULT) != null) {
throw new RuntimeException("Rule group " + ruleGroupId + " is off by default, thus a subrule of " + id + " cannot specify 'default=...'. \033[1m Remove 'default=...' from rule group or subrule level in " + ruleGroupId + "!\033[0m");
}
if (inRuleGroup && ruleGroupDefaultOff) {
defaultOff = true;
} else if (inRuleGroup && ruleGroupDefaultTempOff) {
defaultTempOff = true;
} else {
defaultOff = OFF.equals(attrs.getValue(DEFAULT));
defaultTempOff = TEMP_OFF.equals(attrs.getValue(DEFAULT));
}
correctExamples = new ArrayList<>();
antipatternExamples = new ArrayList<>();
incorrectExamples = new ArrayList<>();
errorTriggeringExamples = new ArrayList<>();
suggestionMatches.clear();
suggestionMatchesOutMsg.clear();
if (attrs.getValue(TYPE) != null) {
ruleIssueType = attrs.getValue(TYPE);
}
isRuleSuppressMisspelled = false;
if (attrs.getValue("tags") != null) {
ruleTags.addAll(Arrays.asList(attrs.getValue("tags").split(" ")));
}
if (attrs.getValue("tone_tags") != null) {
ruleToneTags.addAll(Arrays.asList(attrs.getValue("tone_tags").split(" ")));
}
String isGoalSpecificRule = attrs.getValue(GOAL_SPECIFIC);
//check if this rule is goal specific
if (isGoalSpecificRule != null) {
if (TRUE.equals(isGoalSpecificRule)) {
isGoalSpecific = true;
} else if (FALSE.equals(isGoalSpecificRule)) {
isGoalSpecific = false;
}
} else if (isGoalSpecificRuleGroupAttribute != null) {
if (TRUE.equals(isGoalSpecificRuleGroupAttribute)) {
isGoalSpecific = true;
} else if (FALSE.equals(isGoalSpecificRuleGroupAttribute)) {
isGoalSpecific = false;
}
} else if (isGoalSpecificCategoryAttribute != null) {
if (TRUE.equals(isGoalSpecificCategoryAttribute)) {
isGoalSpecific = true;
} else if (FALSE.equals(isGoalSpecificCategoryAttribute)) {
isGoalSpecific = false;
}
} else {
isGoalSpecific = false;
}
String prioRuleAttributeValue = attrs.getValue(PRIO);
if (prioRuleAttributeValue != null) {
prioRuleAttribute = Integer.parseInt(prioRuleAttributeValue);
}
break;
case PATTERN:
startPattern(attrs);
tokenCountForMarker = 0;
interpretPosTagsPreDisambiguation = YES.equals(attrs.getValue(RAW_TAG));
break;
case ANTIPATTERN:
xmlLineNumberAntiPattern = pLocator.getLineNumber();
inAntiPattern = true;
antiPatternCounter++;
caseSensitive = YES.equals(attrs.getValue(CASE_SENSITIVE));
tokenCounter = 0;
tokenCountForMarker = 0;
break;
case AND:
inAndGroup = true;
tokenCountForMarker++;
break;
case OR:
inOrGroup = true;
tokenCountForMarker++;
break;
case UNIFY:
inUnification = true;
uniNegation = YES.equals(attrs.getValue(NEGATE));
break;
case UNIFY_IGNORE:
inUnificationNeutral = true;
break;
case FEATURE:
uFeature = attrs.getValue(ID);
break;
case TYPE:
uType = attrs.getValue(ID);
uTypeList.add(uType);
break;
case TOKEN:
setToken(attrs);
if (!inAndGroup && !inOrGroup) {
tokenCountForMarker++;
}
break;
case EXCEPTION:
setExceptions(attrs);
break;
case EXAMPLE:
String typeVal = attrs.getValue(TYPE);
if (inAntiPattern) {
if (inRuleGroup && !inRule) {
inAntiPatternForRuleGroupExample = true;
antiPatternForRuleGroupExample = new StringBuilder();
} else {
inAntiPatternExample = true;
antiPatternExample = new StringBuilder();
}
} else if ("incorrect".equals(typeVal) || attrs.getValue("correction") != null) {
inIncorrectExample = true;
incorrectExample = new StringBuilder();
if (attrs.getValue("correction") != null) {
exampleCorrection = new StringBuilder();
exampleCorrection.append(attrs.getValue("correction"));
}
} else if ("triggers_error".equals(typeVal)) {
inErrorTriggerExample = true;
errorTriggerExample = new StringBuilder();
} else {
// no attribute implies the sentence is a correct example
inCorrectExample = true;
correctExample = new StringBuilder();
}
break;
case "filter":
filterClassName = attrs.getValue("class");
filterArgs = attrs.getValue("args");
break;
case MESSAGE:
inMessage = true;
inSuggestion = false;
message = new StringBuilder();
isRuleSuppressMisspelled = YES.equals(attrs.getValue("suppress_misspelled"));
if (isRuleSuppressMisspelled) {
message.append(PLEASE_SPELL_ME);
}
break;
case SUGGESTION:
String strToAppend = "<suggestion>";
isSuggestionSuppressMisspelled = YES.equals(attrs.getValue("suppress_misspelled"));
if (isSuggestionSuppressMisspelled || isRuleSuppressMisspelled) {
strToAppend = strToAppend + PLEASE_SPELL_ME;
}
if (inMessage) {
message.append(strToAppend);
} else { // suggestions outside message
suggestionsOutMsg.append(strToAppend);
}
inSuggestion = true;
break;
case "short":
if (inRule) {
inShortMessage = true;
shortMessage = new StringBuilder();
} else {
inShortMessageForRuleGroup = true;
shortMessageForRuleGroup = new StringBuilder();
}
break;
case "url":
if (inRule) {
inUrl = true;
url = new StringBuilder();
} else {
inUrlForRuleGroup = true;
urlForRuleGroup = new StringBuilder();
}
break;
case RULEGROUP:
ruleGroupId = attrs.getValue(ID);
premiumRuleGroupAttribute = attrs.getValue(PREMIUM);
ruleGroupDescription = attrs.getValue(NAME);
ruleGroupDefaultOff = OFF.equals(attrs.getValue(DEFAULT));
ruleGroupDefaultTempOff = TEMP_OFF.equals(attrs.getValue(DEFAULT));
urlForRuleGroup = new StringBuilder();
shortMessageForRuleGroup = new StringBuilder();
inRuleGroup = true;
subId = 0;
if (attrs.getValue(TYPE) != null) {
ruleGroupIssueType = attrs.getValue(TYPE);
}
if (attrs.getValue("tags") != null) {
ruleGroupTags.addAll(Arrays.asList(attrs.getValue("tags").split(" ")));
}
if (attrs.getValue("tone_tags") != null) {
ruleGroupToneTags.addAll(Arrays.asList(attrs.getValue("tone_tags").split(" ")));
}
isGoalSpecificRuleGroupAttribute = attrs.getValue(GOAL_SPECIFIC);
String minPrevMatchesStr2 = attrs.getValue(MINPREVMATCHES);
if (minPrevMatchesStr2 != null) {
ruleGroupMinPrevMatches = Integer.parseInt(minPrevMatchesStr2);
}
String distanceTokensStr2 = attrs.getValue(DISTANCETOKENS);
if (distanceTokensStr2 != null) {
ruleGroupDistanceTokens = Integer.parseInt(distanceTokensStr2);
}
antipatternForRuleGroupsExamples = new ArrayList<>();
String prioRuleGroupAttributeValue = attrs.getValue(PRIO);
if (prioRuleGroupAttributeValue != null) {
prioRuleGroupAttribute = Integer.parseInt(prioRuleGroupAttributeValue);
}
break;
case MATCH:
setMatchElement(attrs, inSuggestion && (isSuggestionSuppressMisspelled || isRuleSuppressMisspelled));
break;
case MARKER:
if (inMarker) {
throw new IllegalStateException("'<marker>' may not be nested in rule '" + id + "'");
}
if (inIncorrectExample) {
incorrectExample.append(MARKER_TAG);
} else if (inCorrectExample) {
correctExample.append(MARKER_TAG);
} else if (inErrorTriggerExample) {
errorTriggerExample.append(MARKER_TAG);
} else if (inPattern || inAntiPattern) {
startPos = tokenCounter;
inMarker = true;
}
break;
case UNIFICATION:
uFeature = attrs.getValue("feature");
inUnificationDef = true;
break;
case "equivalence":
uType = attrs.getValue(TYPE);
break;
case PHRASES:
inPhrases = true;
break;
case "includephrases":
break;
case "phrase":
if (inPhrases) {
phraseId = attrs.getValue(ID);
}
break;
case "phraseref":
if (attrs.getValue("idref") != null) {
preparePhrase(attrs);
tokenCountForMarker++;
}
break;
}
}