/* * Created on 12-May-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.update; /** * @author parg * */ import java.util.*; import org.gudy.azureus2.core3.util.*; import org.gudy.azureus2.core3.logging.*; import org.gudy.azureus2.plugins.update.*; import org.gudy.azureus2.plugins.utils.resourcedownloader.*; public class UpdateCheckInstanceImpl implements UpdateCheckInstance { private static final LogIDs LOGID = LogIDs.CORE; private List listeners = new ArrayList(); private List updates = new ArrayList(); private List decision_listeners = new ArrayList(); private AESemaphore sem = new AESemaphore("UpdateCheckInstance"); private UpdateManager manager; private int check_type; private String name; private UpdatableComponentImpl[] components; private UpdateCheckerImpl[] checkers; private boolean completed; private boolean cancelled; private boolean automatic = true; protected AEMonitor this_mon = new AEMonitor( "UpdateCheckInstance" ); protected UpdateCheckInstanceImpl( UpdateManager _manager, int _check_type, String _name, UpdatableComponentImpl[] _components ) { manager = _manager; check_type = _check_type; name = _name; components = _components; checkers = new UpdateCheckerImpl[components.length]; for (int i=0;i<components.length;i++){ UpdatableComponentImpl comp = components[i]; checkers[i] = new UpdateCheckerImpl( this, comp, sem ); } } public int getType() { return( check_type ); } public String getName() { return( name ); } public void addUpdatableComponent( UpdatableComponent component, boolean mandatory ) { // add new component UpdatableComponentImpl comp = new UpdatableComponentImpl( component, mandatory ); UpdatableComponentImpl[] new_comps = new UpdatableComponentImpl[components.length+1]; System.arraycopy( components, 0, new_comps, 0, components.length ); new_comps[components.length] = comp; components = new_comps; // add a new checker UpdateCheckerImpl checker = new UpdateCheckerImpl( this, comp, sem ); UpdateCheckerImpl[] new_checkers = new UpdateCheckerImpl[checkers.length+1]; System.arraycopy( checkers, 0, new_checkers, 0, checkers.length ); new_checkers[checkers.length] = checker; checkers = new_checkers; } public void setAutomatic( boolean a ) { automatic = a; } public boolean isAutomatic() { return( automatic ); } public void start() { for (int i=0;i<components.length;i++){ final UpdateCheckerImpl checker = checkers[i]; Thread t = new AEThread( "UpdatableComponent Checker:" + i ) { public void runSupport() { try{ checker.getComponent().checkForUpdate( checker ); }catch( Throwable e ){ checker.failed(); } } }; t.setDaemon( true ); t.start(); } Thread t = new AEThread( "UpdatableComponent Completion Waiter" ) { public void runSupport() { for (int i=0;i<components.length;i++){ sem.reserve(); } try{ this_mon.enter(); if ( cancelled ){ return; } completed = true; }finally{ this_mon.exit(); } boolean mandatory_failed = false; for (int i=0;i<checkers.length;i++){ if ( components[i].isMandatory() && checkers[i].getFailed()){ mandatory_failed = true; break; } } List target_updates = new ArrayList(); // if any mandatory checks failed then we can't do any more if ( mandatory_failed ){ if (Logger.isEnabled()) Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "Dropping all updates as a mandatory update check failed")); }else{ // If there are any manadatory updates then we just go ahead with them and drop the rest boolean mandatory_only = false; for (int i=0;i<updates.size();i++){ UpdateImpl update = (UpdateImpl)updates.get(i); if ( update.isMandatory()){ mandatory_only = true; break; } } for (int i=0;i<updates.size();i++){ UpdateImpl update = (UpdateImpl)updates.get(i); if ( update.isMandatory() || !mandatory_only ){ target_updates.add( update ); }else{ if (Logger.isEnabled()) Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "Dropping update '" + update.getName() + "' as non-mandatory and " + "mandatory updates found")); } } } updates = target_updates; for (int i=0;i<listeners.size();i++){ try{ ((UpdateCheckInstanceListener)listeners.get(i)).complete( UpdateCheckInstanceImpl.this ); }catch( Throwable e ){ Debug.printStackTrace(e); } } } }; t.setDaemon(true); t.start(); } protected UpdateImpl addUpdate( UpdatableComponentImpl comp, String update_name, String[] desc, String new_version, ResourceDownloader[] downloaders, int restart_required ) { try{ this_mon.enter(); UpdateImpl update = new UpdateImpl( this, update_name, desc, new_version, downloaders, comp.isMandatory(), restart_required ); updates.add( update ); if ( cancelled ){ update.cancel(); } return( update ); }finally{ this_mon.exit(); } } public Update[] getUpdates() { try{ this_mon.enter(); Update[] res = new Update[updates.size()]; updates.toArray( res ); return( res ); }finally{ this_mon.exit(); } } public UpdateChecker[] getCheckers() { return( checkers ); } public UpdateInstaller createInstaller() throws UpdateException { return( manager.createInstaller()); } public void cancel() { boolean just_do_updates = false; try{ this_mon.enter(); if ( completed ){ just_do_updates = true; } cancelled = true; }finally{ this_mon.exit(); } for (int i=0;i<updates.size();i++){ ((UpdateImpl)updates.get(i)).cancel(); } if ( !just_do_updates ){ for (int i=0;i<checkers.length;i++){ if ( checkers[i] != null ){ checkers[i].cancel(); } } for (int i=0;i<listeners.size();i++){ try{ ((UpdateCheckInstanceListener)listeners.get(i)).cancelled( this ); }catch( Throwable e ){ Debug.printStackTrace(e); } } } } public boolean isCancelled() { return( cancelled ); } public UpdateManager getManager() { return( manager ); } protected Object getDecision( Update update, int decision_type, String decision_name, String decision_description, Object decision_data ) { for (int i=0;i<decision_listeners.size();i++){ Object res = ((UpdateManagerDecisionListener)decision_listeners.get(i)).decide( update, decision_type, decision_name, decision_description, decision_data ); if ( res != null ){ return( res ); } } return( null ); } public void addDecisionListener( UpdateManagerDecisionListener l ) { decision_listeners.add(l); } public void removeDecisionListener( UpdateManagerDecisionListener l ) { decision_listeners.remove(l); } public void addListener( UpdateCheckInstanceListener l ) { listeners.add( l ); if ( completed ){ l.complete( this ); }else if ( cancelled ){ l.cancelled( this ); } } public void removeListener( UpdateCheckInstanceListener l ) { listeners.remove(l); } }