/*
* 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.data;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Bean for holding TemplateData information.
*
* @see <a href="http://www.mediawiki.org/wiki/Extension:TemplateData">TemplateData extension</a>
*/
public class TemplateData {
/**
* Title of the template.
*/
private String title;
/**
* Template description.
*/
private InterfaceText description;
/**
* Template parameters.
*/
private List<Parameter> parameters;
/**
* Default constructor.
*/
public TemplateData() {
this.description = null;
}
/**
* Create a template data from a page analysis.
*
* @param analysis Page analysis.
* @return TemplateData.
*/
public static TemplateData createFromContent(PageAnalysis analysis) {
TemplateData result = new TemplateData();
List<PageElementParameter> parameters = analysis.getParameters();
if (parameters != null) {
List<Parameter> params = new ArrayList<TemplateData.Parameter>();
for (PageElementParameter parameter : parameters) {
String name = parameter.getParameterName();
Parameter param = null;
for (Parameter tmpParam : params) {
if (name.equals(tmpParam.getName())) {
param = tmpParam;
}
}
if (param == null) {
param = new Parameter(name);
params.add(param);
}
}
Collections.sort(params);
result.parameters = params;
}
return result;
}
/**
* @return Name of the template.
*/
public String getTitle() {
return title;
}
/**
* @param title Name of the template.
*/
public void setTitle(String title) {
this.title = title;
}
/**
* @return Template description.
*/
public InterfaceText getDescription() {
return description;
}
/**
* @param description Template description.
*/
public void setDescription(InterfaceText description) {
this.description = description;
}
/**
* @return Template parameters.
*/
public List<Parameter> getParameters() {
return parameters;
}
/**
* @param parameterName Parameter name.
* @return Parameter for the given name.
*/
public Parameter getParameter(String parameterName) {
if ((parameterName == null) || (parameters == null)) {
return null;
}
for (Parameter param : parameters) {
if (param.isPossibleName(parameterName)) {
return param;
}
}
return null;
}
/**
* @param parameters Template parameters.
*/
public void setParameters(List<Parameter> parameters) {
this.parameters = parameters;
}
/**
* Bean for holding a description in a single language or several languages.
*/
public static class InterfaceText {
/**
* True if multiple languages are used for the description.
*/
private boolean multipleLanguages;
/**
* Description in a single language.
*/
private String text;
/**
* Description in multiple languages.
*/
private List<LanguageValue> texts;
/**
* Default constructor.
*/
public InterfaceText() {
this.multipleLanguages = false;
this.text = null;
this.texts = null;
}
/**
* Constructor for a single language.
*
* @param text Description.
*/
public InterfaceText(String text) {
this.multipleLanguages = false;
this.text = text;
this.texts = null;
}
/**
* Constructor for multiple languages.
*
* @param texts Descriptions.
*/
public InterfaceText(List<LanguageValue> texts) {
this.multipleLanguages = true;
this.text = null;
this.texts = new ArrayList<LanguageValue>();
if (texts != null) {
this.texts.addAll(texts);
}
}
/**
* @return True if descriptions are in multiple languages.
*/
public boolean hasMultipleLanguages() {
return multipleLanguages;
}
/**
* @return Description in a single language.
*/
public String getText() {
return text;
}
/**
* @return Descriptions in multiple languages.
*/
public List<LanguageValue> getTexts() {
return Collections.unmodifiableList(texts);
}
/**
* @return Description.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
if (!multipleLanguages) {
return text;
}
if ((texts != null) && !texts.isEmpty()) {
return texts.get(0).toString();
}
return super.toString();
}
}
/**
* Bean for holding a description in one specified language.
*/
public static class LanguageValue {
/**
* Language code.
*/
private String language;
/**
* Description.
*/
private String text;
/**
* @param language Language code.
* @param text Description in that language.
*/
public LanguageValue(String language, String text) {
this.language = language;
this.text = text;
}
/**
* @return Language code.
*/
public String getLanguage() {
return language;
}
/**
* @return Description.
*/
public String getText() {
return text;
}
/**
* @return Description.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "" + language + " - " + text;
}
}
/**
* Bean for holding a template parameter description.
*/
public static class Parameter implements Comparable<Parameter> {
/** Parameter name. */
private String name;
/** Label for the parameter. */
private InterfaceText label;
/** Parameter description. */
private InterfaceText description;
/** Parameter type. */
private String type;
/** Parameter aliases. */
private List<String> aliases;
/** True if parameter is required. */
private boolean required;
/** True if parameter should be suggested. */
private boolean suggested;
/** True if parameter is deprecated. */
private boolean deprecated;
/** Reason for deprecation. */
private String deprecatedText;
/** Value to use when adding the parameter. */
private String autoValue;
/** Default value when parameter is not set. */
private String defaultValue;
/**
* Default constructor.
*/
public Parameter(String name) {
this.name = name;
this.label = new InterfaceText();
this.description = new InterfaceText();
this.type = null;
this.aliases = null;
this.required = false;
this.suggested = false;
this.deprecated = false;
this.deprecatedText = null;
this.autoValue = null;
this.defaultValue = null;
}
/**
* @return Parameter name.
*/
public String getName() {
return name;
}
/**
* @param parameterName Parameter name.
* @return True if the parameter name matches this template data parameter.
*/
public boolean isPossibleName(String parameterName) {
if (parameterName == null) {
return false;
}
if ((name != null) && (name.equals(parameterName))) {
return true;
}
if (aliases != null) {
for (String alias : aliases) {
if ((alias != null) && (alias.equals(parameterName))) {
return true;
}
}
}
return false;
}
/**
* @return Parameter label.
*/
public InterfaceText getLabel() {
return label;
}
/**
* @param label Parameter label.
*/
public void setLabel(InterfaceText label) {
this.label = label;
}
/**
* @return Parameter description.
*/
public InterfaceText getDescription() {
return description;
}
/**
* @param description Parameter description.
*/
public void setDescription(InterfaceText description) {
this.description = description;
}
/**
* @return Parameter type.
*/
public EnumParameterType getType() {
for (EnumParameterType paramType : EnumParameterType.values()) {
if (paramType.type.equals(type)) {
return paramType;
}
}
return EnumParameterType.UNKNOWN;
}
/**
* @param type Parameter type.
*/
public void setType(String type) {
this.type = type;
}
/**
* @return Parameter aliases.
*/
public List<String> getAliases() {
return aliases;
}
/**
* @param aliases Parameter aliases.
*/
public void setAliases(List<String> aliases) {
this.aliases = aliases;
}
/**
* @return True if parameter is required.
*/
public boolean isRequired() {
return required;
}
/**
* @param required True if parameter is required.
*/
public void setRequired(boolean required) {
this.required = required;
}
/**
* @return True if parameter should be suggested.
*/
public boolean isSuggested() {
return suggested;
}
/**
* @param suggested True if parameter should be suggested.
*/
public void setSuggested(boolean suggested) {
this.suggested = suggested;
}
/**
* @return True if parameter is deprecated.
*/
public boolean isDeprecated() {
return deprecated;
}
/**
* @return Reason for deprecation.
*/
public String getDeprecatedText() {
return deprecatedText;
}
/**
* @param deprecated True if parameter is deprecated.
*/
public void setDeprecated(boolean deprecated) {
this.deprecated = deprecated;
this.deprecatedText = null;
}
/**
* @param text Reason for deprecation.
*/
public void setDeprecated(String text) {
if ((text != null) && (text.trim().length() > 0)) {
this.deprecated = true;
this.deprecatedText = text.trim();
} else {
this.deprecated = false;
this.deprecatedText = null;
}
}
/**
* @return Parameter auto value.
*/
public String getAutoValue() {
return autoValue;
}
/**
* @param autoValue Parameter auto value.
*/
public void setAutoValue(String autoValue) {
this.autoValue = autoValue;
}
/**
* @return Parameter default value.
*/
public String getDefaultValue() {
return defaultValue;
}
/**
* @param defaultValue Parameter default value.
*/
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
/**
* @param o The TemplateData to be compared.
* @return a negative integer, zero, or a positive integer as this TemplateData
* is less than, equal to, or greater than the specified TemplateData.
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(Parameter o) {
return name.compareTo(o.name);
}
/**
* @return Description.
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
if (name != null) {
return name;
}
return super.toString();
}
}
/**
* Enumeration of all parameter types.
*/
public static enum EnumParameterType {
BOOLEAN("boolean"),
CONTENT("content"),
DATE("date"),
LINE("line"),
NUMBER("number"),
STRING("string"),
UNBALANCED_WIKITEXT("unbalanced-wikitext"),
WIKI_FILE_NAME("wiki-file-name"),
WIKI_PAGE_NAME("wiki-page-name"),
WIKI_USER_NAME("wiki-user-name"),
UNKNOWN("unknown");
String type;
/**
* @param name Type name.
*/
EnumParameterType(String name) {
this.type = name;
}
/**
* @param value Value.
* @return True if the value is compatible with the type.
* @see <a href="https://www.mediawiki.org/wiki/Extension:TemplateData#Format">TemplateData format</a>
*/
public boolean isCompatible(String value) {
if (value == null) {
return true;
}
switch (this) {
case CONTENT: // Page content in wikitext, such as text style, links, images, etc.
case STRING: // Any textual value
case UNBALANCED_WIKITEXT: // Raw wikitext that should not be treated as standalone content because it is unbalanced
case WIKI_FILE_NAME: // A valid MediaWiki file name for the current wiki
case WIKI_PAGE_NAME: // A valid MediaWiki page name for the current wiki
case WIKI_USER_NAME: // A valid MediaWiki user name for the current wiki
return true;
case BOOLEAN: // A boolean value ('1' for true, '0' for false, '' for unknown)
if (!value.trim().equals("0") &&
!value.trim().equals("1") &&
!value.trim().equals("")) {
return false;
}
break;
case DATE: // A date in ISO 8601 format, e.g. "2014-05-09" or "2014-05-09T16:01:12Z"
// TODO
// According to https://en.wikipedia.org/wiki/ISO_8601, some possible formats:
// Date:
// YYYY
// ±YYYYY
// YYYY-MM-DD or YYYYMMDD
// YYYY-MM
// YYYY-Www or YYYYWww
// YYYY-Www-D or YYYYWwwD
// YYYY-DDD or YYYYDDD
// Time: T for beginning time ; . or , are equivalent ; . or , can be used on the last item
// hh:mm:ss.sss or hhmmss.sss
// hh:mm:ss or hhmmss
// hh:mm or hhmm
// hh
// Time zone:
// <time>Z
// <time>±hh:mm
// <time>±hhmm
// <time>±hh
break;
case LINE: // Short text field - use for names, labels, and other short-form fields
if (value.indexOf('\n') >= 0) {
return false;
}
break;
case NUMBER: // Any numerical value (without decimal points or thousand separators)
// Check that it's a number
for (int charNum = 0; charNum < value.length(); charNum++) {
char currentChar = value.charAt(charNum);
if (!Character.isDigit(currentChar) &&
!Character.isWhitespace(currentChar) &&
(currentChar != '.')) {
return false;
}
}
break;
}
return true;
}
/**
* @return Description.
* @see java.lang.Enum#toString()
*/
@Override
public String toString() {
return type;
}
}
/**
* Bean for holding a template set.
*/
public static class Set {
/**
* Set label.
*/
private InterfaceText label;
/**
* List of parameters in the set.
*/
private List<String> parameters;
/**
* Default constructor.
*/
public Set() {
this.label = new InterfaceText();
this.parameters = null;
}
/**
* @return Set label.
*/
public InterfaceText getLabel() {
return label;
}
/**
* @return List of parameters in the set.
*/
public List<String> getParameters() {
return parameters;
}
}
}