/*
* WPCleaner: A tool to help on Wikipedia maintenance tasks.
* Copyright (C) 2013 Nicolas Vervelle
*
* See README.txt file for licensing information.
*/
package org.wikipediacleaner.api.constants;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import org.wikipediacleaner.api.APIException;
import org.wikipediacleaner.api.check.CheckError;
import org.wikipediacleaner.api.check.algorithm.CheckErrorAlgorithm;
import org.wikipediacleaner.i18n.GT;
import org.wikipediacleaner.utils.Configuration;
import org.wikipediacleaner.utils.ConfigurationValueBoolean;
/**
* Configuration for Check Wiki project.
*/
public class CWConfiguration {
/**
* Maximum number for error numbers.
*/
public static final int MAX_ERROR_NUMBER = 999;
/**
* Check Wiki project code.
*/
private final String code;
/**
* Wiki.
*/
private final EnumWikipedia wiki;
public CWConfiguration(String code, EnumWikipedia wiki) {
this.code = code;
this.wiki = wiki;
this.configuration = new ArrayList<CWConfigurationError>();
}
// =================================================================================
// Project availability
// =================================================================================
/**
* @return Flag indicating if the Check Wiki project is available.
*/
public boolean isProjectAvailable() {
WPCConfiguration config = wiki.getConfiguration();
String project = config.getString(WPCConfigurationString.CW_PROJECT_PAGE);
if (project != null) {
return true;
}
return config.getBoolean(WPCConfigurationBoolean.CW_FORCE);
}
// =================================================================================
// Comment
// =================================================================================
/**
* @return Comment for Check Wiki project.
*/
public String getComment() {
WPCConfiguration config = wiki.getConfiguration();
String comment = config.getString(WPCConfigurationString.CW_COMMENT);
if (comment != null) {
return comment;
}
String project = config.getString(WPCConfigurationString.CW_PROJECT_PAGE);
return GT._("Fixed using {0}", (project != null) ? "[[" + project + "]]" : "Check Wiki project");
}
/**
* @return Comment for Check Wiki project.
*/
public String getComment(Collection<CheckError.Progress> algorithms) {
if ((algorithms == null) || (algorithms.isEmpty())) {
return "";
}
// Build part of the comment for the errors that were fixed
StringBuilder algorithmsComment = new StringBuilder();
Configuration config = Configuration.getConfiguration();
for (CheckError.Progress progress : algorithms) {
CheckErrorAlgorithm algorithm = progress.algorithm;
if (algorithmsComment.length() > 0) {
algorithmsComment.append(" - ");
}
String link = algorithm.getLink();
if ((link != null) &&
(config != null) &&
(config.getBoolean(
null,
ConfigurationValueBoolean.CHECK_LINK_ERRORS))) {
algorithmsComment.append("[[");
algorithmsComment.append(link);
algorithmsComment.append("|");
algorithmsComment.append(algorithm.getShortDescriptionReplaced());
algorithmsComment.append("]]");
} else {
algorithmsComment.append(algorithm.getShortDescriptionReplaced());
}
}
// Build the entire comment
String comment = getComment();
if (comment.indexOf("{0}") < 0) {
return comment + " (" + algorithmsComment.toString() + ")";
}
return GT._(comment, algorithmsComment.toString());
}
// =================================================================================
// Error configuration
// =================================================================================
/**
* Configuration for each error.
*/
private final ArrayList<CWConfigurationError> configuration;
/**
* @param errorNumber Error number.
* @return Configuration for error.
*/
public CWConfigurationError getErrorConfiguration(int errorNumber) {
if ((errorNumber < 0) || (errorNumber >= configuration.size())) {
return null;
}
return configuration.get(errorNumber);
}
/* ================================================================================= */
/* Property management */
/* ================================================================================= */
/**
* Prefix for property names.
*/
private final static String PREFIX = "error_";
/**
* Enumerated value for the origin of the configuration.
*/
public static enum Origin {
GENERAL_CONFIGURATION,
WIKI_CONFIGURATION,
USER_CONFIGURATION,
}
/**
* Set property.
*
* @param name Property name.
* @param value Property value.
* @param suffix Suffix for properties to consider.
* @param otherSuffix Suffix for properties not to consider.
* @param origin Origin of the configuration.
*/
private void setProperty(
String name, String value,
String suffix, String otherSuffix,
Origin origin) {
boolean matches = true;
// Check that property prefix is OK
if (matches && name.startsWith(PREFIX)) {
name = name.substring(PREFIX.length());
} else {
matches = false;
}
// Check that property suffix is OK
boolean goodSuffix = false;
if (matches && name.endsWith(suffix)) {
name = name.substring(0, name.length() - suffix.length());
goodSuffix = true;
} else if (matches && name.endsWith(otherSuffix)) {
name = name.substring(0, name.length() - otherSuffix.length());
} else {
matches = false;
}
if (matches && name.endsWith("_")) {
name = name.substring(0, name.length() - 1);
} else {
matches = false;
}
// Retrieve error number
int errorNumber = -1;
if (matches && (name.length() > 4) &&
Character.isDigit(name.charAt(0)) &&
Character.isDigit(name.charAt(1)) &&
Character.isDigit(name.charAt(2)) &&
(name.charAt(3) == '_')) {
try {
errorNumber = Integer.parseInt(name.substring(0, 3));
} catch (NumberFormatException e) {
// Not supposed to happen
}
name = name.substring(4);
} else {
matches = false;
}
// Save property
if (matches && (errorNumber > 0) && (errorNumber <= MAX_ERROR_NUMBER)) {
if (goodSuffix) {
CWConfigurationError error = null;
if (configuration.size() > errorNumber) {
error = configuration.get(errorNumber);
}
if (error == null) {
error = new CWConfigurationError(errorNumber);
configuration.ensureCapacity(errorNumber + 1);
while (configuration.size() < errorNumber + 1) {
configuration.add(configuration.size(), null);
}
configuration.set(errorNumber, error);
}
error.addProperty(name, value, origin);
}
}
}
/**
* Extract next parameter from Check Wiki configuration.
*
* @param reader Reader for the configuration.
* @param suffix Suffix for properties to consider.
* @param otherSuffix Suffix for properties not to consider.
* @param origin Origin of the configuration.
* @return Next parameter found.
* @throw APIException.
*/
private boolean setNextParameter(
BufferedReader reader,
String suffix, String otherSuffix,
Origin origin) throws APIException {
String line;
try {
while ((line = reader.readLine()) != null) {
int posEqual = line.indexOf('=');
int posSharp = line.indexOf('#');
if ((posEqual > 0) &&
((posSharp < 0) || (posSharp > posEqual))) {
String name = line.substring(0, posEqual);
line = line.substring(posEqual + 1);
int posEnd = line.indexOf(" END");
while (posEnd == -1) {
String nextLine = reader.readLine();
if (nextLine != null) {
line += "\n" + nextLine;
posEnd = line.indexOf(" END");
} else {
posEnd = line.length();
}
}
line = line.substring(0, posEnd);
if ((name != null) && (line != null)) {
setProperty(name.trim(), line, suffix, otherSuffix, origin);
}
return true;
}
}
} catch (IOException e) {
throw new APIException("Error reading Check Wiki configuration: " + e.getMessage());
}
return false;
}
/**
* @param input Reader for general project configuration.
*/
public void setGeneralConfiguration(Reader input) throws APIException {
BufferedReader reader = new BufferedReader(input);
while (setNextParameter(reader, "script", code, Origin.GENERAL_CONFIGURATION)) {
//
}
try {
reader.close();
} catch (IOException e) {
// Nothing
}
}
/**
* @param input Reader for project configuration specific for this wiki.
*/
public void setWikiConfiguration(Reader input) throws APIException {
BufferedReader reader = new BufferedReader(input);
while (setNextParameter(reader, code, "script", Origin.WIKI_CONFIGURATION)) {
//
}
try {
reader.close();
} catch (IOException e) {
// Nothing
}
}
/**
* @param name Parameter name.
* @param value Parameter value.
*/
void setUserConfiguration(String name, String value) {
setProperty(name, value, code, "script", Origin.USER_CONFIGURATION);
}
}