/*
* Created on 30-Nov-2004
* Created by Paul Gardner
* Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package org.gudy.azureus2.pluginsimpl.local.installer;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.plugins.Plugin;
import org.gudy.azureus2.plugins.PluginException;
import org.gudy.azureus2.plugins.PluginInterface;
import org.gudy.azureus2.plugins.installer.FilePluginInstaller;
import org.gudy.azureus2.plugins.update.UpdatableComponent;
import org.gudy.azureus2.plugins.update.Update;
import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
import org.gudy.azureus2.plugins.update.UpdateChecker;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
import org.gudy.azureus2.pluginsimpl.update.PluginUpdatePlugin;
import org.gudy.azureus2.pluginsimpl.update.sf.SFPluginDetailsLoader;
import org.gudy.azureus2.pluginsimpl.update.sf.SFPluginDetailsLoaderFactory;
/**
* @author parg
*
*/
public class
FilePluginInstallerImpl
extends InstallablePluginImpl
implements FilePluginInstaller
{
protected PluginInstallerImpl installer;
protected File file;
protected String id;
protected String version;
protected String name;
protected boolean is_jar;
protected
FilePluginInstallerImpl(
PluginInstallerImpl _installer,
File _file )
throws PluginException
{
super( _installer );
installer = _installer;
file = _file;
String name = file.getName();
int pos = name.lastIndexOf( "." );
boolean ok = false;
if ( pos != -1 ){
String prefix = name.substring(0,pos);
String suffix = name.substring(pos+1);
// If the name part contains "_src" in it, then strip it out,
// it'll just cause us more hassle to deal with it later.
if (prefix.lastIndexOf("_src") != -1) {
if (prefix.endsWith("_src")) {
prefix = prefix.substring(0, prefix.length()-4);
}
else {
int src_bit_pos = prefix.lastIndexOf("_src");
prefix = prefix.substring(0, src_bit_pos) + prefix.substring(src_bit_pos+1);
}
}
if ( suffix.toLowerCase(MessageText.LOCALE_ENGLISH).equals( "jar") ||
suffix.toLowerCase(MessageText.LOCALE_ENGLISH).equals( "zip" )){
is_jar = suffix.toLowerCase(MessageText.LOCALE_ENGLISH).equals( "jar");
// See if we can get at the plugin.properties in the file
Properties properties = null;
ZipInputStream zis = null;
try{
zis =
new ZipInputStream(
new BufferedInputStream( new FileInputStream( file ) ));
while( properties == null ){
ZipEntry entry = zis.getNextEntry();
if ( entry == null ){
break;
}
String zip_name = entry.getName().toLowerCase( MessageText.LOCALE_ENGLISH );
// System.out.println( "zis1:" + zip_name );
if ( zip_name.equals( "plugin.properties" ) || zip_name.endsWith( "/plugin.properties")){
properties = new Properties();
properties.load( zis );
}else if ( zip_name.endsWith( ".jar" )){
ZipInputStream zis2 = new ZipInputStream( zis );
while( properties == null ){
ZipEntry entry2 = zis2.getNextEntry();
if ( entry2 == null ){
break;
}
String zip_name2 = entry2.getName().toLowerCase( MessageText.LOCALE_ENGLISH );
// System.out.println( " zis2:" + zip_name2 );
if ( zip_name2.equals( "plugin.properties" )){
properties = new Properties();
properties.load( zis2 );
}
}
}
}
}catch( Throwable e ){
throw( new PluginException( "Failed to read plugin file", e ));
}finally{
if ( zis != null ){
try{
zis.close();
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
pos = prefix.lastIndexOf("_");
String filename_id = null, filename_version = null;
if ( pos != -1 ){
filename_id = prefix.substring(0,pos);
filename_version = prefix.substring(pos+1);
}
if ( properties == null ){
// one valid possibility here, this is a built-in plugin. this doesn't have
// a plugin.properties
if (filename_id != null) {
id = filename_id;
version = filename_version;
PluginInterface pi = installer.getPluginManager().getPluginInterfaceByID( id );
ok = pi != null &&
( pi.getPluginDirectoryName() == null ||
pi.getPluginDirectoryName().length() == 0 );
}
if ( !ok ){
throw( new PluginException( "Mandatory file 'plugin.properties' not found in plugin file" ));
}
}else{ // properties != null
// unfortunately plugin.id isn't mandatory for the properties, and neither is plugin.version
PluginInitializer.checkJDKVersion( "", properties, false );
PluginInitializer.checkAzureusVersion("", properties, false);
id = properties.getProperty( "plugin.id" );
version = properties.getProperty( "plugin.version" );
// Force both versions to be the same if they are both defined.
String prop_version = version;
if (prop_version != null && filename_version != null && !filename_version.equals(prop_version)) {
throw new PluginException("inconsistent versions [file=" + filename_version + ", prop=" + prop_version + "]");
}
}
if ( id == null ){
// see if plugin is already loaded, if so we can get the id from it
String plugin_class = properties.getProperty("plugin.class");
if ( plugin_class == null ){
String plugin_classes = properties.getProperty( "plugin.classes" );
if ( plugin_classes != null ){
int semi_pos = plugin_classes.indexOf(";");
if ( semi_pos == -1 ){
plugin_class = plugin_classes;
}else{
plugin_class = plugin_classes.substring( 0, semi_pos );
}
}
}
if ( plugin_class != null ){
try{
PluginInterface pi = installer.getPluginManager().getPluginInterfaceByClass( plugin_class );
if ( pi != null ){
id = pi.getPluginID();
}
}catch( Throwable ignore ){
}
}
}
pos = prefix.lastIndexOf("_");
if ( pos != -1 ){
id = id==null?prefix.substring(0,pos):id;
// see if we can normalise the ID based on SF values
try{
SFPluginDetailsLoader loader = SFPluginDetailsLoaderFactory.getSingleton();
String[] ids = loader.getPluginIDs();
for (int i=0;i<ids.length;i++){
if ( ids[i].equalsIgnoreCase(id)){
id = ids[i];
break;
}
}
}catch( Throwable e ){
Debug.printStackTrace(e);
}
version = version == null?prefix.substring(pos+1):version;
}
this.name = id;
if ( properties != null ){
String plugin_name = properties.getProperty( "plugin.name" );
if ( plugin_name != null ){
this.name = plugin_name;
}
}
ok = id != null && version != null;
}
}
if ( !ok ){
throw( new PluginException( "Invalid plugin file name: must be of form <pluginid>_<version>.[jar|zip]" ));
}
}
public File
getFile()
{
return( file );
}
public String
getId()
{
return( id );
}
public String
getVersion()
{
return( version );
}
public String
getName()
{
return( name );
}
public String
getDescription()
{
return( file.toString());
}
public String
getRelativeURLBase()
{
return( "" );
}
public void
addUpdate(
UpdateCheckInstance inst,
final PluginUpdatePlugin plugin_update_plugin,
final Plugin plugin,
final PluginInterface plugin_interface )
{
inst.addUpdatableComponent(
new UpdatableComponent()
{
public String
getName()
{
return( name );
}
public int
getMaximumCheckTime()
{
return( 0 );
}
public void
checkForUpdate(
UpdateChecker checker )
{
try{
ResourceDownloader rd =
plugin_interface.getUtilities().getResourceDownloaderFactory().create( file );
plugin_update_plugin.addUpdate(
plugin_interface,
checker,
getName(),
new String[]{"Installation from file: " + file.toString()},
version,
rd,
is_jar,
plugin_interface.getPluginState().isUnloadable()?Update.RESTART_REQUIRED_NO:Update.RESTART_REQUIRED_YES,
false );
}finally{
checker.completed();
}
}
}, false );
}
}