ShutdownService implementation
- * currently registered in the bundle context of the active
- * UpdateCheckActivator instance.
- *
- * The returned reference to ShutdownService is not being
- * cached.
- *
ShutdownService implementation
- * currently registered in the bundle context of the active
- * UpdateCheckActivator instance
- */
- private static ShutdownService getShutdownService()
- {
- return
- (ShutdownService)
- bundleContext.getService(
- bundleContext.getServiceReference(
- ShutdownService.class.getName()));
- }
-
- /**
- * Returns a reference to the UIService implementation currently registered
- * in the bundle context or null if no such implementation was found.
- *
- * @return a reference to a UIService implementation currently registered
- * in the bundle context or null if no such implementation was found.
- */
- private static UIService getUIService()
- {
- if(uiService == null)
- {
- ServiceReference uiServiceReference
- = bundleContext.getServiceReference(
- UIService.class.getName());
- uiService = (UIService)bundleContext
- .getService(uiServiceReference);
- }
- return uiService;
- }
-
- /**
- * Returns resource service.
- * @return the resource service.
- */
- private static ResourceManagementService getResources()
- {
- if (resourcesService == null)
- {
- ServiceReference serviceReference = bundleContext
- .getServiceReference(ResourceManagementService.class.getName());
-
- if(serviceReference == null)
- return null;
-
- resourcesService = (ResourceManagementService) bundleContext
- .getService(serviceReference);
- }
-
- return resourcesService;
- }
-
- /**
- * Return the certificate verification service impl.
- * @return the CertificateVerification service.
- */
- private static CertificateVerificationService
- getCertificateVerificationService()
- {
- if(certificateService == null)
- {
- ServiceReference certVerifyReference
- = bundleContext.getServiceReference(
- CertificateVerificationService.class.getName());
- if(certVerifyReference != null)
- certificateService
- = (CertificateVerificationService)bundleContext.getService(
- certVerifyReference);
- }
-
- return certificateService;
- }
-
- /**
- * Check the first link as files on the web are sorted by date
- * @return whether we are using the latest version or not.
- */
- private boolean isNewestVersion()
- {
- try
- {
- ServiceReference serviceReference = bundleContext
- .getServiceReference( net.java.sip.communicator.service.version.
- VersionService.class.getName());
-
- VersionService verService = (VersionService) bundleContext
- .getService(serviceReference);
-
- net.java.sip.communicator.service.version.Version
- ver = verService.getCurrentVersion();
-
- String configString = null;
-
- configString = getConfigurationService().getString(
- PROP_UPDATE_LINK);
-
- if(configString == null)
- {
- configString = Resources.getConfigString("update_link");
- }
-
- if(configString == null)
- {
- if (logger.isDebugEnabled())
- logger.debug(
- "Updates are disabled. Faking latest version.");
- return true;
- }
-
- URL url = new URL(configString);
- URLConnection conn = url.openConnection();
-
- if (conn instanceof HttpURLConnection)
- {
- while(((HttpURLConnection)conn).getResponseCode() ==
- HttpURLConnection.HTTP_UNAUTHORIZED
- && !isAuthenticationCanceled)
- {
- if(userCredentials.getUserName() != null)
- {
- errorMessage = getResources().getI18NString(
- "service.gui.AUTHENTICATION_FAILED",
- new String[]{
- userCredentials.getUserName(),
- host});
-
- userCredentials.setUserName(null);
- userCredentials.setPasswordPersistent(false);
- userCredentials = null;
-
- getConfigurationService().removeProperty(
- UPDATE_USERNAME_CONFIG);
- getConfigurationService().removeProperty(
- UPDATE_PASSWORD_CONFIG);
-
- conn = url.openConnection();
- }
- else
- break;
- }
- }
- conn.setConnectTimeout(10000);
- conn.setReadTimeout(10000);
-
- Properties props = new Properties();
- props.load(conn.getInputStream());
-
- lastVersion = props.getProperty("last_version");
- downloadLink = props.getProperty("download_link");
-
- changesLink =
- configString.substring(0, configString.lastIndexOf("/") + 1)
- + props.getProperty("changes_html");
-
- return lastVersion.compareTo(ver.toString()) <= 0;
- }
- catch (Exception e)
- {
- logger.warn("Cannot get and compare versions!");
- if (logger.isDebugEnabled())
- logger.debug("Error was: ", e);
- // if we get an exception this mean we were unable to compare
- // versions will return that current is newest to prevent opening
- // info dialog about new version
- return true;
- }
- }
-
- /**
- * Show dialog informing about new version with button Download which
- * triggers browser launching
- */
- private void UpdaterShow()
- {
- final JDialog dialog = new SIPCommDialog()
- {
- private static final long serialVersionUID = 0L;
-
- protected void close(boolean isEscaped)
- {
- }
- };
- dialog.setTitle(
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_TITLE"));
-
- JEditorPane contentMessage = new JEditorPane();
- contentMessage.setContentType("text/html");
- contentMessage.setOpaque(false);
- contentMessage.setEditable(false);
-
- String dialogMsg =
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_MESSAGE",
- new String[]{getResources()
- .getSettingsString("service.gui.APPLICATION_NAME")});
-
- if(lastVersion != null)
- dialogMsg +=
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_MESSAGE_2",
- new String[]{
- getResources().getSettingsString(
- "service.gui.APPLICATION_NAME"),
- lastVersion});
-
- contentMessage.setText(dialogMsg);
-
- JPanel contentPane = new TransparentPanel(new BorderLayout(5,5));
- contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10,
- 10));
- contentPane.add(contentMessage, BorderLayout.CENTER);
-
- JPanel buttonPanel
- = new TransparentPanel(new FlowLayout(FlowLayout.CENTER, 10,
- 10));
- JButton closeButton = new JButton(
- getResources().getI18NString(
- "plugin.updatechecker.BUTTON_CLOSE"));
-
- closeButton.addActionListener(new ActionListener() {
-
- public void actionPerformed(ActionEvent e)
- {
- dialog.setVisible(false);
- }
- });
-
- if(downloadLink != null)
- {
- JButton downloadButton = new JButton(getResources().
- getI18NString("plugin.updatechecker.BUTTON_DOWNLOAD"));
-
- downloadButton.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- if(OSUtils.IS_LINUX64)
- downloadLink
- = downloadLink.replace("i386", "amd64");
-
- getBrowserLauncher().openURL(downloadLink);
- dialog.dispose();
- }
- });
-
- buttonPanel.add(downloadButton);
- }
-
- buttonPanel.add(closeButton);
-
- contentPane.add(buttonPanel, BorderLayout.SOUTH);
-
- dialog.setContentPane(contentPane);
-
- dialog.pack();
-
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- dialog.setLocation(
- screenSize.width/2 - dialog.getWidth()/2,
- screenSize.height/2 - dialog.getHeight()/2
- );
-
- dialog.setVisible(true);
- }
-
- /**
- * Shows dialog informing about new version with button Install
- * which triggers the update process.
- */
- private void windowsUpdaterShow()
- {
- final JDialog dialog = new SIPCommDialog()
- {
- private static final long serialVersionUID = 0L;
-
- protected void close(boolean isEscaped)
- {
- }
- };
-
- dialog.setTitle(
- getResources().getI18NString("plugin.updatechecker.DIALOG_TITLE"));
-
- JEditorPane contentMessage = new JEditorPane();
- contentMessage.setContentType("text/html");
- contentMessage.setOpaque(false);
- contentMessage.setEditable(false);
-
- /*
- * Use the font of the dialog because contentMessage is just like a
- * label.
- */
- contentMessage.putClientProperty(
- JEditorPane.HONOR_DISPLAY_PROPERTIES,
- Boolean.TRUE);
-
- String dialogMsg =
- getResources().getI18NString("plugin.updatechecker.DIALOG_MESSAGE",
- new String[]{getResources()
- .getSettingsString("service.gui.APPLICATION_NAME")});
-
- if(lastVersion != null)
- dialogMsg +=
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_MESSAGE_2",
- new String[]{
- getResources().getSettingsString(
- "service.gui.APPLICATION_NAME"),
- lastVersion});
-
- contentMessage.setText(dialogMsg);
-
- JPanel contentPane = new SIPCommFrame.MainContentPane();
- contentMessage.setBorder(BorderFactory.createEmptyBorder(10, 0, 20, 0));
- contentPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
- contentPane.add(contentMessage, BorderLayout.NORTH);
-
- JScrollPane scrollChanges = new JScrollPane();
- scrollChanges.setPreferredSize(new Dimension(550, 200));
- JEditorPane changesHtml = new JEditorPane();
- changesHtml.setContentType("text/html");
- changesHtml.setEditable(false);
- changesHtml.setBorder(BorderFactory.createLoweredBevelBorder());
- scrollChanges.setViewportView(changesHtml);
- contentPane.add(scrollChanges, BorderLayout.CENTER);
- try
- {
- changesHtml.setPage(new URL(changesLink));
- } catch (Exception e)
- {
- logger.error("Cannot set changes Page", e);
- }
-
- JPanel buttonPanel
- = new TransparentPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
- JButton closeButton = new JButton(
- getResources().getI18NString("plugin.updatechecker.BUTTON_CLOSE"));
-
- closeButton.addActionListener(new ActionListener() {
-
- public void actionPerformed(ActionEvent e)
- {
- dialog.setVisible(false);
- }
- });
-
- if(downloadLink != null)
- {
- JButton installButton = new JButton(getResources().getI18NString(
- "plugin.updatechecker.BUTTON_INSTALL"));
-
- installButton.addActionListener(new ActionListener() {
-
- public void actionPerformed(ActionEvent e)
- {
- if(OSUtils.IS_WINDOWS64)
- downloadLink = downloadLink.replace("x86", "x64");
-
- dialog.dispose();
- windowsUpdate();
- }
- });
-
- buttonPanel.add(installButton);
- }
-
- buttonPanel.add(closeButton);
-
- contentPane.add(buttonPanel, BorderLayout.SOUTH);
-
- dialog.setContentPane(contentPane);
-
- dialog.pack();
-
- dialog.setLocation(
- Toolkit.getDefaultToolkit().getScreenSize().width/2
- - dialog.getWidth()/2,
- Toolkit.getDefaultToolkit().getScreenSize().height/2
- - dialog.getHeight()/2
- );
-
- dialog.setVisible(true);
- }
-
- /**
- * The update process itself.
- * - Downloads the installer in a temp directory.
- * - Warns that update will shutdown.
- * - Triggers update (installer) in separate process with the help
- * of update.exe and shutdowns.
- */
- private void windowsUpdate()
- {
- File tempF = null;
- try
- {
- final File temp = File.createTempFile("sc-install", ".exe");
- tempF = temp;
-
- URL u = new URL(downloadLink);
- URLConnection uc = u.openConnection();
-
- if (uc instanceof HttpURLConnection)
- {
- if(uc instanceof HttpsURLConnection)
- {
- CertificateVerificationService vs =
- getCertificateVerificationService();
-
- int port = u.getPort();
-
- /* if we do not specify port in the URL
- * (http://domain.org:port) we have to set up the default
- * port of HTTP (80) or
- * HTTPS (443).
- */
- if(port == -1)
- {
- if(u.getProtocol().equals("http"))
- {
- port = 80;
- }
- else if(u.getProtocol().equals("https"))
- {
- port = 443;
- }
- }
-
- ((HttpsURLConnection)uc).setSSLSocketFactory(
- vs.getSSLContext(
- u.getHost(), port).getSocketFactory());
- }
-
- // we don't handle here authentication fails cause
- // still we gone to downloading file we have gone through
- // successful authentication
- }
-
- InputStream in = uc.getInputStream();
-
- // Chain a ProgressMonitorInputStream to the
- // URLConnection's InputStream
- final ProgressMonitorInputStream pin
- = new ProgressMonitorInputStream(null, u.toString(), in);
-
- // Set the maximum value of the ProgressMonitor
- ProgressMonitor pm = pin.getProgressMonitor();
- pm.setMaximum(uc.getContentLength());
-
- final BufferedOutputStream out =
- new BufferedOutputStream(new FileOutputStream(temp));
- new Thread(new Runnable()
- {
- public void run()
- {
- try
- {
- int read = -1;
- byte[] buff = new byte[1024];
- while((read = pin.read(buff)) != -1)
- {
- out.write(buff, 0, read);
- }
- pin.close();
- out.flush();
- out.close();
-
- if(getUIService().getPopupDialog().
- showConfirmPopupDialog(
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_WARN"),
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_TITLE"),
- PopupDialog.YES_NO_OPTION,
- PopupDialog.QUESTION_MESSAGE
- ) != PopupDialog.YES_OPTION)
- {
- return;
- }
-
- String packageName = getResources().getSettingsString(
- "plugin.updatechecker.package.name");
-
- // file saved. Now start updater and shutdown.
- String workingDir = System.getProperty("user.dir");
-
- String updateFileLocation = workingDir + File.separator;
- if(packageName != null)
- updateFileLocation += packageName + "-up2date.exe";
- else
- updateFileLocation += "up2date.exe";
-
- ProcessBuilder processBuilder
- = new ProcessBuilder(
- new String[]
- {
- updateFileLocation,
- "--wait-parent",
- "--allow-elevation",
- temp.getCanonicalPath(),
- workingDir
- });
- processBuilder.start();
-
- getShutdownService().beginShutdown();
-
- } catch (Exception e)
- {
- logger.error("Error saving", e);
- try
- {
- pin.close();
- out.close();
- } catch (Exception e1)
- {}
- }
- }
- }).start();
-
- }
- catch(FileNotFoundException e)
- {
- getUIService().getPopupDialog().showMessagePopupDialog(
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_MISSING_UPDATE"),
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_NOUPDATE_TITLE"),
- PopupDialog.INFORMATION_MESSAGE);
- tempF.delete();
- }
- catch (Exception e)
- {
- if (logger.isInfoEnabled())
- logger.info("Error starting update process!", e);
- tempF.delete();
- }
- }
-
- /**
- * Invokes action for checking for updates.
- */
- private void checkForUpdate()
- {
- if(isNewestVersion())
- {
- if(isAuthenticationCanceled)
- return;
-
- getUIService().getPopupDialog().showMessagePopupDialog(
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_NOUPDATE"),
- getResources().getI18NString(
- "plugin.updatechecker.DIALOG_NOUPDATE_TITLE"),
- PopupDialog.INFORMATION_MESSAGE);
- }
- else
- windowsUpdaterShow();
- }
-
- /**
- * Installs Dummy TrustManager will not try to validate self-signed certs.
- * Fix some problems with not proper use of certs.
- */
- private static void removeDownloadRestrictions()
- {
- HostnameVerifier hv = new HostnameVerifier()
- {
- public boolean verify(String urlHostName, SSLSession session)
- {
- logger.warn("Warning: URL Host: " + urlHostName +
- " vs. " + session.getPeerHost());
- return true;
- }
- };
- HttpsURLConnection.setDefaultHostnameVerifier(hv);
-
- Authenticator.setDefault(new Authenticator()
- {
- protected PasswordAuthentication getPasswordAuthentication()
- {
- if(userCredentials == null)
- {
- // if there is something save return it
- ConfigurationService config = getConfigurationService();
- String uName
- = (String) config.getProperty(UPDATE_USERNAME_CONFIG);
- if(uName != null)
- {
- String pass
- = (String) config.getProperty(UPDATE_PASSWORD_CONFIG);
-
- if(pass != null)
- {
- userCredentials = new UserCredentials();
- userCredentials.setUserName(uName);
- userCredentials.setPassword(new String(
- Base64.decode(pass)).toCharArray());
- userCredentials.setPasswordPersistent(true);
- }
- }
- }
-
- if(userCredentials != null)
- {
- return new PasswordAuthentication(
- userCredentials.getUserName(),
- userCredentials.getPassword());
- }
- else
- {
- host = getRequestingHost();
-
- AuthenticationWindow authWindow = null;
- if(errorMessage == null)
- {
- authWindow = new AuthenticationWindow(host, true, null);
- }
- else
- {
- authWindow = new AuthenticationWindow(
- null, null, host, true, null, errorMessage);
- // we showed the message, remove it
- errorMessage = null;
- }
-
- userCredentials = new UserCredentials();
-
- authWindow.setVisible(true);
-
- if (!authWindow.isCanceled())
- {
- isAuthenticationCanceled = false;
- userCredentials.setUserName(authWindow.getUserName());
- userCredentials.setPassword(authWindow.getPassword());
- userCredentials.setPasswordPersistent(
- authWindow.isRememberPassword());
-
- if(authWindow.isRememberPassword())
- {
- // if save password is checked save the pass
- getConfigurationService().setProperty(
- UPDATE_USERNAME_CONFIG,
- userCredentials.getUserName());
- getConfigurationService().setProperty(
- UPDATE_PASSWORD_CONFIG,
- new String(Base64.encode(
- userCredentials.getPasswordAsString()
- .getBytes())));
- }
-
- return new PasswordAuthentication(
- userCredentials.getUserName(),
- userCredentials.getPassword());
- }
- else
- {
- isAuthenticationCanceled = true;
- userCredentials.setUserName(null);
- userCredentials = null;
-
- getConfigurationService().removeProperty(
- UPDATE_USERNAME_CONFIG);
- getConfigurationService().removeProperty(
- UPDATE_PASSWORD_CONFIG);
- }
-
- return null;
- }
- }
- });
- }
-
- /**
- * The menu entry under tools menu.
- */
- private class UpdateMenuButtonComponent
- extends AbstractPluginComponent
- {
- /**
- * The menu item to use.
- */
- private final JMenuItem updateMenuItem
- = new JMenuItem(getResources().
- getI18NString("plugin.updatechecker.UPDATE_MENU_ENTRY"));
-
- /**
- * Creates update menu component.
- *
- * @param container the container of the update menu component
- */
- UpdateMenuButtonComponent(Container container)
- {
- super(container);
-
- updateMenuItem.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- // run outside swing thread, if password is required we
- // will block the swing
- new Thread()
- {
- public void run()
- {
- checkForUpdate();
- }
- }.start();
- }
- });
- }
-
- /**
- * Get the name of the component.
- *
- * @return name of the component
- */
- public String getName()
- {
- return getResources().getI18NString(
- "plugin.updatechecker.UPDATE_MENU_ENTRY");
- }
-
- /**
- * Get the Component.
- *
- * @return the Component
- */
- public Object getComponent()
- {
- return updateMenuItem;
- }
- }
-
- /**
- * The thread that do the actual checking.
- */
- private class UpdateCheckThread
- implements Runnable
- {
- /**
- * Thread entry point.
- */
- public void run()
- {
- if (OSUtils.IS_WINDOWS)
- {
- // register update button
- HashtableShutdownService implementation
+ * currently registered in the bundle context of the active
+ * UpdateCheckActivator instance.
+ *
+ * The returned reference to ShutdownService is not being
+ * cached.
+ *
ShutdownService implementation
+ * currently registered in the bundle context of the active
+ * UpdateCheckActivator instance
+ */
+ private static ShutdownService getShutdownService()
+ {
+ return ServiceUtils.getService(bundleContext, ShutdownService.class);
+ }
+
+ /**
+ * Returns a reference to the UIService implementation currently registered
+ * in the bundle context or null if no such implementation was found.
+ *
+ * @return a reference to a UIService implementation currently registered
+ * in the bundle context or null if no such implementation was found.
+ */
+ private static UIService getUIService()
+ {
+ if(uiService == null)
+ uiService = ServiceUtils.getService(bundleContext, UIService.class);
+ return uiService;
+ }
+
+ /**
+ * Returns resource service.
+ * @return the resource service.
+ */
+ private static ResourceManagementService getResources()
+ {
+ if (resources == null)
+ {
+ resources
+ = ServiceUtils.getService(
+ bundleContext,
+ ResourceManagementService.class);
+ }
+ return resources;
+ }
+
+ /**
+ * Returns the certificate verification service implementation.
+ *
+ * @return the CertificateVerificationService
+ */
+ private static CertificateVerificationService getCertificateVerification()
+ {
+ if(certificateVerification == null)
+ {
+ certificateVerification
+ = ServiceUtils.getService(
+ bundleContext,
+ CertificateVerificationService.class);
+ }
+ return certificateVerification;
+ }
+
+ /**
+ * Checks the first link as files on the web are sorted by date.
+ *
+ * @return true if we are currently running the newest version;
+ * otherwise, false
+ */
+ private boolean isNewestVersion()
+ {
+ try
+ {
+ ServiceReference serviceReference = bundleContext
+ .getServiceReference( net.java.sip.communicator.service.version.
+ VersionService.class.getName());
+
+ VersionService verService = (VersionService) bundleContext
+ .getService(serviceReference);
+
+ net.java.sip.communicator.service.version.Version
+ ver = verService.getCurrentVersion();
+
+ String configString
+ = getConfiguration().getString(PROP_UPDATE_LINK);
+ if(configString == null)
+ configString = Resources.getConfigString("update_link");
+ if(configString == null)
+ {
+ if (logger.isDebugEnabled())
+ logger.debug(
+ "Updates are disabled. Faking latest version.");
+ return true;
+ }
+
+ URL url = new URL(configString);
+ URLConnection conn = url.openConnection();
+
+ if (conn instanceof HttpURLConnection)
+ {
+ while(((HttpURLConnection)conn).getResponseCode() ==
+ HttpURLConnection.HTTP_UNAUTHORIZED
+ && !isAuthenticationCanceled)
+ {
+ if(userCredentials.getUserName() != null)
+ {
+ errorMessage = getResources().getI18NString(
+ "service.gui.AUTHENTICATION_FAILED",
+ new String[]{
+ userCredentials.getUserName(),
+ host});
+
+ userCredentials.setUserName(null);
+ userCredentials.setPasswordPersistent(false);
+ userCredentials = null;
+
+ getConfiguration().removeProperty(
+ UPDATE_USERNAME_CONFIG);
+ getConfiguration().removeProperty(
+ UPDATE_PASSWORD_CONFIG);
+
+ conn = url.openConnection();
+ }
+ else
+ break;
+ }
+ }
+ conn.setConnectTimeout(10000);
+ conn.setReadTimeout(10000);
+
+ Properties props = new Properties();
+ props.load(conn.getInputStream());
+
+ lastVersion = props.getProperty("last_version");
+ downloadLink = props.getProperty("download_link");
+
+ changesLink =
+ configString.substring(0, configString.lastIndexOf("/") + 1)
+ + props.getProperty("changes_html");
+
+ return lastVersion.compareTo(ver.toString()) <= 0;
+ }
+ catch (Exception e)
+ {
+ logger.warn("Cannot get and compare versions!");
+ if (logger.isDebugEnabled())
+ logger.debug("Error was: ", e);
+ // if we get an exception this mean we were unable to compare
+ // versions will return that current is newest to prevent opening
+ // info dialog about new version
+ return true;
+ }
+ }
+
+ /**
+ * Shows dialog informing about new version with button Download which
+ * triggers browser launching
+ */
+ private void showGenericNewVersionAvailableDialog()
+ {
+ /*
+ * Before showing the dialog, we'll enterCheckForUpdates() in order to
+ * notify that it is not safe to enter "Check for Updates" again. If we
+ * don't manage to show the dialog, we'll have to exitCheckForUpdates().
+ * If we manage though, we'll have to exitCheckForUpdates() but only
+ * once depending on its modality.
+ */
+ final boolean[] exitCheckForUpdates = new boolean[] { false };
+ final JDialog dialog = new SIPCommDialog()
+ {
+ private static final long serialVersionUID = 0L;
+
+ protected void close(boolean escaped)
+ {
+ synchronized (exitCheckForUpdates)
+ {
+ if (exitCheckForUpdates[0])
+ exitCheckForUpdates(this);
+ }
+ }
+ };
+ dialog.setTitle(
+ getResources().getI18NString(
+ "plugin.updatechecker.DIALOG_TITLE"));
+
+ JEditorPane contentMessage = new JEditorPane();
+ contentMessage.setContentType("text/html");
+ contentMessage.setOpaque(false);
+ contentMessage.setEditable(false);
+
+ String dialogMsg =
+ getResources().getI18NString(
+ "plugin.updatechecker.DIALOG_MESSAGE",
+ new String[]{getResources()
+ .getSettingsString("service.gui.APPLICATION_NAME")});
+
+ if(lastVersion != null)
+ dialogMsg +=
+ getResources().getI18NString(
+ "plugin.updatechecker.DIALOG_MESSAGE_2",
+ new String[]{
+ getResources().getSettingsString(
+ "service.gui.APPLICATION_NAME"),
+ lastVersion});
+
+ contentMessage.setText(dialogMsg);
+
+ JPanel contentPane = new TransparentPanel(new BorderLayout(5,5));
+ contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10,
+ 10));
+ contentPane.add(contentMessage, BorderLayout.CENTER);
+
+ JPanel buttonPanel
+ = new TransparentPanel(new FlowLayout(FlowLayout.CENTER, 10,
+ 10));
+ final JButton closeButton = new JButton(
+ getResources().getI18NString(
+ "plugin.updatechecker.BUTTON_CLOSE"));
+
+ closeButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ dialog.dispose();
+ if (exitCheckForUpdates[0])
+ exitCheckForUpdates(dialog);
+ }
+ });
+
+ if(downloadLink != null)
+ {
+ JButton downloadButton
+ = new JButton(
+ getResources().getI18NString(
+ "plugin.updatechecker.BUTTON_DOWNLOAD"));
+
+ downloadButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ if(OSUtils.IS_LINUX64)
+ downloadLink
+ = downloadLink.replace("i386", "amd64");
+
+ getBrowserLauncher().openURL(downloadLink);
+
+ /*
+ * Do the same as the Close button in order to not duplicate
+ * the code.
+ */
+ closeButton.doClick();
+ }
+ });
+
+ buttonPanel.add(downloadButton);
+ }
+
+ buttonPanel.add(closeButton);
+
+ contentPane.add(buttonPanel, BorderLayout.SOUTH);
+
+ dialog.setContentPane(contentPane);
+
+ dialog.pack();
+
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ dialog.setLocation(
+ screenSize.width/2 - dialog.getWidth()/2,
+ screenSize.height/2 - dialog.getHeight()/2);
+
+ synchronized (exitCheckForUpdates)
+ {
+ enterCheckForUpdates(dialog);
+ exitCheckForUpdates[0] = true;
+ }
+ try
+ {
+ dialog.setVisible(true);
+ }
+ finally
+ {
+ synchronized (exitCheckForUpdates)
+ {
+ if (exitCheckForUpdates[0] && dialog.isModal())
+ exitCheckForUpdates(dialog);
+ }
+ }
+ }
+
+ /**
+ * Shows dialog informing about new version with button Install
+ * which triggers the update process.
+ */
+ private void showWindowsNewVersionAvailableDialog()
+ {
+ /*
+ * Before showing the dialog, we'll enterCheckForUpdates() in order to
+ * notify that it is not safe to enter "Check for Updates" again. If we
+ * don't manage to show the dialog, we'll have to exitCheckForUpdates().
+ * If we manage though, we'll have to exitCheckForUpdates() but only
+ * once depending on its modality.
+ */
+ final boolean[] exitCheckForUpdates = new boolean[] { false };
+ final JDialog dialog = new SIPCommDialog()
+ {
+ private static final long serialVersionUID = 0L;
+
+ protected void close(boolean escaped)
+ {
+ synchronized (exitCheckForUpdates)
+ {
+ if (exitCheckForUpdates[0])
+ exitCheckForUpdates(this);
+ }
+ }
+ };
+ ResourceManagementService resources = getResources();
+
+ dialog.setTitle(
+ resources.getI18NString("plugin.updatechecker.DIALOG_TITLE"));
+
+ JEditorPane contentMessage = new JEditorPane();
+ contentMessage.setContentType("text/html");
+ contentMessage.setOpaque(false);
+ contentMessage.setEditable(false);
+
+ /*
+ * Use the font of the dialog because contentMessage is just like a
+ * label.
+ */
+ contentMessage.putClientProperty(
+ JEditorPane.HONOR_DISPLAY_PROPERTIES,
+ Boolean.TRUE);
+
+ String dialogMsg
+ = resources.getI18NString(
+ "plugin.updatechecker.DIALOG_MESSAGE",
+ new String[]
+ {
+ resources.getSettingsString(
+ "service.gui.APPLICATION_NAME")
+ });
+
+ if(lastVersion != null)
+ {
+ dialogMsg
+ += resources.getI18NString(
+ "plugin.updatechecker.DIALOG_MESSAGE_2",
+ new String[]
+ {
+ resources.getSettingsString(
+ "service.gui.APPLICATION_NAME"),
+ lastVersion
+ });
+ }
+
+ contentMessage.setText(dialogMsg);
+
+ JPanel contentPane = new SIPCommFrame.MainContentPane();
+ contentMessage.setBorder(BorderFactory.createEmptyBorder(10, 0, 20, 0));
+ contentPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
+ contentPane.add(contentMessage, BorderLayout.NORTH);
+
+ JScrollPane scrollChanges = new JScrollPane();
+ scrollChanges.setPreferredSize(new Dimension(550, 200));
+ JEditorPane changesHtml = new JEditorPane();
+ changesHtml.setContentType("text/html");
+ changesHtml.setEditable(false);
+ changesHtml.setBorder(BorderFactory.createLoweredBevelBorder());
+ scrollChanges.setViewportView(changesHtml);
+ contentPane.add(scrollChanges, BorderLayout.CENTER);
+ try
+ {
+ Document changesHtmlDocument = changesHtml.getDocument();
+
+ if (changesHtmlDocument instanceof AbstractDocument)
+ {
+ ((AbstractDocument) changesHtmlDocument)
+ .setAsynchronousLoadPriority(0);
+ }
+ changesHtml.setPage(new URL(changesLink));
+ }
+ catch (Exception e)
+ {
+ logger.error("Cannot set changes Page", e);
+ }
+
+ JPanel buttonPanel
+ = new TransparentPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
+ final JButton closeButton
+ = new JButton(
+ resources.getI18NString(
+ "plugin.updatechecker.BUTTON_CLOSE"));
+
+ closeButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ dialog.dispose();
+ if (exitCheckForUpdates[0])
+ exitCheckForUpdates(dialog);
+ }
+ });
+
+ if(downloadLink != null)
+ {
+ JButton installButton
+ = new JButton(
+ resources.getI18NString(
+ "plugin.updatechecker.BUTTON_INSTALL"));
+
+ installButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ if(OSUtils.IS_WINDOWS64)
+ downloadLink = downloadLink.replace("x86", "x64");
+
+ enterCheckForUpdates(null);
+ try
+ {
+ /*
+ * Do the same as the Close button in order to not
+ * duplicate the code.
+ */
+ closeButton.doClick();
+ }
+ finally
+ {
+ boolean windowsUpdateThreadHasStarted = false;
+
+ try
+ {
+ new Thread()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ windowsUpdate();
+ }
+ finally
+ {
+ exitCheckForUpdates(null);
+ }
+ }
+ }.start();
+ windowsUpdateThreadHasStarted = true;
+ }
+ finally
+ {
+ if (!windowsUpdateThreadHasStarted)
+ exitCheckForUpdates(null);
+ }
+ }
+ }
+ });
+
+ buttonPanel.add(installButton);
+ }
+
+ buttonPanel.add(closeButton);
+
+ contentPane.add(buttonPanel, BorderLayout.SOUTH);
+
+ dialog.setContentPane(contentPane);
+
+ dialog.pack();
+
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ dialog.setLocation(
+ screenSize.width/2 - dialog.getWidth()/2,
+ screenSize.height/2 - dialog.getHeight()/2);
+
+ synchronized (exitCheckForUpdates)
+ {
+ enterCheckForUpdates(dialog);
+ exitCheckForUpdates[0] = true;
+ }
+ try
+ {
+ dialog.setVisible(true);
+ }
+ finally
+ {
+ synchronized (exitCheckForUpdates)
+ {
+ if (exitCheckForUpdates[0] && dialog.isModal())
+ exitCheckForUpdates(dialog);
+ }
+ }
+ }
+
+ /**
+ * The update process itself.
+ * - Downloads the setup in a temporary directory.
+ * - Warns that update will shut down.
+ * - Triggers the setup in a separate process and shuts down.
+ */
+ private void windowsUpdate()
+ {
+ final File[] tempFile = new File[1];
+ FileOutputStream tempFileOutputStream = null;
+ boolean deleteTempFile = false;
+
+ try
+ {
+ URL u = new URL(downloadLink);
+
+ tempFileOutputStream = createTempFileOutputStream(u, tempFile);
+
+ URLConnection uc = u.openConnection();
+
+ if (uc instanceof HttpURLConnection)
+ {
+ if(uc instanceof HttpsURLConnection)
+ {
+ CertificateVerificationService cvs
+ = getCertificateVerification();
+
+ int port = u.getPort();
+
+ /* if we do not specify port in the URL
+ * (http://domain.org:port) we have to set up the default
+ * port of HTTP (80) or
+ * HTTPS (443).
+ */
+ if(port == -1)
+ {
+ if(u.getProtocol().equals("http"))
+ port = 80;
+ else if(u.getProtocol().equals("https"))
+ port = 443;
+ }
+
+ ((HttpsURLConnection)uc).setSSLSocketFactory(
+ cvs.getSSLContext(u.getHost(), port)
+ .getSocketFactory());
+ }
+
+ // we don't handle here authentication fails cause
+ // still we gone to downloading file we have gone through
+ // successful authentication
+ }
+
+ // Track the progress of the download.
+ final ProgressMonitorInputStream input
+ = new ProgressMonitorInputStream(
+ null,
+ u.toString(),
+ uc.getInputStream());
+ // Set the maximum value of the ProgressMonitor
+ input.getProgressMonitor().setMaximum(uc.getContentLength());
+
+ final BufferedOutputStream output
+ = new BufferedOutputStream(tempFileOutputStream);
+
+ try
+ {
+ int read = -1;
+ byte[] buff = new byte[1024];
+
+ while((read = input.read(buff)) != -1)
+ output.write(buff, 0, read);
+ try
+ {
+ input.close();
+ }
+ catch (IOException ioe)
+ {
+ /*
+ * Ignore it because we've already downloaded the
+ * setup and that's what matters most.
+ */
+ }
+ output.close();
+
+ if(getUIService().getPopupDialog()
+ .showConfirmPopupDialog(
+ getResources().getI18NString(
+ "plugin.updatechecker.DIALOG_WARN"),
+ getResources().getI18NString(
+ "plugin.updatechecker.DIALOG_TITLE"),
+ PopupDialog.YES_NO_OPTION,
+ PopupDialog.QUESTION_MESSAGE)
+ != PopupDialog.YES_OPTION)
+ return;
+
+ /*
+ * The setup has been downloaded. Now start it and shut
+ * down.
+ */
+ new ProcessBuilder(
+ tempFile[0].getCanonicalPath(),
+ "--wait-parent",
+ "SIP_COMMUNICATOR_AUTOUPDATE_INSTALLDIR=\""
+ + System.getProperty("user.dir")
+ + "\"")
+ .start();
+
+ getShutdownService().beginShutdown();
+ }
+ catch (Exception e)
+ {
+ logger.error("Error saving", e);
+ }
+ finally
+ {
+ try
+ {
+ input.close();
+ }
+ catch (IOException ioe)
+ {
+ }
+ try
+ {
+ output.close();
+ }
+ catch (IOException ioe)
+ {
+ }
+ }
+ }
+ catch(FileNotFoundException fnfe)
+ {
+ deleteTempFile = true;
+ getUIService().getPopupDialog().showMessagePopupDialog(
+ getResources().getI18NString(
+ "plugin.updatechecker.DIALOG_MISSING_UPDATE"),
+ getResources().getI18NString(
+ "plugin.updatechecker.DIALOG_NOUPDATE_TITLE"),
+ PopupDialog.INFORMATION_MESSAGE);
+ }
+ catch (Exception e)
+ {
+ deleteTempFile = true;
+ if (logger.isInfoEnabled())
+ logger.info("Error starting update process!", e);;
+ }
+ finally
+ {
+ /*
+ * If we've failed, delete the temporary file into which the setup
+ * was supposed to be or has already been downloaded.
+ */
+ if (deleteTempFile)
+ {
+ if (tempFileOutputStream != null)
+ {
+ try
+ {
+ tempFileOutputStream.close();
+ }
+ catch (IOException ioe)
+ {
+ // Ignore it because there's nothing else we can do.
+ }
+ }
+ if (tempFile[0] != null)
+ tempFile[0].delete();
+ }
+ }
+ }
+
+ /**
+ * Tries to create a new FileOutputStream for a temporary file into
+ * which the setup is to be downloaded. Because temporary files generally
+ * have random characters in their names and the name of the setup may be
+ * shown to the user, first tries to use the name of the URL to be
+ * downloaded because it likely is prettier.
+ *
+ * @param url the URL of the file to be downloaded
+ * @param tempFile a File array of at least one element which is to
+ * receive the created File instance at index zero (if successful)
+ * @return the newly created FileOutputStream
+ * @throws IOException if anything goes wrong while creating the new
+ * FileOutputStream
+ */
+ private FileOutputStream createTempFileOutputStream(
+ URL url,
+ File[] tempFile)
+ throws IOException
+ {
+ /*
+ * Try to use the name from the URL because it isn't a "randomly"
+ * generated one.
+ */
+ String path = url.getPath();
+
+ File tf = null;
+ FileOutputStream tfos = null;
+
+ if ((path != null) && (path.length() != 0))
+ {
+ int nameBeginIndex =path.lastIndexOf('/');
+ String name;
+
+ if (nameBeginIndex > 0)
+ {
+ name = path.substring(nameBeginIndex + 1);
+ nameBeginIndex = name.lastIndexOf('\\');
+ if (nameBeginIndex > 0)
+ name = name.substring(nameBeginIndex + 1);
+ }
+ else
+ name = path;
+
+ /*
+ * Make sure the extension of the name is EXE so that we're able to
+ * execute it later on.
+ */
+ int nameLength = name.length();
+
+ if (nameLength != 0)
+ {
+ int baseNameEnd = name.lastIndexOf('.');
+
+ if (baseNameEnd == -1)
+ name += ".exe";
+ else if (baseNameEnd == 0)
+ {
+ if (!".exe".equalsIgnoreCase(name))
+ name += ".exe";
+ }
+ else
+ name = name.substring(0, baseNameEnd) + ".exe";
+
+ try
+ {
+ String tempDir = System.getProperty("java.io.tmpdir");
+
+ if ((tempDir != null) && (tempDir.length() != 0))
+ {
+ tf = new File(tempDir, name);
+ tfos = new FileOutputStream(tf);
+ }
+ }
+ catch (FileNotFoundException fnfe)
+ {
+ // Ignore it because we'll try File#createTempFile().
+ }
+ catch (SecurityException se)
+ {
+ // Ignore it because we'll try File#createTempFile().
+ }
+ }
+ }
+
+ // Well, we couldn't use a pretty name so try File#createTempFile().
+ if (tfos == null)
+ {
+ tf = File.createTempFile("sc-setup", ".exe");
+ tfos = new FileOutputStream(tf);
+ }
+
+ tempFile[0] = tf;
+ return tfos;
+ }
+
+ /**
+ * Invokes "Check for Updates".
+ *
+ * @param notifyAboutNewestVersion true if the user is to be
+ * notified if they have the newest version already; otherwise,
+ * false
+ */
+ private synchronized void checkForUpdates(
+ final boolean notifyAboutNewestVersion)
+ {
+ if (inCheckForUpdates > 0)
+ {
+ if (checkForUpdatesDialog != null)
+ checkForUpdatesDialog.toFront();
+ return;
+ }
+
+ Thread checkForUpdatesThread
+ = new Thread()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ if(isNewestVersion())
+ {
+ if(!isAuthenticationCanceled
+ && notifyAboutNewestVersion)
+ {
+ ResourceManagementService resources
+ = getResources();
+
+ getUIService()
+ .getPopupDialog()
+ .showMessagePopupDialog(
+ resources.getI18NString(
+ "plugin.updatechecker.DIALOG_NOUPDATE"),
+ resources.getI18NString(
+ "plugin.updatechecker.DIALOG_NOUPDATE_TITLE"),
+ PopupDialog.INFORMATION_MESSAGE);
+ }
+ }
+ else if (OSUtils.IS_WINDOWS)
+ showWindowsNewVersionAvailableDialog();
+ else
+ showGenericNewVersionAvailableDialog();
+ }
+ finally
+ {
+ exitCheckForUpdates(null);
+ }
+ }
+ };
+
+ checkForUpdatesThread.setDaemon(true);
+
+ enterCheckForUpdates(null);
+ try
+ {
+ checkForUpdatesThread.start();
+ checkForUpdatesThread = null;
+ }
+ finally
+ {
+ if (checkForUpdatesThread != null)
+ exitCheckForUpdates(null);
+ }
+ }
+
+ /**
+ * Notifies this UpdateCheckActivator that a method is entering the
+ * "Check for Updates" functionality and it is thus not allowed to enter it
+ * again.
+ *
+ * @param checkForUpdatesDialog the JDialog associated with the
+ * entry in the "Check for Updates" functionality if any. While "Check for
+ * Updates" cannot be entered again, clicking the "Check for Updates" menu
+ * item will bring the checkForUpdatesDialog to the front.
+ */
+ private synchronized void enterCheckForUpdates(
+ JDialog checkForUpdatesDialog)
+ {
+ inCheckForUpdates++;
+// if (1 == inCheckForUpdates)
+// checkForUpdatesMenuItemComponent.getComponent().setEnabled(false);
+
+ if (checkForUpdatesDialog != null)
+ this.checkForUpdatesDialog = checkForUpdatesDialog;
+ }
+
+ /**
+ * Notifies this UpdateCheckActivator that a method is exiting the
+ * "Check for Updates" functionality and it may thus be allowed to enter it
+ * again.
+ *
+ * @param checkForUpdatesDialog the JDialog which was associated
+ * with the matching call to {@link #enterCheckForUpdates(JDialog)} if any
+ */
+ private synchronized void exitCheckForUpdates(JDialog checkForUpdatesDialog)
+ {
+ if (inCheckForUpdates == 0)
+ throw new IllegalStateException("inCheckForUpdates");
+ else
+ {
+ inCheckForUpdates--;
+// if (0 == inCheckForUpdates)
+// {
+// checkForUpdatesMenuItemComponent.getComponent().setEnabled(
+// true);
+// }
+
+ if ((checkForUpdatesDialog != null)
+ && (this.checkForUpdatesDialog == checkForUpdatesDialog))
+ this.checkForUpdatesDialog = null;
+ }
+ }
+
+ /**
+ * Installs Dummy TrustManager will not try to validate self-signed certs.
+ * Fix some problems with not proper use of certs.
+ */
+ private static void removeDownloadRestrictions()
+ {
+ HostnameVerifier hv = new HostnameVerifier()
+ {
+ public boolean verify(String urlHostName, SSLSession session)
+ {
+ logger.warn("Warning: URL Host: " + urlHostName +
+ " vs. " + session.getPeerHost());
+ return true;
+ }
+ };
+ HttpsURLConnection.setDefaultHostnameVerifier(hv);
+
+ Authenticator.setDefault(new Authenticator()
+ {
+ protected PasswordAuthentication getPasswordAuthentication()
+ {
+ if(userCredentials == null)
+ {
+ // if there is something save return it
+ ConfigurationService config = getConfiguration();
+ String uName
+ = (String) config.getProperty(UPDATE_USERNAME_CONFIG);
+ if(uName != null)
+ {
+ String pass
+ = (String) config.getProperty(UPDATE_PASSWORD_CONFIG);
+
+ if(pass != null)
+ {
+ userCredentials = new UserCredentials();
+ userCredentials.setUserName(uName);
+ userCredentials.setPassword(new String(
+ Base64.decode(pass)).toCharArray());
+ userCredentials.setPasswordPersistent(true);
+ }
+ }
+ }
+
+ if(userCredentials != null)
+ {
+ return new PasswordAuthentication(
+ userCredentials.getUserName(),
+ userCredentials.getPassword());
+ }
+ else
+ {
+ host = getRequestingHost();
+
+ AuthenticationWindow authWindow = null;
+ if(errorMessage == null)
+ {
+ authWindow = new AuthenticationWindow(host, true, null);
+ }
+ else
+ {
+ authWindow = new AuthenticationWindow(
+ null, null, host, true, null, errorMessage);
+ // we showed the message, remove it
+ errorMessage = null;
+ }
+
+ userCredentials = new UserCredentials();
+
+ authWindow.setVisible(true);
+
+ if (!authWindow.isCanceled())
+ {
+ isAuthenticationCanceled = false;
+ userCredentials.setUserName(authWindow.getUserName());
+ userCredentials.setPassword(authWindow.getPassword());
+ userCredentials.setPasswordPersistent(
+ authWindow.isRememberPassword());
+
+ if(authWindow.isRememberPassword())
+ {
+ // if save password is checked save the pass
+ getConfiguration().setProperty(
+ UPDATE_USERNAME_CONFIG,
+ userCredentials.getUserName());
+ getConfiguration().setProperty(
+ UPDATE_PASSWORD_CONFIG,
+ new String(
+ Base64.encode(
+ userCredentials
+ .getPasswordAsString()
+ .getBytes())));
+ }
+
+ return new PasswordAuthentication(
+ userCredentials.getUserName(),
+ userCredentials.getPassword());
+ }
+ else
+ {
+ isAuthenticationCanceled = true;
+ userCredentials.setUserName(null);
+ userCredentials = null;
+
+ getConfiguration().removeProperty(
+ UPDATE_USERNAME_CONFIG);
+ getConfiguration().removeProperty(
+ UPDATE_PASSWORD_CONFIG);
+ }
+
+ return null;
+ }
+ }
+ });
+ }
+
+ /**
+ * Implements PluginComponent for the "Check for Updates" menu
+ * item.
+ */
+ private class CheckForUpdatesMenuItemComponent
+ extends AbstractPluginComponent
+ {
+ /**
+ * The "Check for Updates" menu item.
+ */
+ private final JMenuItem checkForUpdatesMenuItem
+ = new JMenuItem(
+ getResources().getI18NString(
+ "plugin.updatechecker.UPDATE_MENU_ENTRY"));
+
+ /**
+ * Initializes a new "Check for Updates" menu item.
+ *
+ * @param container the container of the update menu component
+ */
+ public CheckForUpdatesMenuItemComponent(Container container)
+ {
+ super(container);
+
+ checkForUpdatesMenuItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ checkForUpdates(true);
+ }
+ });
+ }
+
+ /**
+ * Gets the UI Component of this PluginComponent.
+ *
+ * @return the UI Component of this PluginComponent
+ * @see PluginComponent#getComponent()
+ */
+ public JMenuItem getComponent()
+ {
+ return checkForUpdatesMenuItem;
+ }
+
+ /**
+ * Gets the name of this PluginComponent.
+ *
+ * @return the name of this PluginComponent
+ * @see PluginComponent#getName()
+ */
+ public String getName()
+ {
+ return getResources().getI18NString(
+ "plugin.updatechecker.UPDATE_MENU_ENTRY");
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/updatechecker/updatecheck.manifest.mf b/src/net/java/sip/communicator/plugin/updatechecker/updatecheck.manifest.mf
index 29f266ede..fc2b897c9 100644
--- a/src/net/java/sip/communicator/plugin/updatechecker/updatecheck.manifest.mf
+++ b/src/net/java/sip/communicator/plugin/updatechecker/updatecheck.manifest.mf
@@ -1,18 +1,18 @@
Bundle-Activator: net.java.sip.communicator.plugin.updatechecker.UpdateCheckActivator
-Bundle-Name: UpdateCheckPlugin
-Bundle-Description: A bundle that implements the UpdateCheck Plugin Package.
+Bundle-Description: Checks for software updates
+Bundle-Name: Update Checker
Bundle-Vendor: sip-communicator.org
Bundle-Version: 0.0.1
System-Bundle: yes
Import-Package: org.osgi.framework,
net.java.sip.communicator.service.browserlauncher,
+ net.java.sip.communicator.service.certificate,
net.java.sip.communicator.service.configuration,
net.java.sip.communicator.service.gui,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.resources,
net.java.sip.communicator.service.shutdown,
net.java.sip.communicator.service.version,
- net.java.sip.communicator.service.certificate,
net.java.sip.communicator.util,
net.java.sip.communicator.util.swing,
javax.imageio,