/**
* Copyright (C) 2005 - 2011 Eric Van Dewoestine
*
* This program 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.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.eclim.plugin;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
import org.eclim.Services;
import org.eclim.command.Command;
import org.eclim.logging.Logger;
import org.eclim.util.file.FileUtils;
import org.eclipse.core.runtime.FileLocator;
/**
* Abstract implementation of {@link PluginResources}.
*
* @author Eric Van Dewoestine
*/
public abstract class AbstractPluginResources
implements PluginResources
{
private static final Logger logger =
Logger.getLogger(AbstractPluginResources.class);
private static final String PLUGIN_PROPERTIES = "/plugin.properties";
private String name;
private String pluginName;
private Properties properties;
private ResourceBundle bundle;
private List<String> missingResources = new ArrayList<String>();
private HashMap<String, Class<? extends Command>> commands =
new HashMap<String, Class<? extends Command>>();
/**
* Initializes this instance.
*
* @param name The plugin name.
*/
public void initialize(String name)
{
this.name = name;
int index = name.lastIndexOf('.');
pluginName = index != -1 ? name.substring(index + 1) : name;
}
/**
* {@inheritDoc}
*/
public String getName()
{
return name;
}
/**
* {@inheritDoc}
*/
public Collection<? extends Class<? extends Command>> getCommandClasses()
{
return commands.values();
}
/**
* {@inheritDoc}
*/
public Command getCommand(String name)
throws Exception
{
if(!containsCommand(name)){
throw new RuntimeException(
Services.getMessage("command.not.found", name));
}
Class<? extends Command> cc = commands.get(name);
return cc.newInstance();
}
/**
* {@inheritDoc}
*/
public boolean containsCommand(String name)
{
return commands.containsKey(name);
}
/**
* {@inheritDoc}
*/
public String getMessage(String key, Object... args)
{
ResourceBundle bundle = getResourceBundle();
String message = bundle.getString(key);
return MessageFormat.format(message, args);
}
/**
* {@inheritDoc}
*/
public ResourceBundle getResourceBundle()
{
if (bundle == null){
bundle = ResourceBundle.getBundle(
getBundleBaseName(), Locale.getDefault(), getClass().getClassLoader());
}
return bundle;
}
/**
* {@inheritDoc}
*/
public String getProperty(String name)
{
return getProperty(name, null);
}
/**
* {@inheritDoc}
*/
public String getProperty(String name, String defaultValue)
{
if (properties == null){
properties = new Properties();
try{
properties.load(getClass().getResourceAsStream(PLUGIN_PROPERTIES));
}catch(Exception e){
logger.warn(
"Error loading plugin.properties for plugin '" + getName() + "'", e);
}
}
return System.getProperty(name, properties.getProperty(name, defaultValue));
}
/**
* {@inheritDoc}
*/
public URL getResource(String resource)
{
// short circuit resources we know are missing
if (missingResources.contains(resource)){
return null;
}
try{
// try vim resources first
// Ex: ~/.eclim/resources/jdt/templates/logger.gst
String localResource = resource;
// inject the pluginName ("jdt", "wst", etc)
int index = localResource.indexOf("resources");
if(index != -1){
localResource = FileUtils.concat(
localResource.substring(0, index + 9),
pluginName,
localResource.substring(index + 9));
}
String file = FileUtils.concat(Services.DOT_ECLIM, localResource);
if (new File(file).exists()){
return new URL("file://" + FileUtils.separatorsToUnix(file));
}
// next try plugin resources
URL url = getClass().getResource(resource);
if (url != null){
// convert any eclipse specific url to a native java one.
return FileLocator.resolve(url);
}
// not found
missingResources.add(resource);
logger.debug(
"Unable to locate resource in '" + getName() + "': " + resource);
return null;
}catch(Exception e){
throw new RuntimeException(e);
}
}
/**
* {@inheritDoc}
*/
public InputStream getResourceAsStream(String resource)
{
try{
URL url = getResource(resource);
if (url != null){
return url.openStream();
}
return null;
}catch(Exception e){
throw new RuntimeException(e);
}
}
/**
* {@inheritDoc}
*/
public void close()
throws Exception
{
}
/**
* {@inheritDoc}
* @see PluginResources#registerCommand(Class)
*/
public void registerCommand(Class<? extends Command> command)
{
org.eclim.annotation.Command info = (org.eclim.annotation.Command)
command.getAnnotation(org.eclim.annotation.Command.class);
if(info != null){
commands.put(info.name(), command);
}else{
logger.error(Services.getMessage("command.missing.annotation", command));
}
}
/**
* Gets the base name used to lookup the plugin's ResourceBundle.
*
* @return The ResourceBundle base name.
*/
protected abstract String getBundleBaseName();
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object other)
{
return ((PluginResources)other).getName().equals(getName());
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode()
{
return getName().hashCode();
}
}