/* * Copyright 2005-2015 by BerryWorks Software, LLC. All rights reserved. * * This file is part of EDIReader. You may obtain a license for its use directly from * BerryWorks Software, and you may also choose to use this software under the terms of the * GPL version 3. Other products in the EDIReader software suite are available only by licensing * with BerryWorks. Only those files bearing the GPL statement below are available under the GPL. * * EDIReader is free software: you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * EDIReader 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along with EDIReader. If not, * see <http://www.gnu.org/licenses/>. */ package com.berryworks.edireader.plugin; import com.berryworks.edireader.EDIAbstractReader; import com.berryworks.edireader.Plugin; import com.berryworks.edireader.PluginController; import com.berryworks.edireader.tokenizer.Tokenizer; import java.util.HashMap; import java.util.Map; import static com.berryworks.edireader.util.FixedLength.isPresent; public abstract class AbstractPluginControllerFactory implements PluginControllerFactoryInterface { protected static final Map<String, Plugin> pluginCache = new HashMap<>(); protected static boolean debug; protected String lastPluginLoaded = null; protected PluginController lastPluginController; public String getLastPluginLoaded() { return lastPluginLoaded; } /** * Creates a new instance of a PluginController, selecting a plugin based on the standard and type of document. * * @param standard - name of EDI standard (for example: "EDIFACT" or "ANSI") * @param docType - type of document (for example: "837" or "INVOIC") * @param tokenizer - reference to the Tokenizer to provide context for syntax exceptions * @return instance of a PluginController */ @Override public PluginController create(String standard, String docType, Tokenizer tokenizer) { return create(standard, docType, null, null, tokenizer); } /** * Find a plugin for a given standard, document type, version, and release. * If no matching plugin is found, return null. * Plugins are cached so that once a plugin is loaded it can be quickly found again without using the * class loader. * * @param standard - name of EDI standard (for example: "EDIFACT" or "ANSI") * @param docType - type of document (for example: "837" or "INVOIC") * @param docVersion - a particular version of the standard (for example: "X" in ANSI or "04A" in EDIFACT) * @param docRelease - a particular release of the standard (for example: "D" in EDIFACT or "004010" in ANSI) * @return Plugin that was found, or null if no suitable plugin was found */ protected Plugin loadPlugin(String standard, String docType, String docVersion, String docRelease) { Plugin result = null; String key = standard + "_" + docType + "_" + docVersion + "_" + docRelease; if (pluginCache.containsKey(key)) { if (debug) trace("plugin for " + key + " found in cache"); lastPluginLoaded = key; result = pluginCache.get(key); } else { String suffix = System.getProperty("EDIREADER_PLUGIN_SUFFIX"); if (isPresent(docVersion) && isPresent(docRelease)) { if (isPresent(suffix)) result = lookForSpecificPlugin(standard, docVersion + "_" + docRelease + "." + standard + "_" + docType + "_" + suffix); if (result == null) result = lookForSpecificPlugin(standard, docVersion + "_" + docRelease + "." + standard + "_" + docType); if (isPresent(suffix)) result = lookForSpecificPlugin(standard, docType + "_" + docVersion + "_" + docRelease + "_" + suffix); if (result == null) result = lookForSpecificPlugin(standard, docType + "_" + docVersion + "_" + docRelease); } if (result == null && isPresent(suffix)) result = lookForSpecificPlugin(standard, docType + "_" + suffix); if (result == null) result = lookForSpecificPlugin(standard, docType); if (result != null) pluginCache.put(key, result); } return result; } /** * Shorthand for EDIReader.trace(String) * * @param text message to appear in trace */ protected static void trace(String text) { EDIAbstractReader.trace(text); } @Override public PluginController getLastControllerCreated() { return lastPluginController; } public void clearCache() { pluginCache.clear(); } /** * Creates a new instance of a PluginController, selecting a plugin based on the standard, the type of document, * and the version and release characteristics. * <p> * This factory method supports version-specific plugins for a given type of document. If first tries to load * a plugin specific to a particular release and version using the naming convention for plugin class names. * If no version-specific plugin is available, it uses the other factory method * to create a plugin based simply on the standard and type. * * @param standard - name of EDI standard (for example: "EDIFACT" or "ANSI") * @param docType - type of document (for example: "837" or "INVOIC") * @param docVersion - a particular version of the standard (for example: "X" in ANSI or "04A" in EDIFACT) * @param docRelease - a particular release of the standard (for example: "D" in EDIFACT or "004010" in ANSI) * @param tokenizer - reference to the Tokenizer to provide context for syntax exceptions * @return instance of a PluginController */ @Override public PluginController create(String standard, String docType, String docVersion, String docRelease, Tokenizer tokenizer) { PluginControllerImpl result; Plugin plugin = loadPlugin(standard, docType, docVersion, docRelease); if (plugin == null) { result = new PluginControllerImpl(standard, tokenizer); result.setEnabled(false); } else { plugin.init(); result = plugin.createController(standard, tokenizer); result.setEnabled(true); } result.setDocumentType(docType); result.setPlugin(plugin); lastPluginController = result; return result; } protected abstract Plugin lookForSpecificPlugin(String standard, String docType); protected abstract Plugin getInstance(String standard, String docType) throws Exception; }