diff options
author | Vincent Lucas <chenzo@jitsi.org> | 2008-05-26 16:45:28 +0000 |
---|---|---|
committer | Vincent Lucas <chenzo@jitsi.org> | 2008-05-26 16:45:28 +0000 |
commit | fa9d637520e01afa293494a16978f7162b32a680 (patch) | |
tree | 8528722ca844a50333ad556009a964134f2e5b27 /src/net/java/sip | |
parent | 5c12cfed50c5cd16835abd0146bda09f3db848d0 (diff) | |
download | jitsi-fa9d637520e01afa293494a16978f7162b32a680.zip jitsi-fa9d637520e01afa293494a16978f7162b32a680.tar.gz jitsi-fa9d637520e01afa293494a16978f7162b32a680.tar.bz2 |
[3/4] Adding DICT protocole and wizzard (corrected version).
Diffstat (limited to 'src/net/java/sip')
9 files changed, 1879 insertions, 0 deletions
diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccRegWizzActivator.java new file mode 100644 index 0000000..7972841 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccRegWizzActivator.java @@ -0,0 +1,136 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.dictaccregwizz; + +import java.util.*; + +import net.java.sip.communicator.service.browserlauncher.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + +import org.osgi.framework.*; + +/** + * Registers the <tt>DictAccountRegistrationWizard</tt> in the UI Service. + * + * @author ROTH Damien + * @author LITZELMANN Cédric + */ +public class DictAccRegWizzActivator implements BundleActivator +{ + public static BundleContext bundleContext; + + private static Logger logger = Logger.getLogger( + DictAccRegWizzActivator.class); + + private static BrowserLauncherService browserLauncherService; + + private static WizardContainer wizardContainer; + + private static DictAccountRegistrationWizard dictWizard; + + private static UIService uiService; + + /** + * Starts this bundle. + * + * @param bc The bundle context. + */ + public void start(BundleContext bc) throws Exception { + + bundleContext = bc; + + ServiceReference uiServiceRef = bundleContext + .getServiceReference(UIService.class.getName()); + + uiService = (UIService) bundleContext.getService(uiServiceRef); + + wizardContainer = uiService.getAccountRegWizardContainer(); + + dictWizard = new DictAccountRegistrationWizard(wizardContainer); + + //wizardContainer.addAccountRegistrationWizard(dictWizard); + Hashtable<String, String> containerFilter + = new Hashtable<String, String>(); + + containerFilter.put( + ProtocolProviderFactory.PROTOCOL, + ProtocolNames.DICT); + + bundleContext.registerService( + AccountRegistrationWizard.class.getName(), + dictWizard, + containerFilter); + } + + + /** + * Stops this bundle. + * + * @param bundleContext The bundle context (unused). + * + * @throws Exception Throws an execption from the + * "wizardContainer.removeAccountRegistrationWizard" method. + * + */ + public void stop(BundleContext bundleContext) throws Exception + { + //wizardContainer.removeAccountRegistrationWizard(dictWizard); + } + + /** + * Returns the <tt>ProtocolProviderFactory</tt> for the Dict protocol. + * @return the <tt>ProtocolProviderFactory</tt> for the Dict protocol + */ + public static ProtocolProviderFactory getDictProtocolProviderFactory() { + + ServiceReference[] serRefs = null; + + String osgiFilter = "(" + + ProtocolProviderFactory.PROTOCOL + + "="+ProtocolNames.DICT+")"; + + try { + serRefs = bundleContext.getServiceReferences( + ProtocolProviderFactory.class.getName(), osgiFilter); + } + catch (InvalidSyntaxException ex){ + logger.error("DictAccRegWizzActivator : " + ex); + } + + return (ProtocolProviderFactory) bundleContext.getService(serRefs[0]); + } + + /** + * Returns the <tt>BrowserLauncherService</tt> obtained from the bundle + * context. + * @return the <tt>BrowserLauncherService</tt> obtained from the bundle + * context + */ + public static BrowserLauncherService getBrowserLauncher() { + if (browserLauncherService == null) { + ServiceReference serviceReference = bundleContext + .getServiceReference(BrowserLauncherService.class.getName()); + + browserLauncherService = (BrowserLauncherService) bundleContext + .getService(serviceReference); + } + + return browserLauncherService; + } + + /** + * Returns the <tt>UIService</tt>. + * + * @return the <tt>UIService</tt> + */ + public static UIService getUIService() + { + return uiService; + } +} diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistration.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistration.java new file mode 100644 index 0000000..5bda4e6 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistration.java @@ -0,0 +1,123 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.dictaccregwizz; + +/** + * The <tt>DictAccountRegistration</tt> is used to store all user input data + * through the <tt>DictAccountRegistrationWizard</tt>. + * + * @author ROTH Damien + * @author LITZELMANN Cédric + */ +public class DictAccountRegistration +{ + private String userID; + private String password; + + /** + * The hostname of the DICT server. + */ + private String host; + + /** + * The port of the DICT server. + */ + private int port; + + /** + * The code id of the strategie selected for the matching of words in dictionnaries. + */ + private String strategyCode; + + /** + * The real name of the strategie selected for the matching of words in dictionnaries. + */ + private String strategy; + + /** + * Returns the User ID of the dict registration account. + * @return the User ID of the dict registration account. + */ + public String getUserID() + { + return userID; + } + + /** + * Sets the password of the dict registration account. + * + * @param password the password of the dict registration account. + */ + public void setPassword(String password) + { + this.password = password; + } + + /** + * Returns the port of the dict registration account. + * @return the port of the dict registration account. + */ + public int getPort() { + return this.port; + } + + /** + * Sets the port of the dict registration account. + * @param port the port of the dict registration account. + */ + public void setPort(int port) { + this.port = port; + } + + /** + * Returns the host of the dict registration account. + * @return the host of the dict registration account. + */ + public String getHost() { + return this.host; + } + + /** + * Sets the host of the dict registration account. + * @param uin the host of the dict registration account. + */ + public void setHost(String host) { + this.host = host; + } + + /** + * Returns the strategy that will be used for this dict account. + * @return the strategy that will be used for this dict account. + */ + public String getStrategy() { + return this.strategy; + } + + /** + * Sets the strategy for this dict account. + * @param strategy the strategy for this dict account. + */ + public void setStrategy(String strategy) { + this.strategy = strategy; + } + + /** + * Returns the strategy code that will be used for this dict account. + * @return the strategy code that will be used for this dict account. + */ + public String getStrategyCode() { + return this.strategyCode; + } + + /** + * Sets the strategy code for this dict account. + * @param strategyCode the strategy code for this dict account. + */ + public void setStrategyCode(String strategyCode) { + this.strategyCode = strategyCode; + } +} diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistrationWizard.java new file mode 100644 index 0000000..b2d2d5b --- /dev/null +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAccountRegistrationWizard.java @@ -0,0 +1,409 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.dictaccregwizz; + +import java.awt.*; +import java.util.*; + +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; + +import org.osgi.framework.*; + +/** + * The <tt>DictAccountRegistrationWizard</tt> is an implementation of the + * <tt>AccountRegistrationWizard</tt> for the Dict protocol. It should allow + * the user to create and configure a new Dict account. + * + * @author ROTH Damien + * @author LITZELMANN Cédric + */ +public class DictAccountRegistrationWizard + implements AccountRegistrationWizard +{ + /** + * The reference to the first page of the wizard. + */ + private FirstWizardPage firstWizardPage; + + /** + * The registration of the DICT account. + */ + private DictAccountRegistration registration = new DictAccountRegistration(); + + /** + * The container of the wizard. + */ + private WizardContainer wizardContainer; + + /** + * The protocole provider. + */ + private ProtocolProviderService protocolProvider; + + /** + * Tells us if the is a modification wiazrd or not. + */ + private boolean isModification; + + /** + * Creates an instance of <tt>DictAccountRegistrationWizard</tt>. + * + * @param wizardContainer the wizard container, where this wizard is added + */ + public DictAccountRegistrationWizard(WizardContainer wizardContainer) + { + this.wizardContainer = wizardContainer; + } + + /** + * Implements the <code>AccountRegistrationWizard.getIcon</code> method. + * @return Returns the icon to be used for this wizard. + */ + public byte[] getIcon() + { + return Resources.getImage(Resources.DICT_LOGO); + } + + /** + * Implements the <code>AccountRegistrationWizard.getPageImage</code> + * method. Returns the image used to decorate the wizard page + * + * @return byte[] the image used to decorate the wizard page + */ + public byte[] getPageImage() + { + return Resources.getImage(Resources.PAGE_IMAGE); + } + + /** + * Implements the <code>AccountRegistrationWizard.getProtocolName</code> + * method. + * @return Returns the protocol name for this wizard. + */ + public String getProtocolName() + { + return Resources.getString("protocolName"); + } + + /** + * Implements the <code>AccountRegistrationWizard.getProtocolDescription + * </code> method. + * @return Returns the description of the protocol for this wizard. + */ + public String getProtocolDescription() + { + return Resources.getString("protocolDescription"); + } + + /** + * Returns the set of pages contained in this wizard. + * + * @return Returns the set of pages contained in this wizard. + */ + public Iterator getPages() + { + ArrayList pages = new ArrayList(); + this.firstWizardPage = new FirstWizardPage(this); + pages.add(this.firstWizardPage); + return pages.iterator(); + } + + /** + * Returns the set of data that user has entered through this wizard. + * @return Returns the set of data that user has entered through this wizard. + */ + public Iterator getSummary() + { + LinkedHashMap<String, String> summaryTable = new LinkedHashMap<String, String>(); + + summaryTable.put("Host", registration.getHost()); + summaryTable.put("Port", String.valueOf(registration.getPort())); + summaryTable.put("Strategy", registration.getStrategy()); + + return summaryTable.entrySet().iterator(); + } + + /** + * Installs the account created through this wizard. + * + * @return The ProtocoleProviderService installed for the account. + */ + public ProtocolProviderService finish() + { + firstWizardPage = null; + ProtocolProviderFactory factory = + DictAccRegWizzActivator.getDictProtocolProviderFactory(); + + return this.installAccount(factory, registration.getHost(), + registration.getPort(), + registration.getStrategyCode()); + } + + /** + * Installs the account created through this wizard. + * @return ProtocolProviderService + */ + public ProtocolProviderService signin() + { + return signin(registration.getUserID(), null); + } + + /** + * Installs the account created through this wizard. + * @return ProtocolProviderService + */ + public ProtocolProviderService signin(String userName, String password) + { + firstWizardPage = null; + ProtocolProviderFactory factory + = DictAccRegWizzActivator.getDictProtocolProviderFactory(); + + /*return this.installAccount(factory, + userName);*/ + return this.installAccount(factory, registration.getHost(), + registration.getPort(), + registration.getStrategyCode()); + } + + /** + * Creates an account for the given user and password. + * + * @param providerFactory the ProtocolProviderFactory which will create the + * account. + * @param host The hostname of the DICT server. + * @param port The port used by the DICT server. + * @param strategy The strategy choosen for matching words in the + * dictionnaries. + * @return the <tt>ProtocolProviderService</tt> for the new account. + */ + public ProtocolProviderService installAccount( + ProtocolProviderFactory providerFactory, + String host, + int port, + String strategy) + { + Hashtable accountProperties = new Hashtable(); + + // Save host + accountProperties.put(ProtocolProviderFactory.SERVER_ADDRESS, host); + // Save port + accountProperties.put(ProtocolProviderFactory.SERVER_PORT, String.valueOf(port)); + // Save strategy + accountProperties.put(ProtocolProviderFactory.STRATEGY, strategy); + + if (isModification) + { + providerFactory.uninstallAccount(protocolProvider.getAccountID()); + this.protocolProvider = null; + this.isModification = false; + } + + try + { + String uid = this.generateUID(); + AccountID accountID = + providerFactory.installAccount(uid, accountProperties); + + ServiceReference serRef = + providerFactory.getProviderForAccount(accountID); + + protocolProvider = + (ProtocolProviderService) DictAccRegWizzActivator.bundleContext + .getService(serRef); + } + catch (IllegalArgumentException e) + { + DictAccRegWizzActivator.getUIService().getPopupDialog() + .showMessagePopupDialog(e.getMessage(), + Resources.getString("error"), + PopupDialog.ERROR_MESSAGE); + } + catch (IllegalStateException e) + { + DictAccRegWizzActivator.getUIService().getPopupDialog() + .showMessagePopupDialog(e.getMessage(), + Resources.getString("error"), + PopupDialog.ERROR_MESSAGE); + } + + return protocolProvider; + } + + /** + * Fills the UIN and Password fields in this panel with the data coming + * from the given protocolProvider. + * + * @param protocolProvider The <tt>ProtocolProviderService</tt> to load + * the data from. + */ + public void loadAccount(ProtocolProviderService protocolProvider) + { + this.isModification = true; + + this.protocolProvider = protocolProvider; + + this.registration = new DictAccountRegistration(); + + this.firstWizardPage.loadAccount(protocolProvider); + } + + /** + * Indicates if this wizard is opened for modification or for creating a + * new account. + * + * @return <code>true</code> if this wizard is opened for modification and + * <code>false</code> otherwise. + */ + public boolean isModification() + { + return isModification; + } + + /** + * Sets if this wizard is opened for modification or for creating a + * new account. + * + * @param b <code>True</code> if this wizard is opened for modification and + * <code>false</code> otherwise. + */ + public void setModification(boolean b) + { + this.isModification = b; + } + + /** + * Returns the wizard container, where all pages are added. + * + * @return the wizard container, where all pages are added + */ + public WizardContainer getWizardContainer() + { + return wizardContainer; + } + + /** + * Returns the registration object, which will store all the data through + * the wizard. + * + * @return the registration object, which will store all the data through + * the wizard + */ + public DictAccountRegistration getRegistration() + { + return registration; + } + + /** + * Returns the size of this wizard. + * @return the size of this wizard + */ + public Dimension getSize() + { + return new Dimension(300, 150); + } + + /** + * Returns the identifier of the page to show first in the wizard. + * @return the identifier of the page to show first in the wizard. + */ + public Object getFirstPageIdentifier() + { + return firstWizardPage.getIdentifier(); + } + + /** + * Returns the identifier of the page to show last in the wizard. + * @return the identifier of the page to show last in the wizard. + */ + public Object getLastPageIdentifier() + { + return firstWizardPage.getIdentifier(); + } + + /** + * Generate the UID for the acount + * @return the new UID + */ + private String generateUID() + { + String uid; + int nbAccounts = this.getNumberOfAccounts(); + String host = this.registration.getHost(); + int nbAccountsForHost = this.getNbAccountForHost(host); + + if (nbAccounts == 0 || (this.isModification() && nbAccounts == 1) || + nbAccountsForHost == 0 || (this.isModification() && nbAccountsForHost == 1)) + { + // We create the first account or we edit the onlyone + // Or we create the first account for this server or edit the onlyone + uid = host; + } + else + { + uid = host + ":" + this.registration.getPort(); + } + + return uid; + } + + /** + * Returns the number of accounts stored for the protocol + * @return the number of accounts stored for the protocol + */ + private int getNumberOfAccounts() + { + ProtocolProviderFactory factory = + DictAccRegWizzActivator.getDictProtocolProviderFactory(); + + return factory.getRegisteredAccounts().size(); + } + + /** + * Returns the number of account for a given host + * @param hostName the host + * @return the number of account for a given host + */ + private int getNbAccountForHost(String host) + { + ProtocolProviderFactory factory = + DictAccRegWizzActivator.getDictProtocolProviderFactory(); + + ArrayList registeredAccounts = factory.getRegisteredAccounts(); + int total = 0; + + for (int i = 0; i < registeredAccounts.size(); i++) + { + AccountID accountID = (AccountID) registeredAccounts.get(i); + + // The host is always stored at the start + if (accountID.getUserID().startsWith(host.toLowerCase())) + { + total++; + } + } + return total; + } + + /** + * Returns an example string, which should indicate to the user how the + * user name should look like. + * @return an example string, which should indicate to the user how the + * user name should look like. + */ + public String getUserNameExample() + { + return null; + } + + /** + * Disables the simple "Sign in" form. + */ + public boolean isSimpleFormEnabled() + { + return false; + } +} diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAdapter.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAdapter.java new file mode 100644 index 0000000..e7329ab --- /dev/null +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/DictAdapter.java @@ -0,0 +1,183 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.dictaccregwizz; + +import java.io.*; +import java.net.*; +import java.util.*; + +import net.java.sip.communicator.util.Logger; + +/** + * Copy of DictAdapter class to solve the import problem + * @author ROTH Damien + * @author LITZELMANN Cédric + */ + +public class DictAdapter +{ + private static Logger logger = Logger.getLogger(DictAdapter.class); + + /** + * The socket used to connect to the DICT server. + */ + private Socket socket = null; + + /** + * A output stream piped to the socket in order to send command to the server. + */ + private PrintWriter out = null; + + /** + * A input stream piped to the socket in order to receive messages from the server. + */ + private BufferedReader in = null; + + /** + * A boolean telling if we are currently connected to the DICT server. + */ + private boolean connected = false; + + /** + * Get the strategies allowed by the server for the MATCH command + * @return a HashMap containing the database list - otherwise null + */ + public ArrayList<String> getStrategies() + { + String fromServer; + boolean quit = false; + ArrayList<String> result = null; + + // Connexion + if (!this.connected) + { + // Not connected + return null; + } + + try + { + this.out.println("SHOW STRAT"); + fromServer = this.in.readLine(); + + if (fromServer.startsWith("111")) + { // OK - getting responses from the server + result = new ArrayList<String>(); + while (quit == false && (fromServer = this.in.readLine()) != null) + { + if (fromServer.startsWith("250")) + { + quit = true; + } + else if (!fromServer.equals(".")) + { + result.add(fromServer); + } + } + } + } + catch (IOException ioe) + { + logger.trace("Cannot get the strategies : " + ioe.getMessage()); + result = null; + } + return result; + } + + + /** + * Open a connection to the given host on the given port + * @param host The hostname of the server. + * @param port The port used by the server. + * @return true, if a connection is open - false otherwise + */ + public boolean connect(String host, int port) + { + this.connected = false; + String fromServer; + + try + { + this.socket = new Socket(host, port); + this.out = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream(), + "UTF-8"), true); + this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream(), + "UTF-8")); + + fromServer = this.in.readLine(); // Server banner + + if (fromServer.startsWith("220")) + { // 220 = connect ok + this.connected = true; + } + } + catch(Exception ex) + { // If an exception is throw == connexion impossible + logger.trace("Cannot establish a connexion to the server (" + + host + ":" + port + ")", ex); + } + + return this.connected; + } + + /** + * Close the connexion to the server + */ + public void close() + { + String fromServer; + + try + { + this.out.println("QUIT"); + + // Clean the socket buffer + while ((fromServer = this.in.readLine()) != null) + { + if (fromServer.startsWith("221")) + { // Quit response + break; + } + } + + this.out.close(); + this.in.close(); + this.socket.close(); + } + catch (IOException ioe) + { + logger.info("Cannot close the connextion to the server", ioe); + } + } + + /** + * Checks if the given url is correct and exists + * @param host The url that we have to test if it is correct and if it + * exists. + * @return true if the url exists - false otherwise + */ + public static boolean isUrl(String host) + { + boolean ok = false; + + if (host == null || host.length() == 0) + { + return false; + } + + // If an exception is throw, the host format isn't correct or isn't recheable + try + { + InetAddress.getByName(host); + ok = true; + } + catch (UnknownHostException uhex) + { + logger.trace("Test URL ("+host+") : " + uhex.getMessage(), uhex); + } + return ok; + } +} diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/FirstWizardPage.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/FirstWizardPage.java new file mode 100644 index 0000000..474bc6d --- /dev/null +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/FirstWizardPage.java @@ -0,0 +1,672 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.dictaccregwizz; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; + +import javax.swing.*; +import javax.swing.event.*; + +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + +/** + * The <tt>FirstWizardPage</tt> is the page, where user could enter the host, + * port and the strategy of the account. + * + * @author ROTH Damien + * @author LITZELMANN Cédric + */ +public class FirstWizardPage + extends JPanel + implements WizardPage, DocumentListener, ActionListener +{ + private static Logger logger = Logger.getLogger(FirstWizardPage.class); + + public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier"; + + private JPanel hostPortPanel = new JPanel(new BorderLayout(10, 10)); + + private JPanel labelsPanel = new JPanel(); + + private JPanel valuesPanel = new JPanel(); + + private JLabel hostLabel = new JLabel("Host"); + + private JPanel emptyPanel = new JPanel(); + + private JLabel hostExampleLabel = new JLabel("Ex: dict.org"); + + private JLabel portLabel = new JLabel("Port"); + + private JLabel existingAccountLabel = + new JLabel(Resources.getString("existingAccount")); + + private JTextField hostField = new JTextField(); + + private JTextField portField = new JTextField("2628"); + + + private JPanel strategyPanel = new JPanel(new BorderLayout(10, 10)); + + private JPanel strategyTitleBloc = new JPanel(new BorderLayout()); + + private JLabel strategyTitle = new JLabel(Resources.getString("strategyList")); + + private JButton strategyLoader = new JButton(Resources.getString("strategyActu")); + + private Vector<String> strategyList; + private JScrollPane jScrollPane; + private JList strategyBox; + private JTextArea strategyDescription = new JTextArea(Resources.getString("strategyDesc")); + private JLabel strategyMessage; + private boolean strategyMessInstall = false; + + private JPanel mainPanel = new JPanel(); + + private Object nextPageIdentifier = WizardPage.SUMMARY_PAGE_IDENTIFIER; + + private DictAccountRegistrationWizard wizard; + + private String initstrategy = ""; + + private ArrayList<String> strategiesAssoc = new ArrayList<String>(); + + private StrategyThread populateThread = null; + + private boolean firstAccount = false; + + /** + * Initial AccountID (null if new account) + * Used to check if there are modifications to the account + */ + private AccountID initAccountID = null; + + /** + * Creates an instance of <tt>FirstWizardPage</tt>. + * + * @param wizard the parent wizard + */ + public FirstWizardPage(DictAccountRegistrationWizard wizard) + { + super(new BorderLayout()); + + this.wizard = wizard; + + this.setPreferredSize(new Dimension(300, 150)); + + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + + this.populateThread = new StrategyThread(this); + + this.firstAccount = !this.hasAccount(); + + if (this.firstAccount) + { + this.initFirstAccount(); + } + else + { + this.init(); + } + + this.populateThread = new StrategyThread(this); + this.populateThread.start(); + + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + } + + /** + * Initializes all panels, buttons, etc. + */ + private void init() + { + // Host and port Field + this.hostField = new JTextField(); + this.portField = new JTextField("2628"); + + this.hostField.getDocument().addDocumentListener(this); + this.portField.getDocument().addDocumentListener(this); + + // Server informations + this.existingAccountLabel.setForeground(Color.RED); + + this.hostExampleLabel.setForeground(Color.GRAY); + this.hostExampleLabel.setFont(hostExampleLabel.getFont().deriveFont(8)); + this.emptyPanel.setMaximumSize(new Dimension(40, 35)); + this.hostExampleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, + 0)); + + labelsPanel.add(hostLabel); + labelsPanel.add(emptyPanel); + labelsPanel.add(portLabel); + + valuesPanel.add(hostField); + valuesPanel.add(hostExampleLabel); + valuesPanel.add(portField); + + hostPortPanel.add(labelsPanel, BorderLayout.WEST); + hostPortPanel.add(valuesPanel, BorderLayout.CENTER); + + hostPortPanel.setBorder(BorderFactory.createTitledBorder("Server informations")); + + this.labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.Y_AXIS)); + this.valuesPanel.setLayout(new BoxLayout(valuesPanel, BoxLayout.Y_AXIS)); + + mainPanel.add(hostPortPanel); + + this.portField.addKeyListener(new KeyListener() { + public void keyTyped(KeyEvent evt) + { + // If evt isn't a digit, we don't add it + if (!Character.isDigit(evt.getKeyChar())) + { + evt.consume(); + } + } + + // Not used + public void keyPressed(KeyEvent evt) {;} + public void keyReleased(KeyEvent evt) {;} + }); + + // Strategies + this.strategyList = new Vector<String>(); + this.strategyBox = new JList(this.strategyList); + + for (int i=0; i<20; i++) + { + this.strategyList.add("Elem "+i); + } + + this.strategyBox.setVisibleRowCount(6); + + this.strategyBox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + this.jScrollPane = new JScrollPane(); + this.jScrollPane.getViewport().add(this.strategyBox); + this.strategyPanel.add(this.jScrollPane); + + // Strategy title + button + this.strategyTitleBloc.add(this.strategyTitle, BorderLayout.WEST); + this.strategyTitleBloc.add(this.strategyLoader, BorderLayout.EAST); + + // Button action listener + this.strategyLoader.setActionCommand("populateList"); + this.strategyLoader.addActionListener(this); + + // South Panel + JPanel sSouthPanel = new JPanel(new BorderLayout()); + + // Description + this.strategyDescription.setLineWrap(true); + this.strategyDescription.setLineWrap(true); + this.strategyDescription.setRows(4); + this.strategyDescription.setWrapStyleWord(true); + this.strategyDescription.setAutoscrolls(false); + sSouthPanel.add(this.strategyDescription); + + // Message + this.strategyMessage = new JLabel(" "); + sSouthPanel.add(this.strategyMessage, BorderLayout.SOUTH); + + this.strategyPanel.add(sSouthPanel, BorderLayout.SOUTH); + + this.strategyPanel.add(this.strategyTitleBloc, BorderLayout.NORTH); + this.strategyPanel.setBorder(BorderFactory.createTitledBorder("Strategy selection")); + mainPanel.add(this.strategyPanel); + + this.add(mainPanel, BorderLayout.NORTH); + } + + private void initFirstAccount() + { + // Data init + this.hostField = new JTextField("dict.org"); + this.portField = new JTextField("2628"); + + // Init strategy box + this.strategyList = new Vector<String>(); + this.strategyBox = new JList(this.strategyList); + this.strategyMessage = new JLabel(" "); + + + JPanel infoTitlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + JTextArea firstDescription = new JTextArea(Resources.getString("firstAccount")); + JLabel title = new JLabel(Resources.getString("dictAccountInfoTitle")); + + // Title + title.setFont(title.getFont().deriveFont(Font.BOLD, 14.0f)); + infoTitlePanel.add(title); + this.add(infoTitlePanel, BorderLayout.NORTH); + this.add(this.strategyMessage, BorderLayout.SOUTH); + + // Description + firstDescription.setLineWrap(true); + firstDescription.setLineWrap(true); + firstDescription.setRows(6); + firstDescription.setWrapStyleWord(true); + firstDescription.setAutoscrolls(false); + this.add(firstDescription); + } + + /** + * Implements the <code>WizardPage.getIdentifier</code> to return this + * page identifier. + * + * @return Returns the identifier of the current (the first) page of the wizard. + */ + public Object getIdentifier() + { + return FIRST_PAGE_IDENTIFIER; + } + + /** + * Implements the <code>WizardPage.getNextPageIdentifier</code> to return + * the next page identifier - the summary page. + * + * @return Returns the identifier of the next page of the wizard. + */ + public Object getNextPageIdentifier() + { + return nextPageIdentifier; + } + + /** + * Implements the <code>WizardPage.getBackPageIdentifier</code> to return + * the next back identifier - the default page. + * + * @return Returns the identifier of the previous page of the wizard. + */ + public Object getBackPageIdentifier() + { + return WizardPage.DEFAULT_PAGE_IDENTIFIER; + } + + /** + * Implements the <code>WizardPage.getWizardForm</code> to return this + * panel. + * @return Returns this form of the wizard. + */ + public Object getWizardForm() + { + return this; + } + + /** + * Before this page is displayed enables or disables the "Next" wizard + * button according to whether the UIN field is empty. + */ + public void pageShowing() + { + this.setNextButtonEnabled(); + } + + /** + * Saves the user input when the "Next" wizard buttons is clicked. + */ + public void pageNext() + { + //* + String host = hostField.getText(); + int port = Integer.parseInt(portField.getText()); + int stPos; + boolean isModified = false; + + if (this.initAccountID instanceof AccountID) + { // We check if there is modifications to the server + String accHost = (String) this.initAccountID.getAccountProperties() + .get(ProtocolProviderFactory.SERVER_ADDRESS); + int accPort = Integer.parseInt((String) this.initAccountID.getAccountProperties() + .get(ProtocolProviderFactory.SERVER_PORT)); + + if (accHost != host || accPort != port) + { + isModified = true; + } + } + + // We check if a strategy has been selected + if (this.strategyList.size() == 0) + { // No Strategy, we get them + this.populateStrategies(); + + while (this.populateThread.isRunning()) {;} + } + + if (this.strategyList.size() == 0) + { + // No strategy, maybe not connected + // Information message is already on the wizard + nextPageIdentifier = FIRST_PAGE_IDENTIFIER; + this.revalidate(); + } + else if ((!wizard.isModification() && isExistingAccount(host, port)) + || (isModified && isExistingAccount(host, port))) + { + nextPageIdentifier = FIRST_PAGE_IDENTIFIER; + hostPortPanel.add(existingAccountLabel, BorderLayout.NORTH); + this.revalidate(); + } + else + { + nextPageIdentifier = SUMMARY_PAGE_IDENTIFIER; + hostPortPanel.remove(existingAccountLabel); + + DictAccountRegistration registration = wizard.getRegistration(); + + registration.setHost(host); + registration.setPort(port); + + stPos = this.strategyBox.getSelectedIndex(); + registration.setStrategyCode(this.strategiesAssoc.get(stPos)); + registration.setStrategy(this.strategyBox.getSelectedValue().toString()); + } + //*/ + } + + /** + * Enables or disables the "Next" wizard button according to whether the UIN + * field is empty. + */ + private void setNextButtonEnabled() + { + boolean hostOK = DictAdapter.isUrl(hostField.getText()); + boolean portOK = !this.portField.getText().isEmpty() + && Integer.parseInt(this.portField.getText()) > 10; + + if (this.firstAccount) + { + wizard.getWizardContainer().setNextFinishButtonEnabled(true); + } + else if (hostOK && portOK) + { + this.strategyLoader.setEnabled(true); + wizard.getWizardContainer().setNextFinishButtonEnabled(true); + } + else + { + // Disable the finish button + wizard.getWizardContainer().setNextFinishButtonEnabled(false); + + // Clear the list and disable the button + this.strategyList.clear(); + this.strategyLoader.setEnabled(false); + } + } + + /** + * Handles the <tt>DocumentEvent</tt> triggered when user types in the UIN + * field. Enables or disables the "Next" wizard button according to whether + * the UIN field is empty. + * + * @param e the <tt>DocumentEvent</tt> triggered when user types in the UIN + * field. + */ + public void insertUpdate(DocumentEvent e) + { + this.setNextButtonEnabled(); + } + + /** + * Handles the <tt>DocumentEvent</tt> triggered when user deletes letters + * from the UIN field. Enables or disables the "Next" wizard button + * according to whether the UIN field is empty. + * + * @param e The <tt>DocumentEvent</tt> triggered when user deletes letters + * from the UIN field. + */ + public void removeUpdate(DocumentEvent e) + { + this.setNextButtonEnabled(); + } + + /** + * Handles the <tt>DocumentEvent</tt> triggered when user changes an + * attribute or set of attributes from the UIN field. + * Currently this notification has no effect and is just here to implement + * the DocumentListener interface. + * + * @param e The <tt>DocumentEvent</tt> triggered when an attribute or set of + * attributes changed from the UIN field. + */ + public void changedUpdate(DocumentEvent e) + { + } + + /** + * Invoked when this WizardPage will be hidden eighter because the user has + * clicked "Back" or "Next". + * This function has no effect. + */ + public void pageHiding() + { + } + + /** + * Invoked when this WizardPage will be shown eighter because the user has + * clicked "Back" on the next wizard page or "Next" on the previous one. + * This function has no effect. + */ + public void pageShown() + { + } + + /** + * Invoked when user clicks on the "Back" wizard button. + * This function has no effect. + */ + public void pageBack() + { + } + + /** + * Fills the Host, Port and Strategy fields in this panel with the data comming + * from the given protocolProvider. + * + * @param protocolProvider The <tt>ProtocolProviderService</tt> to load + * the data from. + */ + public void loadAccount(ProtocolProviderService protocolProvider) + { + AccountID accountID = protocolProvider.getAccountID(); + String host = (String) accountID.getAccountProperties() + .get(ProtocolProviderFactory.SERVER_ADDRESS); + String port = (String) accountID.getAccountProperties() + .get(ProtocolProviderFactory.SERVER_PORT); + String strategy = (String) accountID.getAccountProperties() + .get(ProtocolProviderFactory.STRATEGY); + + this.initAccountID = accountID; + + // Host field + this.hostField.setText(host); + + // Port Field + this.portField.setText(port); + + // Load strategies + this.initstrategy = strategy; + this.populateStrategies(); + } + + /** + * Handles the action of the button. + * + * @param e The event generated when the button is pressed. + */ + public void actionPerformed(ActionEvent e) + { + // Button action -> populate the list + if (e.getActionCommand().equals("populateList")) + { + this.populateStrategies(); + } + } + + /** + * Checks if an account is stored for this protocol + * @return TRUE, if an account is stored - FALSE otherwise + */ + private boolean hasAccount() + { + ProtocolProviderFactory factory = + DictAccRegWizzActivator.getDictProtocolProviderFactory(); + + ArrayList registeredAccounts = factory.getRegisteredAccounts(); + return !registeredAccounts.isEmpty(); + } + + /** + * Checks if an acount with the given account already exists. + * + * @param host the host of the account to check + * @param port the port of the account to check + * @return TRUE, if an account with the given name already exists, FALSE - + * otherwise + */ + private boolean isExistingAccount(String host, int port) + { + //* + ProtocolProviderFactory factory = + DictAccRegWizzActivator.getDictProtocolProviderFactory(); + + ArrayList registeredAccounts = factory.getRegisteredAccounts(); + + String accHost; + int accPort; + + for (int i = 0; i < registeredAccounts.size(); i++) + { + AccountID accountID = (AccountID) registeredAccounts.get(i); + accHost = (String) accountID.getAccountProperties() + .get(ProtocolProviderFactory.SERVER_ADDRESS); + + if (host.equalsIgnoreCase(accHost)) + { + // We check the port, only if there is an account with the same host + accPort = Integer.parseInt((String) accountID.getAccountProperties() + .get(ProtocolProviderFactory.SERVER_PORT)); + + if (port == accPort) + { + return true; + } + } + } + //*/ + return false; + } + + /** + * Start the thread which will populate the Strategy List + */ + public void populateStrategies() + { + // Clear ArrayLists + this.strategiesAssoc.clear(); + this.strategyList.clear(); + + + //this.populateThread = new StrategyThread(this); + this.populateThread.setHost(this.hostField.getText()) + .setPort(Integer.parseInt(this.portField.getText())) + .sendProcessRequest(); + } + + /** + * Called by the thread, display a message + * @param message a message + */ + public void threadMessage(String message) + { + this.strategyMessage.setText(message); + } + + /** + * Called by the thread, remove the special message section + */ + public void threadRemoveMessage() + { + this.strategyMessage.setText(" "); + } + + /** + * Called by the thread, add a strategy in the list + * @param code The strategy code + * @param description The strategy description + */ + public void threadAddStrategy(String code, String description) + { + this.strategiesAssoc.add(code); + this.strategyList.add(description); + this.strategyBox.setListData(this.strategyList); + } + + /** + * Automatic selection of a strategy + */ + public void autoSelectStrategy() + { + int index = -1; + + if (this.initstrategy.length() > 0) + { // saved strategy + index = this.strategiesAssoc.indexOf(this.initstrategy); + this.initstrategy = ""; + } + if (index < 0) + { + // First case : levenstein distance + index = this.strategiesAssoc.indexOf("lev"); + } + if (index < 0) + { + // Second case : soundex + index = this.strategiesAssoc.indexOf("soundex"); + } + if (index < 0) + { + // Last case : prefix + index = this.strategiesAssoc.indexOf("prefix"); + } + + // If the index is still < 0, we select the first index + if (index < 0) + { + index = 0; + } + if (index < this.strategyBox.getVisibleRowCount()) + { + // If the index is visible row, we don't need to scroll + this.strategyBox.setSelectedIndex(index); + } + else + { + // Otherwise, we scroll to the selected value + this.strategyBox.setSelectedValue(this.strategyList.get(index), true); + } + + } + + /** + * Enables or disable the Next Button and the Strategy Button + * @param e TRUE enables - FALSE disables + */ + public void setStrategyButtonEnable(boolean e) + { + // During all the process the buttons and the fieldsset are in the same state + + this.hostField.setEnabled(e); + this.portField.setEnabled(e); + + this.strategyLoader.setEnabled(e); + wizard.getWizardContainer().setNextFinishButtonEnabled(e); + } +} diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java new file mode 100644 index 0000000..c86ebd6 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/Resources.java @@ -0,0 +1,116 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ + +package net.java.sip.communicator.plugin.dictaccregwizz; + +import java.io.*; +import java.util.*; + +import net.java.sip.communicator.util.*; + +/** + * The <tt>Resources</tt> class manages the access to the internationalization + * properties files and the image resources used in this plugin. + * + * @author ROTH Damien + * @author LITZELMAN Cédric + */ +public class Resources +{ + private static Logger log = Logger.getLogger(Resources.class); + + /** + * The name of the resource, where internationalization strings for this + * plugin are stored. + */ + private static final String STRING_RESOURCE_NAME + = "resources.languages.plugin.dictaccregwizz.resources"; + + /** + * The name of the resource, where paths to images used in this bundle are + * stored. + */ + private static final String IMAGE_RESOURCE_NAME + = "net.java.sip.communicator.plugin.dictaccregwizz.resources"; + + /** + * The string resource bundle. + */ + private static final ResourceBundle STRING_RESOURCE_BUNDLE + = ResourceBundle.getBundle(STRING_RESOURCE_NAME); + + /** + * The image resource bundle. + */ + private static final ResourceBundle IMAGE_RESOURCE_BUNDLE + = ResourceBundle.getBundle(IMAGE_RESOURCE_NAME); + + public static ImageID DICT_LOGO = new ImageID("protocolIcon"); + + public static ImageID PAGE_IMAGE = new ImageID("pageImage"); + + /** + * Returns an internationalized string corresponding to the given key. + * + * @param key The key of the string. + * @return An internationalized string corresponding to the given key. + */ + public static String getString(String key) + { + try + { + return STRING_RESOURCE_BUNDLE.getString(key); + } + catch (MissingResourceException e) + { + return '!' + key + '!'; + } + //return '!' + key + '!'; + } + + /** + * Loads an image from a given image identifier. + * @param imageID The identifier of the image. + * @return The image for the given identifier. + */ + public static byte[] getImage(ImageID imageID) + { + byte[] image = new byte[100000]; + + String path = IMAGE_RESOURCE_BUNDLE.getString(imageID.getId()); + + try + { + Resources.class.getClassLoader() + .getResourceAsStream(path).read(image); + } + catch (IOException e) + { + log.error("Failed to load image:" + path, e); + } + + return image; + } + + /** + * Represents the Image Identifier. + */ + public static class ImageID + { + private String id; + + private ImageID(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + } +} diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/StrategyThread.java b/src/net/java/sip/communicator/plugin/dictaccregwizz/StrategyThread.java new file mode 100644 index 0000000..24754e9 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/StrategyThread.java @@ -0,0 +1,207 @@ +/* + * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.dictaccregwizz; + +import java.util.*; + +import net.java.sip.communicator.util.*; + +/** + * The <tt>StrategyThread</tt> is the thread called by the wizzard to populate + * the strategies list. + * + * @author ROTH Damien + * @author LITZELMANN Cédric + */ +public class StrategyThread + extends Thread +{ + private static Logger logger = Logger.getLogger(StrategyThread.class); + + /** + * The hostname of the DICT server. + */ + private String host; + + /** + * The port used by the DICT server. + */ + private int port; + + /** + * True if the thread is running. + */ + private boolean isRunning = false; + + /** + * True if we need to search the strategies handled by the server in order + * to populate the list. + */ + private boolean needProcess = false; + + /** + * The first page wizard for the DICT protocole. + */ + private FirstWizardPage wizard; + + /** + * The java abstraction of the DICT server. + */ + private DictAdapter adapter = null; + + /** + * Create a new StrategyThread + * @param wizard the wizard for callback methods + */ + public StrategyThread(FirstWizardPage wizard) + { + this.wizard = wizard; + } + + /** + * Thread method running until it's destroy + */ + public void run() + { + while (true) + { + if (this.needProcess()) + { + this.setRunning(true); + this.process(); + this.processDone(); + this.setRunning(false); + } + try + { + this.sleep(500); + } + catch (InterruptedException ie) + { + // Action de log + logger.info("DICT THREAD : " + ie); + } + } + } + + /** + * Search the strategies on the server and populate the list + */ + private void process() + { + ArrayList<String> strategies = null; + String temp[]; + + if (adapter == null) { + adapter = new DictAdapter(); + } + + this.wizard.setStrategyButtonEnable(false); + + // Initialize the connexion + this.wizard.threadMessage("Trying to connect to server"); + if (!adapter.connect(this.host, this.port)) + { + // Connexion attempt failed + this.wizard.threadMessage("Connexion attempt failed, this isn't a" + + "dict server or the server is offline"); + return; + } + + // Retrieving strategies + this.wizard.threadMessage("Retrieving strategies"); + strategies = adapter.getStrategies(); + if (strategies == null) + { + // No strategy found + this.wizard.threadMessage("No strategy found on the server"); + return; + } + + + // Insert the strategies in the list + for (int i=0; i<strategies.size(); i++) + { + temp = strategies.get(i).split(" ", 2); + + this.wizard.threadAddStrategy(temp[0], temp[1].replace("\"", "")); + } + + this.wizard.autoSelectStrategy(); + + // Closing connexion + this.wizard.threadMessage("Closing connexion"); + adapter.close(); + + this.wizard.threadRemoveMessage(); + this.wizard.setStrategyButtonEnable(true); + } + + /** + * Set the hostname of the dict server + * @param host The hostname of the server. + * @return The thread for populating strategie list. + */ + public StrategyThread setHost(String host) + { + this.host = host; + return this; + } + + /** + * Set the port of the dict server + * @param port The port of the DICT server. + * @return The thread for populating strategie list. + */ + public StrategyThread setPort(int port) + { + this.port = port; + return this; + } + + /** + * Checks if the thread is processing a query + * @return TRUE if the thread is processing a query - FALSE otherwise + */ + public synchronized boolean isRunning() + { + return this.isRunning || this.needProcess; + } + + /** + * Marks the thread as running or not + * @param r Activate or desactivate the strategie thread. + */ + public synchronized void setRunning(boolean r) + { + this.isRunning = r; + } + + /** + * Checks if we need to process a query + * @return Returns true if we need to search and populate the strategie list. False otherwise. + */ + private synchronized boolean needProcess() + { + return this.needProcess; + } + + /** + * Init the request + */ + public synchronized void sendProcessRequest() + { + this.needProcess = true; + } + + /** + * Defines that the thread has done the query + */ + private synchronized void processDone() + { + this.needProcess = false; + } +} diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf new file mode 100644 index 0000000..4dcab77 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/dictaccregwizz.manifest.mf @@ -0,0 +1,31 @@ +Bundle-Activator: net.java.sip.communicator.plugin.dictaccregwizz.DictAccRegWizzActivator +Bundle-Name: Dict account registration wizard +Bundle-Description: Dict account registration wizard. +Bundle-Vendor: sip-communicator.org +Bundle-Version: 0.0.1 +Import-Package: org.osgi.framework, + net.java.sip.communicator.util, + net.java.sip.communicator.service.configuration, + net.java.sip.communicator.service.configuration.event, + net.java.sip.communicator.service.protocol, + net.java.sip.communicator.service.protocol.icqconstants, + net.java.sip.communicator.service.protocol.event, + net.java.sip.communicator.service.contactlist, + net.java.sip.communicator.service.contactlist.event, + net.java.sip.communicator.service.gui, + net.java.sip.communicator.service.gui.event, + net.java.sip.communicator.service.browserlauncher, + javax.swing, + javax.swing.event, + javax.swing.table, + javax.swing.text, + javax.swing.text.html, + javax.accessibility, + javax.swing.plaf, + javax.swing.plaf.metal, + javax.swing.plaf.basic, + javax.imageio, + javax.swing.filechooser, + javax.swing.tree, + javax.swing.undo, + javax.swing.border diff --git a/src/net/java/sip/communicator/plugin/dictaccregwizz/resources.properties b/src/net/java/sip/communicator/plugin/dictaccregwizz/resources.properties new file mode 100644 index 0000000..b1146b3 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/dictaccregwizz/resources.properties @@ -0,0 +1,2 @@ +protocolIcon=resources/images/protocol/dict/dict-16x16.png +pageImage=resources/images/protocol/dict/dict-64x64.png |