// jDownloader - Downloadmanager // Copyright (C) 2009 JD-Team support@jdownloader.org // // 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.milipede.storage.layer.internal; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.TreeMap; import javax.swing.Timer; //import org.milipede.api.config.Configuration; //import org.milipede.api.config.SubConfiguration; //import org.milipede.api.event.JDBroadcaster; //import jd.gui.swing.components.Balloon; import org.milipede.storage.layer.AccountControllerService; import org.milipede.storage.layer.domain.Account; import org.milipede.storage.layer.domain.AccountInfo; import org.millipede.router.vo.ProviderVO; //import org.milipede.api.plugins.ProviderVO; //import jd.utils.JDTheme; //import org.milipede.api.utils.MilipedeUtilities; //import org.milipede.api.controlling.MilipedeLogger; //import org.milipede.controller.internal.MilipedeController; //import org.milipede.jm.event.JDBroadcaster; public class AccountController implements AccountControllerService { //extends SubConfiguration implements ActionListener, AccountControllerListener, AccountControllerService { private static final long serialVersionUID = -7560087582989096645L; // Account <-- uses AccountInfo (specific to JDownloader) // Create a AccountInfo for every storagetype private static TreeMap<String, ArrayList<Account>> hosteraccounts = null; // private static AccountControllerService INSTANCE = null; // JDBroadCaster dep eleminated through OSGi Event Mechanism // private JDBroadcaster<AccountControllerListener, AccountControllerEvent> broadcaster = new JDBroadcaster<AccountControllerListener, AccountControllerEvent>() { // // @Override // protected void fireEvent(AccountControllerListener listener, AccountControllerEvent event) { // listener.onAccountControllerEvent(event); // } // // }; private Timer asyncSaveIntervalTimer; private boolean saveinprogress = false; private long lastballoon = 0; private long waittimeAccountInfoUpdate = 15 * 60 * 1000l; private final long ballooninterval = 30 * 60 * 1000l; /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#getUpdateTime() */ public long getUpdateTime() { return waittimeAccountInfoUpdate; } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#setUpdateTime(long) */ public void setUpdateTime(long time) { this.waittimeAccountInfoUpdate = time; } private static Comparator<Account> COMPARE_MOST_TRAFFIC_LEFT = new Comparator<Account>() { public int compare(Account o1, Account o2) { AccountInfo ai1 = o1.getAccountInfo(); AccountInfo ai2 = o2.getAccountInfo(); if (ai1 != null && ai2 != null) { if (ai1.getTrafficLeft() < ai2.getTrafficLeft()) { return -1; } else { return 1; } } return 0; } }; public AccountController() { // private AccountController() { // super("AccountController"); // asyncSaveIntervalTimer = new Timer(2000, this); asyncSaveIntervalTimer.setInitialDelay(2000); asyncSaveIntervalTimer.setRepeats(false); hosteraccounts = loadAccounts(); // broadcaster.addListener(this); } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#updateAccountInfo(org.milipede.api.plugin.ProviderVO, org.milipede.storage.layer.domain.Account, boolean) */ public AccountInfo updateAccountInfo(ProviderVO host, Account account, boolean forceupdate) { return updateAccountInfo(host.getTitle(), account, forceupdate); } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#updateAccountInfo(java.lang.String, org.milipede.storage.layer.domain.Account, boolean) */ public AccountInfo updateAccountInfo(String host, Account account, boolean forceupdate) { String hostname = host != null ? host : getHosterName(account); if (hostname == null) { account.setAccountInfo(null); // logger.severe("Cannot update AccountInfo, no Hostername available!"); return null; } // ProviderVO plugin = MilipedeUtilities.getNewProviderVOInstance(hostname); ProviderVO plugin = null; if (plugin == null) { account.setAccountInfo(null); // logger.severe("Cannot update AccountInfo, no HosterPlugin available!"); return null; } AccountInfo ai = account.getAccountInfo(); if (!forceupdate) { if (account.lastUpdateTime() != 0 && ai != null && ai.isExpired()) { /* account is expired, no need to update */ return ai; } if (!account.isValid() && account.lastUpdateTime() != 0) { /* account is invalid, no need to update */ return ai; } if ((System.currentTimeMillis() - account.lastUpdateTime()) < waittimeAccountInfoUpdate) { /* * account was checked before, timeout for recheck not reached, * no need to update */ return ai; } } try { account.setUpdateTime(System.currentTimeMillis()); /* not every plugin sets this info correct */ account.setValid(true); // ai = plugin.fetchAccountInfo(account); if (ai == null) { // System.out.println("plugin no update " + hostname); /* not every plugin has fetchAccountInfo */ account.setAccountInfo(null); // this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_UPDATE, hostname, account)); return null; } // synchronized (ACCOUNT_LOCK) { // account.setAccountInfo(ai); // } if (ai.isExpired()) { account.setEnabled(false); // this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_EXPIRED, hostname, account)); } else if (!account.isValid()) { account.setEnabled(false); // this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_INVALID, hostname, account)); } // else { // this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_UPDATE, hostname, account)); // } // } catch (IOException e) { // logger.severe("AccountUpdate: " + host + " failed!"); } catch (Exception e) { // logger.severe("AccountUpdate: " + host + " failed!"); // MilipedeLogger.exception(e); account.setAccountInfo(null); account.setEnabled(false); account.setValid(false); // this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_INVALID, hostname, account)); } return ai; } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#getHosterName(org.milipede.storage.layer.domain.Account) */ public String getHosterName(Account account) { if (account.getHoster() != null) return account.getHoster(); synchronized (hosteraccounts) { for (String host : hosteraccounts.keySet()) { if (hosteraccounts.get(host).contains(account)) { account.setHoster(host); return host; } } } return null; } // public synchronized static AccountControllerService getInstance() { // if (INSTANCE == null) INSTANCE = new AccountController(); // return INSTANCE; // } // public void addListener(AccountControllerListener l) { // broadcaster.addListener(l); // } // public void removeListener(AccountControllerListener l) { // broadcaster.removeListener(l); // } private TreeMap<String, ArrayList<Account>> loadAccounts() { // return getGenericProperty("accountlist", new TreeMap<String, ArrayList<Account>>()); return null; } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#addAccount(org.milipede.api.plugin.ProviderVO, org.milipede.storage.layer.domain.Account) */ public void addAccount(ProviderVO ProviderVO, Account account) { String host = ProviderVO.getTitle(); addAccount(host, account); } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#hasAccounts(java.lang.String) */ public boolean hasAccounts(String host) { return !getAllAccounts(host).isEmpty(); } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#getAllAccounts(org.milipede.api.plugin.ProviderVO) */ public ArrayList<Account> getAllAccounts(ProviderVO ProviderVO) { if (ProviderVO == null) return new ArrayList<Account>(); return this.getAllAccounts(ProviderVO.getTitle()); } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#getAllAccounts(java.lang.String) */ public ArrayList<Account> getAllAccounts(String host) { if (host == null) return new ArrayList<Account>(); synchronized (hosteraccounts) { if (hosteraccounts.containsKey(host)) { return hosteraccounts.get(host); } else { ArrayList<Account> haccounts = new ArrayList<Account>(); hosteraccounts.put(host, haccounts); return haccounts; } } } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#validAccounts() */ public int validAccounts() { int count = 0; synchronized (hosteraccounts) { for (ArrayList<Account> accs : hosteraccounts.values()) { for (Account acc : accs) { if (acc.isEnabled()) count++; } } } return count; } private void addAccount(String host, Account account) { if (host == null) return; if (account == null) return; synchronized (hosteraccounts) { if (hosteraccounts.containsKey(host)) { ArrayList<Account> haccounts = hosteraccounts.get(host); synchronized (haccounts) { boolean b = haccounts.contains(account); if (!b) { boolean b2 = false; ArrayList<Account> temp = new ArrayList<Account>(haccounts); for (Account acc : temp) { if (acc.equals(account)) { b2 = true; break; } } if (!b2) { haccounts.add(account); b = true; } } // if (b) this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_ADDED, host, account)); } } else { ArrayList<Account> haccounts = new ArrayList<Account>(); haccounts.add(account); hosteraccounts.put(host, haccounts); // this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_ADDED, host, account)); } } } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#removeAccount(java.lang.String, org.milipede.storage.layer.domain.Account) */ public boolean removeAccount(String hostname, Account account) { if (account == null) return false; String host = hostname; if (host == null) host = getHosterName(account); if (host == null) return false; synchronized (hosteraccounts) { if (!hosteraccounts.containsKey(host)) return false; ArrayList<Account> haccounts = hosteraccounts.get(host); synchronized (haccounts) { boolean b = haccounts.remove(account); if (!b) { ArrayList<Account> temp = new ArrayList<Account>(haccounts); for (Account acc : temp) { if (acc.equals(account)) { account = acc; b = haccounts.remove(account); break; } } } // if (b) this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_REMOVED, host, account)); return b; } } } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#removeAccount(org.milipede.api.plugin.ProviderVO, org.milipede.storage.layer.domain.Account) */ public boolean removeAccount(ProviderVO ProviderVO, Account account) { if (account == null) return false; if (ProviderVO == null) return removeAccount((String) null, account); return removeAccount(ProviderVO.getTitle(), account); } public void actionPerformed(ActionEvent arg0) { if (arg0.getSource() == asyncSaveIntervalTimer) { saveSync(); } } // public void onAccountControllerEvent(AccountControllerEvent event) { // switch (event.getID()) { // case AccountControllerEvent.ACCOUNT_ADDED: // MilipedeUtilities.getConfiguration().setProperty(Configuration.PARAM_USE_GLOBAL_PREMIUM, true); // MilipedeUtilities.getConfiguration().save(); // saveAsync(); // break; // case AccountControllerEvent.ACCOUNT_REMOVED: // case AccountControllerEvent.ACCOUNT_UPDATE: // case AccountControllerEvent.ACCOUNT_EXPIRED: // case AccountControllerEvent.ACCOUNT_INVALID: // saveAsync(); // break; // default: // break; // } // } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#throwUpdateEvent(org.milipede.api.plugin.ProviderVO, org.milipede.storage.layer.domain.Account) */ public void throwUpdateEvent(ProviderVO ProviderVO, Account account) { if (ProviderVO != null) { // this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_UPDATE, ProviderVO.getHost(), account)); } else { // this.broadcaster.fireEvent(new AccountControllerEvent(this, AccountControllerEvent.ACCOUNT_UPDATE, null, account)); } } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#saveAsync() */ public void saveAsync() { if (saveinprogress == true) return; asyncSaveIntervalTimer.restart(); } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#saveSync() */ public void saveSync() { if (saveinprogress == true) return; new Thread() { @Override public void run() { saveSyncnonThread(); } }.start(); } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#saveSyncnonThread() */ public void saveSyncnonThread() { asyncSaveIntervalTimer.stop(); // String id = MilipedeController.requestDelayExit("accountcontroller"); synchronized (hosteraccounts) { saveinprogress = true; // save(); saveinprogress = false; } // MilipedeController.releaseDelayExit(id); } /* (non-Javadoc) * @see org.milipede.storage.layer.internal.AccountControllerService#getValidAccount(org.milipede.api.plugin.ProviderVO) */ public Account getValidAccount(ProviderVO ProviderVO) { Account ret = null; synchronized (hosteraccounts) { ArrayList<Account> accounts = new ArrayList<Account>(getAllAccounts(ProviderVO)); // if (getBooleanProperty(PROPERTY_ACCOUNT_SELECTION, true)) Collections.sort(accounts, COMPARE_MOST_TRAFFIC_LEFT); for (int i = 0; i < accounts.size(); i++) { Account next = accounts.get(i); if (!next.isTempDisabled() && next.isEnabled() && next.isValid()) { ret = next; break; } } } // if (ret != null && !MilipedeUtilities.getConfiguration().getBooleanProperty(Configuration.PARAM_USE_GLOBAL_PREMIUM, true)) { // if (System.currentTimeMillis() - lastballoon > ballooninterval) { // lastballoon = System.currentTimeMillis(); //// Balloon.show(JDL.L("gui.ballon.accountmanager.title", "Accountmanager"), JDTheme.II("gui.images.accounts", 32, 32), JDL.L("gui.accountcontroller.globpremdisabled", "Premiumaccounts are globally disabled!<br/>Click <a href='http://jdownloader.org/knowledge/wiki/gui/premiummenu'>here</a> for help.")); // } // ret = null; // } return ret; } }