/* Copyright (C) 2009 Mobile Sorcery AB This program is free software; you can redistribute it and/or modify it under the terms of the Eclipse Public License v1.0. 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 Eclipse Public License v1.0 for more details. You should have received a copy of the Eclipse Public License v1.0 along with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html */ package com.mobilesorcery.sdk.ui.targetphone; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.Reader; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IMemento; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.XMLMemento; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; import com.mobilesorcery.sdk.core.CoreMoSyncPlugin; import com.mobilesorcery.sdk.core.MoSyncProject; import com.mobilesorcery.sdk.core.MoSyncTool; import com.mobilesorcery.sdk.core.Util; import com.mobilesorcery.sdk.lib.JNALibInitializer; import com.mobilesorcery.sdk.ui.MosyncUIPlugin; import com.mobilesorcery.sdk.ui.targetphone.internal.TargetPhoneTransportProxy; import com.mobilesorcery.sdk.ui.targetphone.internal.bt.BTDIALOG; import com.mobilesorcery.sdk.ui.targetphone.internal.bt.BTTargetPhoneTransport; /** * The activator class controls the plug-in life cycle */ public class TargetPhonePlugin extends AbstractUIPlugin { // The plug-in ID public static final String PLUGIN_ID = "com.mobilesorcery.sdk.ui.targetphone"; private static final String TARGET_PHONE_PREF_PREFIX = "target.phone."; private static final String TARGET_PHONE_PREF_NAME_SUFFIX = ".name"; private static final String TARGET_PHONE_PREF_ADDR_SUFFIX = ".addr"; private static final String TARGET_PHONE_PREF_PORT_SUFFIX = ".port"; private static final String TARGET_PHONE_PREF_SELECTED_SUFFIX = ".current"; private static final String TARGET_PHONE_PREF_PROFILE_SUFFIX = ".preferred.profile"; private static final int MAX_HISTORY_SIZE = 15; public static final String DEFAULT_TARGET_PHONE_TRANSPORT = "bt"; // The shared instance private static TargetPhonePlugin plugin; private final LinkedList<ITargetPhone> history = new LinkedList<ITargetPhone>(); private ITargetPhone selectedPhone; private final HashMap<String, ITargetPhoneTransport> transports = new HashMap<String, ITargetPhoneTransport>(); private final CopyOnWriteArrayList<ITargetPhoneTransportListener> listeners = new CopyOnWriteArrayList<ITargetPhoneTransportListener>(); /** * The constructor */ public TargetPhonePlugin() { } /* * (non-Javadoc) * * @see * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext * ) */ @Override public void start(BundleContext context) throws Exception { super.start(context); plugin = this; initNativeLibs(context); initTargetPhoneTransports(); initTargetPhoneHistory(); } private void initTargetPhoneHistory() { Reader historyInput = null; try { File historyInputFile = getHistoryOutputPath().toFile(); if (!historyInputFile.exists()) { return; } historyInput = new FileReader(historyInputFile); XMLMemento historyMemento = XMLMemento.createReadRoot(historyInput); IMemento[] devices = historyMemento.getChildren("device"); history.clear(); Integer selected = historyMemento.getInteger("selected"); for (int i = 0; i < devices.length; i++) { IMemento device = devices[i]; String transportId = device.getString("transport"); ITargetPhoneTransport transport = getTargetPhoneTransport(transportId); if (transport != null) { Integer ix = device.getInteger("ix"); String name = device .getString(ITargetPhoneTransport.NAME_ATTR); String legacyProfile = device .getString(ITargetPhoneTransport.LEGACY_PROFILE_ATTR); String platformProfile = device .getString(ITargetPhoneTransport.DEFAULT_PROFILE_ATTR); ITargetPhone targetPhone = transport.load(device, name); targetPhone.setPreferredProfile(MoSyncTool.LEGACY_PROFILE_TYPE, MoSyncTool.getDefault().getProfileManager(MoSyncTool.LEGACY_PROFILE_TYPE) .getProfile(legacyProfile)); targetPhone.setPreferredProfile(MoSyncTool.DEFAULT_PROFILE_TYPE, MoSyncTool.getDefault().getProfileManager(MoSyncTool.DEFAULT_PROFILE_TYPE) .getProfile(platformProfile)); history.addFirst(targetPhone); if (Util.equals(ix, selected)) { selectedPhone = targetPhone; } } } } catch (Exception e) { CoreMoSyncPlugin.getDefault().log(e); } finally { Util.safeClose(historyInput); } } private void initTargetPhoneTransports() { // The default (BT) transport addTransport(new BTTargetPhoneTransport()); // Other (extension points) transports IConfigurationElement[] transportExtensions = Platform.getExtensionRegistry().getConfigurationElementsFor("com.mobilesorcery.sdk.targetphonetransports"); for (int i = 0; i < transportExtensions.length; i++) { IConfigurationElement transportExtension = transportExtensions[i]; String transportId = transportExtension.getAttribute("id"); if (transportId != null) { addTransport(new TargetPhoneTransportProxy(transportExtension)); } } } private void addTransport(ITargetPhoneTransport transport) { transports.put(transport.getId(), transport); } public ITargetPhoneTransport getTargetPhoneTransport(String transportId) { return transports.get(transportId); } public List<ITargetPhoneTransport> getTargetPhoneTransports() { ArrayList<ITargetPhoneTransport> result = new ArrayList<ITargetPhoneTransport>(); for (ITargetPhoneTransport transport : transports.values()) { if (transport.isAvailable()) { result.add(transport); } } return result; } private void storeTargetPhoneHistory() throws CoreException { int i = 0; XMLMemento historyMemento = XMLMemento.createWriteRoot("history"); for (Iterator<ITargetPhone> phones = this.history.iterator(); phones .hasNext();) { ITargetPhone phone = phones.next(); ITargetPhoneTransport transport = phone.getTransport(); if (transport != null) { IMemento deviceMemento = historyMemento.createChild("device"); deviceMemento.putInteger("ix", i); deviceMemento.putString("transport", transport.getId()); deviceMemento.putString(ITargetPhoneTransport.NAME_ATTR, phone .getName()); deviceMemento.putString(ITargetPhoneTransport.LEGACY_PROFILE_ATTR, MoSyncTool.toString(phone.getPreferredProfile(MoSyncTool.LEGACY_PROFILE_TYPE))); deviceMemento.putString(ITargetPhoneTransport.DEFAULT_PROFILE_ATTR, MoSyncTool.toString(phone.getPreferredProfile(MoSyncTool.DEFAULT_PROFILE_TYPE))); transport.store(phone, deviceMemento); if (selectedPhone == phone) { historyMemento.putInteger("selected", i); } } i++; } IPath historyOutputPath = getHistoryOutputPath(); Writer historyOutputWriter = null; try { historyOutputWriter = new FileWriter(historyOutputPath.toFile()); historyMemento.save(historyOutputWriter); } catch (Exception e) { throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, e .getMessage(), e)); } finally { Util.safeClose(historyOutputWriter); } } private IPath getHistoryOutputPath() { return Platform.getStateLocation(getBundle()).append("history.xml"); } private void initNativeLibs(BundleContext context) { if(System.getProperty("os.name").toLowerCase().indexOf("win") == -1) { return; } try { JNALibInitializer.init(getBundle(), "libbtdialog"); BTDIALOG dummy = BTDIALOG.INSTANCE; // Just to execute the .clinit. } catch (Throwable t) { t.printStackTrace(); } } /* * (non-Javadoc) * * @see * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext * ) */ @Override public void stop(BundleContext context) throws Exception { try { storeTargetPhoneHistory(); } finally { plugin = null; super.stop(context); } } /** * Returns the shared instance * * @return the shared instance */ public static TargetPhonePlugin getDefault() { return plugin; } public List<ITargetPhone> getSelectedTargetPhoneHistory() { return history; } public void addToHistory(ITargetPhone phone) { if (phone == null) { return; } history.remove(phone); history.addFirst(phone); setCurrentlySelectedPhone(phone); while (history.size() > MAX_HISTORY_SIZE) { history.removeLast(); } } public void setCurrentlySelectedPhone(ITargetPhone selectedPhone) { this.selectedPhone = selectedPhone; } public ITargetPhone getCurrentlySelectedPhone() { return selectedPhone; } public void clearHistory() { history.clear(); selectedPhone = null; } public int getCurrentProfileManagerType() { MoSyncProject current = MosyncUIPlugin.getDefault().getCurrentlySelectedProject(PlatformUI.getWorkbench().getActiveWorkbenchWindow()); if (current == null) { return MoSyncTool.DEFAULT_PROFILE_TYPE; } return current.getProfileManagerType(); } public void addTargetPhoneTransportListener(ITargetPhoneTransportListener listener) { listeners.add(listener); } public void removeTargetPhoneTransportListener(ITargetPhoneTransportListener listener) { listeners.remove(listener); } public void notifyListeners(TargetPhoneTransportEvent event) { for (ITargetPhoneTransportListener listener : listeners) { listener.handleEvent(event); } } public Image getIcon(ITargetPhoneTransport transport) { if (transport == null) { return null; } String id = transport.getId(); Image image = getImageRegistry().get(id); if (image == null) { getImageRegistry().put(transport.getId(), transport.getIcon()); } return getImageRegistry().get(id); } }