package com.aelitis.azureus.ui.swt.mdi;
import java.util.*;
import java.util.regex.Pattern;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.download.DownloadManager;
import org.gudy.azureus2.core3.global.GlobalManager;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper;
import org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.IViewInfo;
import org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.PluginAddedViewListener;
import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
import com.aelitis.azureus.core.AzureusCore;
import com.aelitis.azureus.core.AzureusCoreFactory;
import com.aelitis.azureus.core.AzureusCoreRunningListener;
import com.aelitis.azureus.ui.common.updater.UIUpdatable;
import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
import com.aelitis.azureus.ui.mdi.*;
import com.aelitis.azureus.ui.skin.SkinConstants;
import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
import com.aelitis.azureus.ui.swt.views.skin.SkinView;
import com.aelitis.azureus.util.ConstantsVuze;
import com.aelitis.azureus.util.ContentNetworkUtils;
import com.aelitis.azureus.util.MapUtils;
public abstract class BaseMDI
extends SkinView
implements MultipleDocumentInterfaceSWT, UIUpdatable
{
protected MdiEntrySWT currentEntry;
private Map<String, MdiEntryCreationListener> mapIdToCreationListener = new LightHashMap<String, MdiEntryCreationListener>();
private Map<String, MdiEntryCreationListener2> mapIdToCreationListener2 = new LightHashMap<String, MdiEntryCreationListener2>();
// Sync changes to entry maps on mapIdEntry
protected Map<String, MdiEntrySWT> mapIdToEntry = new LightHashMap<String, MdiEntrySWT>();
private List<MdiListener> listeners = new ArrayList<MdiListener>();
private List<MdiEntryLoadedListener> listLoadListeners = new ArrayList<MdiEntryLoadedListener>();
private static LinkedHashMap<String, Object> mapAutoOpen = new LinkedHashMap<String, Object>();
private String[] preferredOrder;
public void addListener(MdiListener l) {
synchronized (listeners) {
if (listeners.contains(l)) {
return;
}
listeners.add(l);
}
}
public void removeListener(MdiListener l) {
synchronized (listeners) {
listeners.remove(l);
}
}
public void addListener(MdiEntryLoadedListener l) {
synchronized (listLoadListeners) {
if (listLoadListeners.contains(l)) {
return;
}
listLoadListeners.add(l);
}
// might be a very rare thread issue here if entry gets loaded while
// we are walking through entries
MdiEntry[] entries = getEntries();
for (MdiEntry entry : entries) {
if (entry.isAdded()) {
l.mdiEntryLoaded(entry);
}
}
}
public void removeListener(MdiEntryLoadedListener l) {
synchronized (listLoadListeners) {
listLoadListeners.remove(l);
}
}
protected void triggerSelectionListener(MdiEntry newEntry, MdiEntry oldEntry) {
MdiListener[] array;
synchronized (listeners) {
array = listeners.toArray(new MdiListener[0]);
}
for (MdiListener l : array) {
try {
l.mdiEntrySelected(newEntry, oldEntry);
} catch (Exception e) {
Debug.out(e);
}
}
}
public void triggerEntryLoadedListeners(MdiEntry entry) {
MdiEntryLoadedListener[] array;
synchronized (listLoadListeners) {
array = listLoadListeners.toArray(new MdiEntryLoadedListener[0]);
}
for (MdiEntryLoadedListener l : array) {
try {
l.mdiEntryLoaded(entry);
} catch (Exception e) {
Debug.out(e);
}
}
}
public void closeEntry(final String id) {
MdiEntry entry = getEntry(id);
if (entry != null) {
entry.close(false);
} else {
removeEntryAutoOpen(id);
}
}
public abstract MdiEntry createEntryFromEventListener(String parentID,
UISWTViewEventListener l, String id, boolean closeable, Object datasource, String preferedAfterID);
public abstract MdiEntry createEntryFromView(String parentID, UISWTViewCore iview,
String id, Object datasource, boolean closeable, boolean show,
boolean expand);
public abstract MdiEntry createEntryFromSkinRef(String parentID, String id,
String configID, String title, ViewTitleInfo titleInfo, Object params,
boolean closeable, String preferedAfterID);
public MdiEntry getCurrentEntry() {
return currentEntry;
}
public MdiEntrySWT getCurrentEntrySWT() {
return currentEntry;
}
public MdiEntry[] getEntries() {
return mapIdToEntry.values().toArray(new MdiEntry[0]);
}
public MdiEntrySWT[] getEntriesSWT() {
return mapIdToEntry.values().toArray(new MdiEntrySWT[0]);
}
public MdiEntry getEntry(String id) {
if (SkinConstants.VIEWID_BROWSER_BROWSE.equalsIgnoreCase(id)) {
id = ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork());
}
MdiEntry entry = mapIdToEntry.get(id);
return entry;
}
public MdiEntrySWT getEntrySWT(String id) {
if (SkinConstants.VIEWID_BROWSER_BROWSE.equalsIgnoreCase(id)) {
id = ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork());
}
MdiEntrySWT entry = mapIdToEntry.get(id);
return entry;
}
/**
* @param skinView
* @return
*
* @since 3.1.1.1
*/
public MdiEntry getEntryBySkinView(Object skinView) {
SWTSkinObject so = ((SkinView)skinView).getMainSkinObject();
Object[] sideBarEntries = mapIdToEntry.values().toArray();
for (int i = 0; i < sideBarEntries.length; i++) {
//MdiEntrySWT entry = (MdiEntrySWT) sideBarEntries[i];
BaseMdiEntry entry = (BaseMdiEntry) sideBarEntries[i];
SWTSkinObject entrySO = entry.getSkinObject();
SWTSkinObject entrySOParent = entrySO == null ? entrySO
: entrySO.getParent();
if (entrySO == so || entrySO == so.getParent() || entrySOParent == so) {
return entry;
}
}
return null;
}
public UISWTViewCore getCoreViewFromID(String id) {
if (id == null) {
return null;
}
MdiEntrySWT entry = getEntrySWT(id);
if (entry == null) {
return null;
}
return entry.getCoreView();
}
public String getUpdateUIName() {
if (currentEntry == null || currentEntry.getView() == null) {
return "MDI";
}
return currentEntry.getView().getViewID();
}
public void registerEntry(String id, MdiEntryCreationListener2 l) {
mapIdToCreationListener2.put(id, l);
createIfAutoOpen(id);
}
private boolean createIfAutoOpen(String id) {
Object o = mapAutoOpen.get(id);
if (o instanceof Map<?, ?>) {
Map<?, ?> autoOpenMap = (Map<?, ?>) o;
return createEntryByCreationListener(id, autoOpenMap.get("datasource"), autoOpenMap) != null;
}
return false;
}
private MdiEntry createEntryByCreationListener(String id, Object ds, Map<?, ?> autoOpenMap) {
MdiEntryCreationListener mdiEntryCreationListener = null;
for (String key : mapIdToCreationListener.keySet()) {
if (Pattern.matches(key, id)) {
mdiEntryCreationListener = mapIdToCreationListener.get(key);
break;
}
}
if (mdiEntryCreationListener != null) {
try {
MdiEntry mdiEntry = mdiEntryCreationListener.createMDiEntry(id);
if (mdiEntry != null && ds != null) {
mdiEntry.setDatasource(ds);
}
return mdiEntry;
} catch (Exception e) {
Debug.out(e);
}
}
MdiEntryCreationListener2 mdiEntryCreationListener2 = null;
for (String key : mapIdToCreationListener2.keySet()) {
if (Pattern.matches(key, id)) {
mdiEntryCreationListener2 = mapIdToCreationListener2.get(key);
break;
}
}
if (mdiEntryCreationListener2 != null) {
try {
MdiEntry mdiEntry = mdiEntryCreationListener2.createMDiEntry(this, id, ds, autoOpenMap);
if (mdiEntry == null) {
removeEntryAutoOpen(id);
}
return mdiEntry;
} catch (Exception e) {
Debug.out(e);
}
}
setEntryAutoOpen(id, ds);
return null;
}
public void registerEntry(String id, MdiEntryCreationListener l) {
mapIdToCreationListener.put(id, l);
createIfAutoOpen(id);
}
public boolean showEntryByID(String id) {
return loadEntryByID(id, true);
}
@Override
public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
return null;
}
// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#skinObjectDestroyed(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
public Object skinObjectDestroyed(SWTSkinObject skinObject, Object params) {
MdiEntry entry = getCurrentEntry();
if (entry != null) {
COConfigurationManager.setParameter("v3.StartTab",
entry.getId());
String ds = entry.getExportableDatasource();
COConfigurationManager.setParameter("v3.StartTab.ds", ds == null ? null : ds.toString());
}
return super.skinObjectDestroyed(skinObject, params);
}
public void updateUI() {
MdiEntry currentEntry = getCurrentEntry();
if (currentEntry != null) {
currentEntry.updateUI();
}
}
// @see com.aelitis.azureus.ui.mdi.MultipleDocumentInterface#loadEntryByID(java.lang.String, boolean)
public boolean loadEntryByID(String id, boolean activate) {
return loadEntryByID(id, activate, false, null);
}
/* (non-Javadoc)
* @see com.aelitis.azureus.ui.mdi.MultipleDocumentInterface#loadEntryByID(java.lang.String, boolean, boolean)
*/
public boolean loadEntryByID(String id, boolean activate,
boolean onlyLoadOnce, Object datasource) {
if (id == null) {
return false;
}
MdiEntry entry = getEntry(id);
if (entry != null) {
if (datasource != null) {
entry.setDatasource(datasource);
}
if (activate) {
showEntry(entry);
}
return true;
}
@SuppressWarnings("deprecation")
boolean loadedOnce = wasEntryLoadedOnce(id);
if (loadedOnce && onlyLoadOnce) {
return false;
}
MdiEntry mdiEntry = createEntryByCreationListener(id, datasource, null);
if (mdiEntry != null) {
if (onlyLoadOnce) {
setEntryLoadedOnce(id);
}
if (activate) {
showEntry(mdiEntry);
}
return true;
}
return false;
}
protected abstract void setEntryLoadedOnce(String id);
protected abstract boolean wasEntryLoadedOnce(String id);
public boolean entryExists(String id) {
if (SkinConstants.VIEWID_BROWSER_BROWSE.equalsIgnoreCase(id)) {
id = ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork());
}
MdiEntry entry = mapIdToEntry.get(id);
if (entry == null) {
return false;
}
return entry.isAdded();
}
// @see com.aelitis.azureus.ui.mdi.MultipleDocumentInterface#setEntryAutoOpen(java.lang.String, java.lang.Object)
public void setEntryAutoOpen(String id, Object datasource) {
Map<String, Object> map = (Map<String, Object>) mapAutoOpen.get(id);
if (map == null) {
map = new LightHashMap<String, Object>(1);
}
map.put("datasource", datasource);
mapAutoOpen.put(id, map);
}
// @see com.aelitis.azureus.ui.mdi.MultipleDocumentInterface#removeEntryAutoOpen(java.lang.String)
public void removeEntryAutoOpen(String id) {
mapAutoOpen.remove(id);
}
protected void setupPluginViews() {
// When a new Plugin View is added, check out auto-open list to see if
// the user had it open
PluginsMenuHelper.getInstance().addPluginAddedViewListener(
new PluginAddedViewListener() {
// @see org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.PluginAddedViewListener#pluginViewAdded(org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.IViewInfo)
public void pluginViewAdded(IViewInfo viewInfo) {
//System.out.println("PluginView Added: " + viewInfo.viewID);
Object o = mapAutoOpen.get(viewInfo.viewID);
if (o instanceof Map<?, ?>) {
processAutoOpenMap(viewInfo.viewID, (Map<?, ?>) o, viewInfo);
}
}
});
}
public void informAutoOpenSet(MdiEntry entry, Map<String, Object> autoOpenInfo) {
mapAutoOpen.put(entry.getId(), autoOpenInfo);
}
public void loadCloseables() {
try{
Map<?,?> loadedMap = FileUtil.readResilientConfigFile("sidebarauto.config", true);
if (loadedMap.isEmpty()) {
return;
}
BDecoder.decodeStrings(loadedMap);
List<Map> orderedEntries = (List<Map>)loadedMap.get( "_entries_" );
if ( orderedEntries == null ){
// migrate old format
for (Iterator<?> iter = loadedMap.keySet().iterator(); iter.hasNext();) {
String id = (String) iter.next();
Object o = loadedMap.get(id);
if (o instanceof Map<?, ?>) {
if (!processAutoOpenMap(id, (Map<?, ?>) o, null)) {
mapAutoOpen.put(id, o);
}
}
}
}else{
for (Map map: orderedEntries){
String id = (String)map.get( "id" );
//System.out.println( "loaded " + id );
Object o = map.get( "value" );
if (o instanceof Map<?, ?>) {
if (!processAutoOpenMap(id, (Map<?, ?>) o, null)) {
mapAutoOpen.put(id, o);
}
}
}
}
}catch( Throwable e ){
Debug.out( e );
}
}
@SuppressWarnings({
"unchecked",
"rawtypes"
})
public void saveCloseables() {
try{
// update auto open info
for (Iterator<String> iter = new ArrayList<String>(mapAutoOpen.keySet()).iterator(); iter.hasNext();) {
String id = (String) iter.next();
MdiEntry entry = getEntry(id);
if ( entry != null && entry.isAdded()){
mapAutoOpen.put(id, entry.getAutoOpenInfo());
}else{
mapAutoOpen.remove(id);
}
}
Map map = new HashMap();
List<Map> list = new ArrayList<Map>( mapAutoOpen.size());
map.put( "_entries_", list );
for ( Map.Entry<String,Object> entry: mapAutoOpen.entrySet()){
Map m = new HashMap();
list.add( m );
String id = entry.getKey();
m.put( "id", id );
m.put( "value", entry.getValue());
//System.out.println( "saved " + id );
}
FileUtil.writeResilientConfigFile("sidebarauto.config", map );
}catch( Throwable e ){
Debug.out( e );
}
}
private boolean processAutoOpenMap(String id, Map<?, ?> autoOpenInfo,
IViewInfo viewInfo) {
try {
MdiEntry entry = getEntry(id);
if (entry != null) {
return true;
}
Object datasource = autoOpenInfo.get("datasource");
String title = MapUtils.getMapString(autoOpenInfo, "title", id);
MdiEntry mdiEntry = createEntryByCreationListener(id, datasource, autoOpenInfo);
if (mdiEntry != null) {
if (mdiEntry.getTitle().equals("")) {
mdiEntry.setTitle(title);
}
return true;
}
String parentID = MapUtils.getMapString(autoOpenInfo, "parentID", SIDEBAR_HEADER_PLUGINS);
if (viewInfo != null) {
if (viewInfo.view != null) {
entry = createEntryFromView(parentID, viewInfo.view, id, datasource,
true, false, true);
} else if (viewInfo.event_listener != null) {
entry = createEntryFromEventListener(parentID,
viewInfo.event_listener, id, true, datasource,null);
entry.setTitle(title);
}
}
if (entry != null && datasource == null) {
final MdiEntry fEntry = entry;
final String dmHash = MapUtils.getMapString(autoOpenInfo, "dm", null);
if (dmHash != null) {
AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
public void azureusCoreRunning(AzureusCore core) {
GlobalManager gm = core.getGlobalManager();
HashWrapper hw = new HashWrapper(Base32.decode(dmHash));
DownloadManager dm = gm.getDownloadManager(hw);
if (dm != null) {
fEntry.setDatasource(dm);
}
}
});
} else {
final List<?> listHashes = MapUtils.getMapList(autoOpenInfo, "dms",
null);
if (listHashes != null) {
AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
public void azureusCoreRunning(AzureusCore core) {
List<DownloadManager> listDMS = new ArrayList<DownloadManager>(
1);
GlobalManager gm = core.getGlobalManager();
for (Object oDM : listHashes) {
if (oDM instanceof String) {
String hash = (String) oDM;
DownloadManager dm = gm.getDownloadManager(new HashWrapper(
Base32.decode(hash)));
if (dm != null) {
listDMS.add(dm);
}
}
fEntry.setDatasource(listDMS.toArray(new DownloadManager[0]));
}
}
});
}
}
}
return entry != null;
} catch (Throwable e) {
Debug.out(e);
}
return false;
}
public void removeItem(MdiEntry entry) {
String id = entry.getId();
synchronized (mapIdToEntry) {
mapIdToEntry.remove(id);
removeChildrenOf(id);
}
}
private void removeChildrenOf(String id) {
if (id == null) {
return;
}
synchronized (mapIdToEntry) {
MdiEntrySWT[] entriesSWT = getEntriesSWT();
for (MdiEntrySWT entry : entriesSWT) {
if (id.equals(entry.getParentID())) {
mapIdToEntry.remove(entry);
removeChildrenOf(entry.getId());
}
}
}
}
public List<MdiEntry> getChildrenOf(String id) {
if (id == null) {
return Collections.emptyList();
}
List<MdiEntry> list = new ArrayList<MdiEntry>(1);
synchronized (mapIdToEntry) {
MdiEntrySWT[] entriesSWT = getEntriesSWT();
for (MdiEntrySWT entry : entriesSWT) {
if (id.equals(entry.getParentID())) {
list.add(entry);
}
}
}
return list;
}
public Object updateLanguage(SWTSkinObject skinObject, Object params) {
MdiEntry[] entries = getEntries();
for (MdiEntry entry : entries) {
if (entry instanceof BaseMdiEntry) {
BaseMdiEntry baseEntry = (BaseMdiEntry) entry;
baseEntry.updateLanguage();
}
}
return null;
}
public void setPreferredOrder(String[] preferredOrder) {
this.preferredOrder = preferredOrder;
}
public String[] getPreferredOrder() {
return preferredOrder == null ? new String[0] : preferredOrder;
}
}