/*
* File : CategoryImpl.java
* Created : 09 feb. 2004
* By : TuxPaper
*
* Azureus - a Java Bittorrent client
*
* 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.
*
* 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 ( see the LICENSE file ).
*
* 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
*/
package org.gudy.azureus2.core3.category.impl;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.gudy.azureus2.core3.category.Category;
import org.gudy.azureus2.core3.category.CategoryListener;
import org.gudy.azureus2.core3.download.*;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.IndentWriter;
import org.gudy.azureus2.core3.util.ListenerManager;
import org.gudy.azureus2.core3.util.ListenerManagerDispatcher;
import com.aelitis.azureus.core.AzureusCore;
import com.aelitis.azureus.core.AzureusCoreFactory;
import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
import com.aelitis.azureus.core.tag.TagDownload;
import com.aelitis.azureus.core.tag.TagFeatureRunState;
import com.aelitis.azureus.core.tag.Taggable;
import com.aelitis.azureus.core.tag.impl.TagBase;
import com.aelitis.azureus.core.util.IdentityHashSet;
public class
CategoryImpl
extends TagBase
implements Category, Comparable, TagDownload
{
private String sName;
private int type;
private List<DownloadManager> managers = new ArrayList<DownloadManager>();
private int upload_speed;
private int download_speed;
private Object UPLOAD_PRIORITY_KEY = new Object();
private final Map<String,String> attributes;
private static AtomicInteger tag_ids = new AtomicInteger();
private LimitedRateGroup upload_limiter =
new LimitedRateGroup()
{
public String
getName()
{
return( "cat_up: " + sName);
}
public int
getRateLimitBytesPerSecond()
{
return( upload_speed );
}
public void
updateBytesUsed(
int used )
{
}
};
private LimitedRateGroup download_limiter =
new LimitedRateGroup()
{
public String
getName()
{
return( "cat_down: " + sName);
}
public int
getRateLimitBytesPerSecond()
{
return( download_speed );
}
public void
updateBytesUsed(
int used )
{
}
};
private static final int LDT_CATEGORY_DMADDED = 1;
private static final int LDT_CATEGORY_DMREMOVED = 2;
private ListenerManager<CategoryListener> category_listeners = ListenerManager.createManager(
"CatListenDispatcher",
new ListenerManagerDispatcher<CategoryListener>()
{
public void
dispatch(
CategoryListener target,
int type,
Object value )
{
if ( type == LDT_CATEGORY_DMADDED )
target.downloadManagerAdded((Category) CategoryImpl.this, (DownloadManager)value);
else if ( type == LDT_CATEGORY_DMREMOVED )
target.downloadManagerRemoved(CategoryImpl.this, (DownloadManager)value);
}
});
public CategoryImpl(CategoryManagerImpl manager, String sName, int maxup, int maxdown, Map<String,String> _attributes ) {
super( manager, tag_ids.incrementAndGet(), sName );
addTag();
this.sName = sName;
this.type = Category.TYPE_USER;
upload_speed = maxup;
download_speed = maxdown;
attributes = _attributes;
}
public CategoryImpl(CategoryManagerImpl manager, String sName, int type, Map<String,String> _attributes) {
super( manager, tag_ids.incrementAndGet(), sName);
addTag();
this.sName = sName;
this.type = type;
attributes = _attributes;
}
public void addCategoryListener(CategoryListener l) {
category_listeners.addListener( l );
}
public void removeCategoryListener(CategoryListener l) {
category_listeners.removeListener( l );
}
public boolean
hasCategoryListener(
CategoryListener l )
{
return( category_listeners.hasListener( l ));
}
public String getName() {
return sName;
}
public int getType() {
return type;
}
public List<DownloadManager> getDownloadManagers(List<DownloadManager> all_dms) {
if ( type == Category.TYPE_USER ){
return managers;
}else if ( type == Category.TYPE_ALL || all_dms == null ){
return all_dms;
}else{
List<DownloadManager> result = new ArrayList<DownloadManager>();
for (int i=0;i<all_dms.size();i++){
DownloadManager dm = all_dms.get(i);
Category cat = dm.getDownloadState().getCategory();
if ( cat == null || cat.getType() == Category.TYPE_UNCATEGORIZED){
result.add( dm );
}
}
return( result );
}
}
public void addManager(DownloadManagerState manager_state) {
Category manager_cat = manager_state.getCategory();
if ((type != Category.TYPE_UNCATEGORIZED && manager_cat != this)
|| (type == Category.TYPE_UNCATEGORIZED && manager_cat != null)) {
manager_state.setCategory(this);
// we will be called again by CategoryManager.categoryChange
return;
}
DownloadManager manager = manager_state.getDownloadManager();
// can be null if called during downloadmanagerstate construction
if ( manager == null ){
return;
}
addTaggable( manager );
if (!managers.contains(manager)) {
if (type == Category.TYPE_USER) {
managers.add(manager);
}
manager.addRateLimiter( upload_limiter, true );
manager.addRateLimiter( download_limiter, false );
int pri = getIntAttribute( AT_UPLOAD_PRIORITY, -1 );
if ( pri > 0 ){
// another call-during-construction issue to avoid here
if ( manager.getDownloadState() != null ){
manager.updateAutoUploadPriority( UPLOAD_PRIORITY_KEY, true );
}
}
category_listeners.dispatch(LDT_CATEGORY_DMADDED, manager);
}
}
public void removeManager(DownloadManagerState manager_state) {
if (manager_state.getCategory() == this) {
manager_state.setCategory(null);
// we will be called again by CategoryManager.categoryChange
return;
}
DownloadManager manager = manager_state.getDownloadManager();
// can be null if called during downloadmanagerstate construction
if ( manager == null ){
return;
}
removeTaggable( manager );
if (type != Category.TYPE_USER || managers.contains(manager)) {
managers.remove(manager);
manager.removeRateLimiter( upload_limiter, true );
manager.removeRateLimiter( download_limiter, false );
int pri = getIntAttribute( AT_UPLOAD_PRIORITY, -1 );
if ( pri > 0 ){
// another call-during-construction issue to avoid here
if ( manager.getDownloadState() != null ){
manager.updateAutoUploadPriority( UPLOAD_PRIORITY_KEY, false );
}
}
category_listeners.dispatch( LDT_CATEGORY_DMREMOVED, manager );
}
}
public void
setDownloadSpeed(
int speed )
{
if ( download_speed != speed ){
download_speed = speed;
CategoryManagerImpl.getInstance().saveCategories(this);
}
}
public int
getDownloadSpeed()
{
return( download_speed );
}
public void
setUploadSpeed(
int speed )
{
if ( upload_speed != speed ){
upload_speed = speed;
CategoryManagerImpl.getInstance().saveCategories(this);
}
}
public int
getUploadSpeed()
{
return( upload_speed );
}
protected void
setAttributes(
Map<String,String> a )
{
attributes.clear();
attributes.putAll( a );
}
protected Map<String,String>
getAttributes()
{
return( attributes );
}
public String
getStringAttribute(
String name )
{
return( attributes.get(name));
}
public void
setStringAttribute(
String name,
String value )
{
String old = attributes.put( name, value );
if ( old == null || !old.equals( value )){
CategoryManagerImpl.getInstance().saveCategories(this);
}
}
public int
getIntAttribute(
String name )
{
return( getIntAttribute( name, 0 ));
}
private int
getIntAttribute(
String name,
int def )
{
String str = getStringAttribute( name );
if ( str == null ){
return( def );
}
return( Integer.parseInt( str ));
}
public void
setIntAttribute(
String name,
int value )
{
String str_val = String.valueOf( value );
String old = attributes.put( name, str_val );
if ( old == null || !old.equals( str_val )){
if ( name.equals( AT_UPLOAD_PRIORITY )){
for ( DownloadManager dm: managers ){
dm.updateAutoUploadPriority( UPLOAD_PRIORITY_KEY, value > 0 );
}
}
CategoryManagerImpl.getInstance().saveCategories(this);
}
}
public boolean
getBooleanAttribute(
String name )
{
String str = getStringAttribute( name );
return( str != null && str.equals( "true" ));
}
public void
setBooleanAttribute(
String name,
boolean value )
{
String str_val = value?"true":"false";
String old = attributes.put( name, str_val );
if ( old == null || !old.equals( str_val )){
CategoryManagerImpl.getInstance().saveCategories(this);
}
}
public int
getTaggableTypes()
{
return( Taggable.TT_DOWNLOAD );
}
public String
getTagName(
boolean localize )
{
if ( localize ){
if ( type == Category.TYPE_ALL || type == Category.TYPE_UNCATEGORIZED){
return( MessageText.getString( getTagNameRaw()));
}
}
return( super.getTagName(localize));
}
public boolean
supportsTagRates()
{
return( false );
}
public boolean
supportsTagUploadLimit()
{
return( true );
}
public boolean
supportsTagDownloadLimit()
{
return( true );
}
public int
getTagUploadLimit()
{
return( getUploadSpeed());
}
public void
setTagUploadLimit(
int bps )
{
setUploadSpeed( bps );
}
public int
getTagCurrentUploadRate()
{
return( -1 );
}
public int
getTagDownloadLimit()
{
return( getDownloadSpeed());
}
public void
setTagDownloadLimit(
int bps )
{
setDownloadSpeed( bps );
}
public int
getTagCurrentDownloadRate()
{
return( -1 );
}
public int
getTagUploadPriority()
{
if ( type == Category.TYPE_USER ){
return( getIntAttribute( AT_UPLOAD_PRIORITY ));
}else{
return( -1 );
}
}
public void
setTagUploadPriority(
int priority )
{
setIntAttribute( AT_UPLOAD_PRIORITY, priority );
}
public boolean
getCanBePublicDefault()
{
return( type == Category.TYPE_USER );
}
public boolean
supportsTagTranscode()
{
return( false );
}
public String[]
getTagTranscodeTarget()
{
return( null );
}
public void
setTagTranscodeTarget(
String uid,
String display_name )
{
}
public Set<DownloadManager>
getTaggedDownloads()
{
AzureusCore core = AzureusCoreFactory.getSingleton();
if (!core.isStarted()) {
return new IdentityHashSet<DownloadManager>();
}
return( new IdentityHashSet<DownloadManager>(getDownloadManagers( core.getGlobalManager().getDownloadManagers())));
}
public Set<Taggable>
getTagged()
{
return((Set<Taggable>)(Object)( getTaggedDownloads()));
}
public int
getTaggedCount()
{
return( getTagged().size());
}
public boolean
hasTaggable(
Taggable t )
{
return( getTagged().contains( t ));
}
public int
getRunStateCapabilities()
{
return( TagFeatureRunState.RSC_NONE );
}
public boolean
hasRunStateCapability(
int capability )
{
return( false );
}
public boolean[]
getPerformableOperations(
int[] ops )
{
return( new boolean[ ops.length]);
}
public void
performOperation(
int op )
{
Debug.out( "derp" );
}
protected void
destroy()
{
removeTag();
}
public int compareTo(Object b)
{
boolean aTypeIsUser = type == Category.TYPE_USER;
boolean bTypeIsUser = ((Category)b).getType() == Category.TYPE_USER;
if (aTypeIsUser == bTypeIsUser)
return sName.compareToIgnoreCase(((Category)b).getName());
if (aTypeIsUser)
return 1;
return -1;
}
public void dump(IndentWriter writer) {
if ( upload_speed != 0 ){
writer.println( "up=" + upload_speed );
}
if ( download_speed != 0 ){
writer.println( "down=" + download_speed );
}
if ( attributes.size() > 0 ){
writer.println( "attributes: " + attributes );
}
}
}