/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.tools.documentation; import com.rapidminer.operator.OperatorDescription; import com.rapidminer.tools.LogService; import com.rapidminer.tools.OperatorService; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.ResourceBundle; import java.util.logging.Level; /** * A resource bundle that maps operator names to {@link OperatorDocumentation} instances. Instances * of this class always return {@link OperatorDocumentation}s from their {@link #getObject(String)} * methods. * * @author Sebastian Land * */ public class OperatorDocBundle extends ResourceBundle { public static final String GROUP_PREFIX = "group."; public static final String OPERATOR_PREFIX = "operator."; private final Map<String, OperatorDocumentation> operatorKeyDescriptionMap; private final Map<String, GroupDocumentation> groupMap; public OperatorDocBundle() { this.operatorKeyDescriptionMap = new HashMap<String, OperatorDocumentation>(); this.groupMap = new HashMap<String, GroupDocumentation>(); } public OperatorDocBundle(Map<String, OperatorDocumentation> operatorKeyDescriptionMap, Map<String, GroupDocumentation> groupMap) { this.operatorKeyDescriptionMap = operatorKeyDescriptionMap; this.groupMap = groupMap; } protected void addOperatorDoc(String key, OperatorDocumentation documentation) { this.operatorKeyDescriptionMap.put(key, documentation); } protected void addGroupDoc(String key, GroupDocumentation documentation) { this.groupMap.put(key, documentation); } @Override public Enumeration<String> getKeys() { return Collections.enumeration(operatorKeyDescriptionMap.keySet()); } @Override protected Object handleGetObject(String key) { if (key.startsWith(OPERATOR_PREFIX)) { key = key.substring(OPERATOR_PREFIX.length()); OperatorDocumentation doc = operatorKeyDescriptionMap.get(key); if (doc == null) { doc = new OperatorDocumentation(key); operatorKeyDescriptionMap.put(key, doc); // LogService.getRoot().fine("Creating new empty documentation for operator " + // key); LogService.getRoot().log(Level.FINE, "com.rapidminer.tools.documentation.OperatorDocBundle.creating_empty_documentation_for_operator", key); } return doc; } else if (key.startsWith(GROUP_PREFIX)) { key = key.substring(GROUP_PREFIX.length()); GroupDocumentation groupDocumentation = groupMap.get(key); if (groupDocumentation == null) { groupDocumentation = new GroupDocumentation(key); groupMap.put(key, groupDocumentation); // LogService.getRoot().fine("Creating new empty documentation for group " + key); LogService.getRoot().log(Level.FINE, "com.rapidminer.tools.documentation.OperatorDocBundle.creating_empty_documentation_for_group", key); } return groupDocumentation; } return null; } /** Checks for empty documentation and documentation that has no associated operator. */ public void check() { // LogService.getRoot().info("Checking operator documentation"); LogService.getRoot().log(Level.INFO, "com.rapidminer.tools.documentation.OperatorDocBundle.checking_operator_documentation"); int missing = 0; int same = 0; int deprecation = 0; int different = 0; int empty = 0; for (Map.Entry<String, OperatorDocumentation> entry : operatorKeyDescriptionMap.entrySet()) { String key = entry.getKey(); OperatorDocumentation doc = entry.getValue(); if (key.startsWith("W-")) { continue; } if (doc.getDocumentation().trim().isEmpty()) { // LogService.getRoot().warning("Empty documentation for " + key); LogService.getRoot().log(Level.WARNING, "com.rapidminer.tools.documentation.OperatorDocBundle.empty_documentation", key); empty++; } OperatorDescription desc = OperatorService.getOperatorDescription(key); if (desc == null) { missing++; // LogService.getRoot().warning("Documentation for nonexistent operator " + key); LogService.getRoot().log(Level.WARNING, "com.rapidminer.tools.documentation.OperatorDocBundle.documentation_for_nonexistent_operator", key); } String replacement = OperatorService.getReplacementForDeprecatedClass(key); if (replacement != null) { deprecation++; String string; OperatorDocumentation otherDoc = operatorKeyDescriptionMap.get(replacement); if (otherDoc != null) { if (otherDoc.getDocumentation().equals(doc.getDocumentation())) { string = replacement + " has the same documentation entry."; same++; } else { string = replacement + " has a different documentation entry."; different++; } } else { string = replacement + " has no documentation entry."; } // LogService.getRoot().warning("Documentation for deprecated operator " + key + // " replaced by " + replacement + ". " + string); LogService.getRoot().log(Level.WARNING, "com.rapidminer.tools.documentation.OperatorDocBundle.documentation_for_deprecated_operator", new Object[] { key, replacement, string }); } } // LogService.getRoot().info("Found " + empty + // " empty documentations. Found documentation for " + missing + " nonexistent and " + // (deprecation) + " replaced operators. Out of these, " + same + // " documentations are identical to the documentation of the replacement and " // + (deprecation - same - different) + " replacements have no documentation."); LogService.getRoot().log(Level.INFO, "com.rapidminer.tools.I18N.operator_doc_bundle_warning4", new Object[] { empty, missing, (deprecation), same, (deprecation - same - different) }); } }