Package org.freeplane.main.application

Source Code of org.freeplane.main.application.UpdateCheckAction

package org.freeplane.main.application;

import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.border.Border;

import org.freeplane.core.resources.ResourceController;
import org.freeplane.core.ui.AFreeplaneAction;
import org.freeplane.core.ui.MenuBuilder;
import org.freeplane.core.ui.components.UITools;
import org.freeplane.core.util.FreeplaneVersion;
import org.freeplane.core.util.LogUtils;
import org.freeplane.core.util.TextUtils;
import org.freeplane.features.mode.Controller;
import org.freeplane.features.mode.ModeController;
import org.freeplane.features.ui.IMapViewChangeListener;
import org.freeplane.main.addons.AddOnProperties;
import org.freeplane.main.addons.AddOnsController;

/**
* Checks for updates.
*
* @author robert ladstaetter
*/
class UpdateCheckAction extends AFreeplaneAction {
  private static boolean autorunEnabled = true;
  private static Timer autorunTimer = null;
  private static final int CHECK_TIME = 30 * 1000;
  private static final String CHECK_UPDATES_AUTOMATICALLY = "check_updates_automatically";
  private static final String LAST_UPDATE_CHECK_TIME = "last_update_check_time";
  private static final String LAST_UPDATE_VERSION = "last_update_verson";
  /**
   * the sid.
   */
  private static final long serialVersionUID = 1L;
  private static final int TWO_DAYS = 1 * 24 * 60 * 60 * 1000;
  private static final String UPDATE_BUTTON_LOCATION = "main_toolbar_update";
  private static final String UPDATE_BUTTON_PATH = UPDATE_BUTTON_LOCATION + "/checkUpdate";
//  /**
//   * the url where to download the newest version
//   */
//  private static final String WEB_DOWNLOAD_LOCATION_KEY = "webDownloadLocation";
  /**
   * the url to check the local version against
   */
  private static final String WEB_UPDATE_LOCATION_KEY = "webUpdateLocation";

  /**
   * the client which asks a remote repository for the current version of the program.
   */
  public UpdateCheckAction() {
    super("UpdateCheckAction");
    final Controller controller = Controller.getCurrentController();
    controller.getMapViewManager().addMapViewChangeListener(new IMapViewChangeListener() {
      public void afterViewChange(final Component oldView, final Component newView) {
        if (newView == null) {
          return;
        }
        controller.getViewController().invokeLater(new Runnable() {
          public void run() {
            removeMe();
          }
        });
        setTimer();
      }

      public void afterViewClose(final Component oldView) {
      }

      public void afterViewCreated(final Component mapView) {
      }

      public void beforeViewChange(final Component oldView, final Component newView) {
      }

      private void removeMe() {
        controller.getMapViewManager().removeMapViewChangeListener(this);
      }
    });
  }

  public void actionPerformed(final ActionEvent e) {
    final boolean autoRun = e.getSource().equals(autorunTimer);
    if (autorunTimer != null) {
      autorunTimer.stop();
      autorunTimer = null;
    }
    new Thread(new Runnable() {
      public void run() {
        checkForUpdates(autoRun);
      }
    }, "checkForUpdates").start();
  }

  private void addUpdateButton(final FreeplaneVersion lastVersion) {
    Controller controller = Controller.getCurrentController();
    final Set<String> modes = controller.getModes();
    for (final String mode : modes) {
      ModeController modeController = controller.getModeController(mode);
      if(!modeController.getUserInputListenerFactory().useRibbonMenu()) { 
        final MenuBuilder menuBuilder = modeController.getUserInputListenerFactory()
            .getMenuBuilder(MenuBuilder.class);
        if (lastVersion == null || lastVersion.compareTo(FreeplaneVersion.getVersion()) <= 0) {
          ResourceController.getResourceController().setProperty(LAST_UPDATE_VERSION, "");
          if (menuBuilder.get(UPDATE_BUTTON_PATH) != null) {
            menuBuilder.removeElement(UPDATE_BUTTON_PATH);
          }
          continue;
        }
        ResourceController.getResourceController().setProperty(LAST_UPDATE_VERSION, lastVersion.toString());
        final String updateAvailable = TextUtils.format("new_version_available", lastVersion.toString());
        controller.getViewController().out(updateAvailable);
        putValue(SHORT_DESCRIPTION, updateAvailable);
        putValue(LONG_DESCRIPTION, updateAvailable);
        if (menuBuilder.get(UPDATE_BUTTON_PATH) == null) {
          menuBuilder.addAction(UPDATE_BUTTON_LOCATION, UPDATE_BUTTON_PATH, UpdateCheckAction.this,
              MenuBuilder.AS_CHILD);
        }
      }
    }
  }

  private void checkForUpdates(final boolean autoRun) {
    final Date now = new Date();
    ResourceController.getResourceController().setProperty(LAST_UPDATE_CHECK_TIME, Long.toString(now.getTime()));
    final Locale defaultLocale = Locale.getDefault();
    final String language = defaultLocale.getLanguage();
    final String DEFAULT_LANGUAGE = "en";
    final String translatedWebUpdate = getWebUpdateUrl(language);
    final FreeplaneVersion localVersion = FreeplaneVersion.getVersion();
    final HttpVersionClient translatedVersionClient = new HttpVersionClient(translatedWebUpdate, localVersion);
    FreeplaneVersion lastTranslatedVersion = translatedVersionClient.getRemoteVersion();
    if (lastTranslatedVersion == null) {
      lastTranslatedVersion = localVersion;
    }
    final String history;
    final FreeplaneVersion lastVersion;
    final boolean connectSuccessfull;
    if (!language.equals(DEFAULT_LANGUAGE)) {
      final String defaultWebUpdate = getWebUpdateUrl(DEFAULT_LANGUAGE);
      final HttpVersionClient defaultVersionClient = new HttpVersionClient(defaultWebUpdate,
          lastTranslatedVersion);
      lastVersion = defaultVersionClient.getRemoteVersion();
      history = defaultVersionClient.getHistory() + translatedVersionClient.getHistory();
      connectSuccessfull = defaultVersionClient.isSuccessful();
    }
    else {
      lastVersion = lastTranslatedVersion;
      history = translatedVersionClient.getHistory();
      connectSuccessfull = translatedVersionClient.isSuccessful();
    }
   
    checkForAddonsUpdates();
    Controller.getCurrentController().getViewController().invokeLater(new Runnable() {
      public void run() {
        addUpdateButton(lastVersion);
        if (autoRun) {
          return;
        }
        showUpdateDialog(connectSuccessfull, localVersion, lastVersion, history);
      }
    });
  }

 
  // looking for new versions of add-ons
  // and store the latest version as a property
  private void checkForAddonsUpdates() {
    // loop on add-ons
    List<AddOnProperties> installedAddOns = AddOnsController.getController().getInstalledAddOns();
    LogUtils.info("checking for updates of " + installedAddOns.size() + " add-ons");
    for (AddOnProperties addOnProperties : installedAddOns) {
      FreeplaneVersion addOnLocalVersion = toFreeplaneVersion(addOnProperties.getVersion());
      // get the update-url for this add-on
      // append the current add-on version for
      // - statistics (appending a freeplane installation unique id would enable building add-on usage statistics)
      // - handling special cases ? (maybe we could send the freeplane version too)     
      final URL updateUrl = addOnProperties.getUpdateUrl();
            if (updateUrl != null) {
        final String addOnUpdateRequest = updateUrl + "?v=" + addOnLocalVersion.toString();
        final HttpVersionClient versionClient = new HttpVersionClient(addOnUpdateRequest, addOnLocalVersion);
        final boolean connectSuccesfull;
        final FreeplaneVersion latestVersion = versionClient.getRemoteVersion();

        connectSuccesfull = versionClient.isSuccessful();
        if (connectSuccesfull) {
          addOnProperties.setLatestVersion(latestVersion.toString());
          if (versionClient.getRemoteVersionDownloadUrl() != null) {
            addOnProperties.setLatestVersionDownloadUrl(versionClient.getRemoteVersionDownloadUrl());
          }
          if (versionClient.getRemoteVersionChangelogUrl() != null) {
            addOnProperties.setLatestVersionChangelogUrl(versionClient.getRemoteVersionChangelogUrl());
          }
        }
      }
        }
  }

    private String getWebUpdateUrl(final String language) {
    {
      final String webUpdateUrl = ResourceController.getResourceController().getProperty(WEB_UPDATE_LOCATION_KEY);
      final FreeplaneVersion localVersion = FreeplaneVersion.getVersion();
      final StringBuilder sb = new StringBuilder(webUpdateUrl);
      final String type = localVersion.getType();
      if(! type.equals("")){
        sb.append(type);
        sb.append('/');
      }
      sb.append("history_");
      sb.append(language);
      sb.append(".txt");
      return sb.toString();
    }
  }

  private FreeplaneVersion getKnownNewVersion() {
    final FreeplaneVersion localVersion = FreeplaneVersion.getVersion();
    final String property = ResourceController.getResourceController().getProperty(LAST_UPDATE_VERSION);
    if (property.equals("")) {
      return null;
    }
   
    FreeplaneVersion lastVersion = FreeplaneVersion.getVersion(property);
    if (lastVersion.compareTo(localVersion) <= 0) {
      lastVersion = null;
    }
    return lastVersion;
  }

  private void setTimer() {
    if (autorunEnabled == false) {
      return;
    }
    autorunEnabled = ResourceController.getResourceController().getBooleanProperty(CHECK_UPDATES_AUTOMATICALLY);
    if (autorunEnabled == false) {
      return;
    }
    autorunEnabled = false;
    final Date now = new Date();
    final long nextCheckMillis = ResourceController.getResourceController().getLongProperty(LAST_UPDATE_CHECK_TIME,
        0)
            + TWO_DAYS;
    final Date nextCheckDate = new Date(nextCheckMillis);
    if (now.before(nextCheckDate)) {
      final FreeplaneVersion knownNewVersion = getKnownNewVersion();
      addUpdateButton(knownNewVersion);
      return;
    }
    autorunTimer = new Timer(CHECK_TIME, this);
    autorunTimer.setRepeats(false);
    autorunTimer.start();
  }


  private void showUpdateDialog(final boolean connectSuccesfull, final FreeplaneVersion localVersion,
                                final FreeplaneVersion newVersion, final String history) {
    if (connectSuccesfull == false) {
      showUpdateDialog("can_not_connect_to_info_server", newVersion, history);
    } else {
      showUpdateDialog("new_version_available", newVersion, history);
    }
   
    return;
  }

  private int showUpdateDialog(final String info, final FreeplaneVersion freeplaneLatestVersion, final String history) {
   
    // dialog layout
    // - messagePane (verticalBox)
    // |- gridPane (GridBagLayout)
    //     Components | Installed version | Latestversion | Changelog button | Got to download button
    //
    // |- preferences label
    // |- checkbox for automatic update
   
    final Box messagePane = Box.createVerticalBox();
    final JLabel emptyLabel = new JLabel("");
   
    // grid setup
    final JPanel gridPane = new JPanel(new GridBagLayout());
    gridPane.setAlignmentX(JLabel.LEFT_ALIGNMENT);
   
    final Border paddingBorder = BorderFactory.createEmptyBorder(0, 10, 10, 0);
    gridPane.setBorder(BorderFactory.createCompoundBorder(paddingBorder,paddingBorder));
   
    final GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        int gridRow = 0;
        c.weightx = 0.5;
       
   
    // table headers
    final JLabel componentHeader = new JLabel(TextUtils.getText("updater.component"), SwingConstants.CENTER);
    final JLabel installedVersionHeader = new JLabel(TextUtils.getText("updater.version.installed"), SwingConstants.CENTER);
    final JLabel latestVersionHeader = new JLabel(TextUtils.getText("updater.version.latest"), SwingConstants.CENTER);
   
    final Font boldFont = new Font(componentHeader.getFont().getName(),Font.BOLD,componentHeader.getFont().getSize());
   
    componentHeader.setFont(boldFont);
    installedVersionHeader.setFont(boldFont);
    latestVersionHeader.setFont(boldFont);
   
    componentHeader.setBorder(paddingBorder);
    installedVersionHeader.setBorder(paddingBorder);
    latestVersionHeader.setBorder(paddingBorder);

    // adding headers
        c.gridy = 0;
       
        c.gridx = 0;
    gridPane.add(componentHeader, c);
    c.gridx = 1;
    gridPane.add(installedVersionHeader, c);
    c.gridx = 2;
    gridPane.add(latestVersionHeader, c);
    c.gridx = 3;
    gridPane.add(emptyLabel, c);
    c.gridx = 4;
    gridPane.add(emptyLabel, c);
       
    // first row : freeplane
        c.gridy = 1;
       
    final JLabel freeplaneLabel = new JLabel("Freeplane");
    final FreeplaneVersion freeplaneLocalVersion = FreeplaneVersion.getVersion();
    final JLabel freeplaneInstalledVersionLabel = new JLabel(freeplaneLocalVersion.toString(), SwingConstants.CENTER);
    final JLabel freeplaneLatestVersionLabel;

    JButton updateButton;
    JButton changelogButton;
    final Locale defaultLocale = Locale.getDefault();
    final String language = defaultLocale.getLanguage();
    final String translatedWebUpdate = getWebUpdateUrl(language);
   
    changelogButton = new JButton(TextUtils.getText("updater.viewChangelog"));
    changelogButton.addActionListener(openUrlListener);
    changelogButton.setActionCommand(translatedWebUpdate);
   
    updateButton = new JButton(TextUtils.getText("updater.goToDownload"));
    updateButton.addActionListener(openUrlListener);
    updateButton.setActionCommand("http://freeplane.sourceforge.net");

    Boolean needsUpdate = Boolean.FALSE;
    if (freeplaneLatestVersion != null) {
      if (freeplaneLocalVersion.compareTo(freeplaneLatestVersion) < 0) {
        needsUpdate = Boolean.TRUE;
      } else {
        needsUpdate = Boolean.FALSE;
      }
      freeplaneLatestVersionLabel = new JLabel(freeplaneLatestVersion.toString(), SwingConstants.CENTER);
    } else {
      freeplaneLatestVersionLabel = new JLabel(TextUtils.getText("updater.version.unknown"), SwingConstants.CENTER);
      freeplaneLatestVersionLabel.setToolTipText(TextUtils.getText(info));
    }
    changelogButton.setEnabled(needsUpdate);
    updateButton.setEnabled(needsUpdate);

    c.gridx = 0;
    gridPane.add(freeplaneLabel, c);
    c.gridx = 1;
    gridPane.add(freeplaneInstalledVersionLabel, c);
    c.gridx = 2;
    gridPane.add(freeplaneLatestVersionLabel, c);
    c.gridx = 3;
    gridPane.add(changelogButton, c);
    c.gridx = 4;
    gridPane.add(updateButton, c);
   

    final List<AddOnProperties> installedAddOns = AddOnsController.getController().getInstalledAddOns();
    gridRow = 3;
    for (AddOnProperties addOnProperties : installedAddOns) {
      FreeplaneVersion addOnLocalVersion = toFreeplaneVersion(addOnProperties.getVersion());
      FreeplaneVersion addOnLatestVersion = toFreeplaneVersion(addOnProperties.getLatestVersion());
     
      final JLabel addOnInstalledVersionLabel = new JLabel(addOnLocalVersion.toString(), SwingConstants.CENTER);
      final JLabel addOnLatestVersionLabel;
      needsUpdate = Boolean.FALSE;
      if (addOnLatestVersion != null) {
        if (addOnLocalVersion.compareTo(addOnLatestVersion) < 0) {
          needsUpdate = Boolean.TRUE;
        }
        addOnLatestVersionLabel = new JLabel(addOnLatestVersion.toString(), SwingConstants.CENTER);
      } else {
        addOnLatestVersionLabel = new JLabel(TextUtils.getText("updater.version.unknown"), SwingConstants.CENTER);
        if (addOnProperties.getUpdateUrl() != null) {
          addOnLatestVersionLabel.setToolTipText(TextUtils.getText("updater.version.unreachable") + " " + addOnProperties.getUpdateUrl());
        } else {
          addOnLatestVersionLabel.setToolTipText(TextUtils.getText("updater.version.noUpdateUrl"));
        }
      }
     
      final JLabel addOnLabel = new JLabel(TextUtils.getText("addons." + addOnProperties.getName()));
      c.gridx = 0;
      c.gridy = gridRow;
      gridPane.add(addOnLabel, c);
     
      c.gridx = 1;
      c.gridy = gridRow;
      gridPane.add(addOnInstalledVersionLabel, c);
     
      c.gridx = 2;
      c.gridy = gridRow;
      gridPane.add(addOnLatestVersionLabel, c);
     
      c.gridx = 3;
      c.gridy = gridRow;
      changelogButton = new JButton(TextUtils.getText("updater.viewChangelog"));
      changelogButton.addActionListener(openUrlListener);
      if (addOnProperties.getLatestVersionChangelogUrl() != null) {
        changelogButton.setActionCommand(addOnProperties.getLatestVersionChangelogUrl().toString());
      } else if (addOnProperties.getUpdateUrl() != null) {
        changelogButton.setActionCommand(String.valueOf(addOnProperties.getUpdateUrl()));
      }
      gridPane.add(changelogButton,c );
      changelogButton.setEnabled(needsUpdate);
     
      c.gridx = 4;
      c.gridy = gridRow;
      updateButton = new JButton(TextUtils.getText("updater.goToDownload"));
      updateButton.addActionListener(openUrlListener);
      if (addOnProperties.getLatestVersionDownloadUrl() != null) {
        updateButton.setActionCommand(addOnProperties.getLatestVersionDownloadUrl().toString());
      } else if (addOnProperties.getHomepage() != null) {
        updateButton.setActionCommand(addOnProperties.getHomepage().toString());
      }
      gridPane.add(updateButton, c);
      updateButton.setEnabled(needsUpdate);

      gridRow++;
    }
    messagePane.add(gridPane);
   
   
    final JLabel confLabel = new JLabel(TextUtils.getText("preferences"));
    confLabel.setFont(boldFont);
    messagePane.add(confLabel);
    final JCheckBox updateAutomatically = new JCheckBox(TextUtils
          .getText("OptionPanel.check_updates_automatically"), ResourceController.getResourceController()
          .getBooleanProperty(CHECK_UPDATES_AUTOMATICALLY));
      updateAutomatically.setAlignmentX(JLabel.LEFT_ALIGNMENT);
    messagePane.add(updateAutomatically);
    final Object[] options;
    options = new Object[] { TextUtils.getText("simplyhtml.closeBtnName") };

   
    final int choice = JOptionPane.showOptionDialog(Controller.getCurrentController().getViewController().getFrame(), messagePane,
        TextUtils.getText("updatecheckdialog"), JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null,
        options, options[0]);
    ResourceController.getResourceController().setProperty(CHECK_UPDATES_AUTOMATICALLY,
        Boolean.toString(updateAutomatically.isSelected()));
    return choice;
  }

  // note: FreeplaneVersion.getVersion() handles leading 'v' gracefully
    private FreeplaneVersion toFreeplaneVersion(String versionString) {
        try {
          return FreeplaneVersion.getVersion(versionString);
        } catch (Exception e) {
          return FreeplaneVersion.getVersion("0.0.0");
        }
    }


  private ActionListener openUrlListener = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
      try {
        Controller.getCurrentController().getViewController().openDocument(
            new URL( ((JButton) e.getSource()).getActionCommand()) );
      }
      catch (final MalformedURLException ex) {
        UITools.errorMessage(TextUtils.getText("url_error") + "\n" + ex);
      }
      catch (final Exception ex) {
        UITools.errorMessage(ex);
      }
    }
  };

}
TOP

Related Classes of org.freeplane.main.application.UpdateCheckAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.