001/*
002 * Syncany, www.syncany.org
003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package org.syncany.plugins;
019
020import java.io.InputStream;
021import java.util.Properties;
022
023import org.syncany.plugins.transfer.TransferManager;
024import org.syncany.plugins.transfer.TransferSettings;
025
026/**
027 * A plugin can be used to store Syncany's repository files on any remote location. 
028 * Implementations of the <code>Plugin</code> class identify a storage/transfer plugin.
029 * 
030 * <p>Using the 'id' attribute, plugins can be loaded by the {@link Plugins} class. 
031 * Once a plugin is loaded, a corresponding {@link TransferSettings} object must be created and 
032 * initialized. From the connection object, a {@link TransferManager} can then be used to
033 * upload/download files to the repository.
034 * 
035 * <p>Per <b>naming convention</b>, plugins must end by the name <b>Plugin</b> and extend this class. 
036 * Furthermore, all plugin classes must reside in a package <b>org.syncany.plugins.<i>plugin-id</i></b>,
037 * where <i>plugin-id</i> is the identifier specified by {@link #getId()}. 
038 * 
039 * @author Philipp C. Heckel (philipp.heckel@gmail.com)
040 */
041public abstract class Plugin {
042        private static final String PLUGIN_PROPERTIES_NAME_KEY = "pluginName";
043        private static final String PLUGIN_PROPERTIES_VERSION_KEY = "pluginVersion";
044        private static final String PLUGIN_PROPERTIES_DATE_KEY = "pluginDate";
045
046        private String pluginId;
047        private Properties pluginProperties;
048
049        public Plugin(String pluginId) {
050                this.pluginId = pluginId;
051                this.pluginProperties = loadPluginProperties(pluginId);
052        }
053
054        /**
055         * Returns a unique plugin identifier.
056         * 
057         * <p>This identifier must correspond to the to the fully qualified package name in
058         * which the plugin classes reside. all plugin classes must reside in a package 
059         * 'org.syncany.connection.plugins.<i>plugin-id</i>'. 
060         */
061        public String getId() {
062                return pluginId;
063        }
064
065        /**
066         * Returns a short name of the plugin
067         */
068        public String getName() {
069                return pluginProperties.getProperty(PLUGIN_PROPERTIES_NAME_KEY);
070        }
071
072        /**
073         * Returns the version of the plugin
074         */
075        public String getVersion() {
076                return pluginProperties.getProperty(PLUGIN_PROPERTIES_VERSION_KEY);
077        }
078        
079        /**
080         * Returns the date the plugin was compiled
081         */
082        public String getDateStr() {
083                return pluginProperties.getProperty(PLUGIN_PROPERTIES_DATE_KEY);
084        }
085
086        /**
087         * Loads the plugin properties (ID, name, version)
088         * from the resource
089         */
090        private Properties loadPluginProperties(String pluginId) {
091                String pluginInfoResource = "/" + Plugin.class.getPackage().getName().replace('.', '/') + "/" + pluginId + "/plugin.properties";
092                
093                InputStream pluginPropertiesInputStream = Plugin.class.getResourceAsStream(pluginInfoResource);
094
095                try {
096                        Properties pluginProperties = new Properties();
097                        pluginProperties.load(pluginPropertiesInputStream);
098
099                        return pluginProperties;
100                }
101                catch (Exception e) {
102                        throw new RuntimeException("Cannot load application properties.", e);
103                }
104        }       
105}