Package org.rssowl.ui.internal.dialogs

Source Code of org.rssowl.ui.internal.dialogs.UpdateDialog

/*   **********************************************************************  **
**   Copyright notice                                                       **
**                                                                          **
**   (c) 2005-2009 RSSOwl Development Team                                  **
**   http://www.rssowl.org/                                                 **
**                                                                          **
**   All rights reserved                                                    **
**                                                                          **
**   This program and the accompanying materials are made available under   **
**   the terms of the Eclipse Public License v1.0 which accompanies this    **
**   distribution, and is available at:                                     **
**   http://www.rssowl.org/legal/epl-v10.html                               **
**                                                                          **
**   A copy is found in the file epl-v10.html and important notices to the  **
**   license from the team is found in the textfile LICENSE.txt distributed **
**   in this package.                                                       **
**                                                                          **
**   This copyright notice MUST APPEAR in all copies of the file!           **
**                                                                          **
**   Contributors:                                                          **
**     RSSOwl Development Team - initial API and implementation             **
**                                                                          **
**  **********************************************************************  */

package org.rssowl.ui.internal.dialogs;

import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.update.core.ICategory;
import org.eclipse.update.core.IFeature;
import org.eclipse.update.core.IURLEntry;
import org.eclipse.update.operations.IInstallFeatureOperation;
import org.rssowl.core.Owl;
import org.rssowl.core.internal.persist.pref.DefaultPreferences;
import org.rssowl.core.persist.pref.IPreferenceScope;
import org.rssowl.core.util.LoggingSafeRunnable;
import org.rssowl.core.util.StringUtils;
import org.rssowl.ui.internal.OwlUI;
import org.rssowl.ui.internal.util.BrowserUtils;
import org.rssowl.ui.internal.util.LayoutUtils;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.concurrent.atomic.AtomicBoolean;

/**
* The <code>UpdateDialog</code> shows when updates are available and will show
* a description of the update.
*
* @author bpasero
*/
public class UpdateDialog extends TitleAreaDialog {
  private static final String PLUGINS = "plugins"; //$NON-NLS-1$
  private static final String FEATURES = "features"; //$NON-NLS-1$

  private LocalResourceManager fResources;
  private final IInstallFeatureOperation[] fUpdates;
  private StyledText fUpdateInfoTextRight;
  private StyledText fUpdateInfoTextLeft;
  private StyledText fUpdateInfoTextBottom;
  private Button fUpdateOnStartupCheck;
  private IPreferenceScope fPreferences;
  private final boolean fCanUpdate;

  /**
   * @param parentShell
   * @param updates
   */
  public UpdateDialog(Shell parentShell, IInstallFeatureOperation[] updates) {
    super(parentShell);
    fResources = new LocalResourceManager(JFaceResources.getResources());
    fPreferences = Owl.getPreferenceService().getGlobalScope();
    fUpdates = updates;
    fCanUpdate = canUpdate();
  }

  /*
   * @see org.eclipse.jface.dialogs.TitleAreaDialog#close()
   */
  @Override
  public boolean close() {
    if (!fUpdateOnStartupCheck.isDisposed())
      fPreferences.putBoolean(DefaultPreferences.UPDATE_ON_STARTUP, fUpdateOnStartupCheck.getSelection());
    fResources.dispose();
    return super.close();
  }

  /*
   * @see org.eclipse.jface.dialogs.Dialog#okPressed()
   */
  @Override
  protected void okPressed() {

    /* Show an Extra Warning if Update will Fail due to missing write Permissions */
    if (!fCanUpdate) {
      MessageDialog dialog = new MessageDialog(getShell(), Messages.UpdateDialog_WARNING, null, Messages.UpdateDialog_MISSING_PERMISSIONS_WARNING, MessageDialog.WARNING, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 0);
      if (dialog.open() != 0)
        return;
    }

    super.okPressed();
  }

  /*
   * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
   */
  @Override
  protected void configureShell(Shell shell) {
    super.configureShell(shell);
    shell.setText(Messages.UpdateDialog_UPDATE_AVAILABLE);
  }

  /*
   * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
   */
  @Override
  protected Control createDialogArea(Composite parent) {

    /* Title */
    setTitle(Messages.UpdateDialog_UPDATE_AVAILABLE);

    /* Title Image */
    setTitleImage(OwlUI.getImage(fResources, "icons/wizban/update_wiz.png")); //$NON-NLS-1$

    /* Title Message */
    setMessage(Messages.UpdateDialog_NEW_VERSION_MSG);

    /* Separator */
    new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL).setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));

    /* Composite to hold all components */
    Composite composite = new Composite(parent, SWT.NONE);
    composite.setLayout(LayoutUtils.createGridLayout(1, 5, 5));
    composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    Composite updateInfoContainer = new Composite(composite, SWT.BORDER);
    updateInfoContainer.setLayout(LayoutUtils.createGridLayout(2, 5, 5, 0, 5, false));
    updateInfoContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    updateInfoContainer.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

    fUpdateInfoTextLeft = new StyledText(updateInfoContainer, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP);
    fUpdateInfoTextLeft.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
    fUpdateInfoTextLeft.setLineSpacing(5);
    fUpdateInfoTextLeft.setEnabled(false);
    fUpdateInfoTextLeft.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

    fUpdateInfoTextRight = new StyledText(updateInfoContainer, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP);
    fUpdateInfoTextRight.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
    fUpdateInfoTextRight.setLineSpacing(5);
    fUpdateInfoTextRight.setEnabled(false);
    fUpdateInfoTextRight.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

    fUpdateInfoTextBottom = new StyledText(updateInfoContainer, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP);
    fUpdateInfoTextBottom.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
    ((GridData) fUpdateInfoTextBottom.getLayoutData()).widthHint = 300;
    fUpdateInfoTextBottom.setLineSpacing(5);
    fUpdateInfoTextBottom.setEnabled(false);
    fUpdateInfoTextBottom.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));

    /* Fill in Update Details */
    showUpdateDescription();

    /* Link to open RSSOwl.org */
    Link link = new Link(updateInfoContainer, SWT.NONE);
    link.setBackground(updateInfoContainer.getBackground());
    link.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 2, 1));
    link.setText(Messages.UpdateDialog_VISIT_HP);
    link.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        BrowserUtils.openLinkExternal("http://www.rssowl.org"); //$NON-NLS-1$
      }
    });

    /* Add Option to Control Checking for Updates Automatically */
    fUpdateOnStartupCheck = new Button(composite, SWT.CHECK);
    fUpdateOnStartupCheck.setText(Messages.UpdateDialog_UPDATE_ON_STARTUP);
    fUpdateOnStartupCheck.setSelection(fPreferences.getBoolean(DefaultPreferences.UPDATE_ON_STARTUP));

    /* Show Error if Update will Fail due to missing Write Permissions */
    if (!fCanUpdate)
      setErrorMessage(Messages.UpdateDialog_MISSING_PERMISSIONS_ERROR);

    /* Separator */
    new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL).setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));

    applyDialogFont(composite);

    return composite;
  }

  /* Create a temporary file in the install location to check if write permissions are qualified */
  private boolean canUpdate() {
    final AtomicBoolean canUpdate = new AtomicBoolean(true);

    SafeRunnable.run(new LoggingSafeRunnable() {
      public void run() throws Exception {
        Location installLocation = Platform.getInstallLocation();
        if (installLocation != null && installLocation.getURL() != null) {
          File installDirectory = toFile(installLocation.getURL());
          if (!installDirectory.isFile()) {
            File pluginsDir = new File(installDirectory, PLUGINS);
            File featuresDir = new File(installDirectory, FEATURES);
            if (pluginsDir.isDirectory() && featuresDir.isDirectory()) {
              try {

                /* Check Write Permission in Plugins Directory */
                writeTempFile(canUpdate, pluginsDir);

                /* Check Write Permission in Features Directory */
                if (canUpdate.get())
                  writeTempFile(canUpdate, featuresDir);
              } catch (IOException e) {
                canUpdate.set(false);
              } catch (SecurityException e) {
                canUpdate.set(false);
              }
            }
          }
        }
      }

      private void writeTempFile(AtomicBoolean canUpdate, File dir) throws IOException {
        File tmpFile = File.createTempFile("permcheck", ".tmp", dir); //$NON-NLS-1$ //$NON-NLS-2$
        tmpFile.deleteOnExit();
        canUpdate.set(tmpFile.exists() && tmpFile.canWrite());
        tmpFile.delete();
      }
    });

    return canUpdate.get();
  }

  private static File toFile(URL url) {
    try {
      return new File(url.toURI());
    } catch (URISyntaxException e) {
      return new File(url.getPath());
    }
  }

  @SuppressWarnings("deprecation")
  private void showUpdateDescription() {
    String oldVer = null;
    String newVer = null;
    long dlSize = 0;
    String provider = null;
    String description = null;
    boolean isQualifierUpdate = false;

    if (fUpdates != null && fUpdates.length > 0) {
      IFeature oldFeature = fUpdates[0].getOldFeature();
      IFeature newFeature = fUpdates[0].getFeature();

      /* Versions */
      org.eclipse.core.runtime.PluginVersionIdentifier oldVersion = (oldFeature != null) ? oldFeature.getVersionedIdentifier().getVersion() : null;
      org.eclipse.core.runtime.PluginVersionIdentifier newVersion = newFeature.getVersionedIdentifier().getVersion();
      if (oldVersion != null)
        oldVer = oldVersion.getMajorComponent() + "." + oldVersion.getMinorComponent() + "." + oldVersion.getServiceComponent(); //$NON-NLS-1$ //$NON-NLS-2$
      newVer = newVersion.getMajorComponent() + "." + newVersion.getMinorComponent() + "." + newVersion.getServiceComponent(); //$NON-NLS-1$ //$NON-NLS-2$

      /* Special Treat Case of a Qualifier Update */
      if (newVer.equals(oldVer) && oldVersion != null) {
        isQualifierUpdate = true;
        String newQualifierComponent = newVersion.getQualifierComponent();
        String oldQualifierComponent = oldVersion.getQualifierComponent();
        if (newQualifierComponent.length() == 12 && oldQualifierComponent.length() == 12) {
          newVer += " (" + formatQualifier(newQualifierComponent) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
          oldVer += " (" + formatQualifier(oldQualifierComponent) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
        } else {
          newVer += "." + newQualifierComponent; //$NON-NLS-1$
          oldVer += "." + oldQualifierComponent; //$NON-NLS-1$
        }
      }

      /* Other */
      dlSize = newFeature.getDownloadSize() * 1000;
      provider = newFeature.getProvider();

      /* Description */
      if (!isQualifierUpdate) {
        ICategory[] categories = newFeature.getSite().getCategories();
        if (categories.length > 0) {
          IURLEntry descriptionEntry = categories[0].getDescription();
          if (descriptionEntry != null)
            description = descriptionEntry.getAnnotation();
        }
      } else
        description = Messages.UpdateDialog_QUALIFIER_UPDATE_DESCRIPTION;

      showUpdateDescription(oldVer, newVer, dlSize, provider, description);
    }
  }

  private String formatQualifier(String qualifier) {
    if (qualifier.length() == 12)
      return qualifier.substring(0, 4) + "-" + qualifier.substring(4, 6) + "-" + qualifier.substring(6, 8); //$NON-NLS-1$ //$NON-NLS-2$

    return qualifier;
  }

  private void showUpdateDescription(String oldVer, String newVer, long dlSize, String provider, String description) {

    /* Old Version */
    if (StringUtils.isSet(oldVer)) {
      int offset = fUpdateInfoTextLeft.getText().length();
      fUpdateInfoTextLeft.append(Messages.UpdateDialog_CURRENT_VERSION);
      fUpdateInfoTextLeft.setStyleRange(new StyleRange(offset, fUpdateInfoTextLeft.getText().length() - offset, null, null, SWT.BOLD));
      fUpdateInfoTextRight.append(oldVer);
      fUpdateInfoTextLeft.append("\n"); //$NON-NLS-1$
      fUpdateInfoTextRight.append("\n"); //$NON-NLS-1$
    }

    /* New Version */
    if (StringUtils.isSet(newVer)) {
      int offset = fUpdateInfoTextLeft.getText().length();
      fUpdateInfoTextLeft.append(Messages.UpdateDialog_NEW_VERSION);
      fUpdateInfoTextLeft.setStyleRange(new StyleRange(offset, fUpdateInfoTextLeft.getText().length() - offset, null, null, SWT.BOLD));
      fUpdateInfoTextRight.append(newVer);
      fUpdateInfoTextLeft.append("\n"); //$NON-NLS-1$
      fUpdateInfoTextRight.append("\n"); //$NON-NLS-1$
    }

    /* Provider */
    if (StringUtils.isSet(provider)) {
      int offset = fUpdateInfoTextLeft.getText().length();
      fUpdateInfoTextLeft.append(Messages.UpdateDialog_UPDATE_PROVIDER);
      fUpdateInfoTextLeft.setStyleRange(new StyleRange(offset, fUpdateInfoTextLeft.getText().length() - offset, null, null, SWT.BOLD));
      fUpdateInfoTextRight.append(provider);
      fUpdateInfoTextLeft.append("\n"); //$NON-NLS-1$
      fUpdateInfoTextRight.append("\n"); //$NON-NLS-1$
    }

    /* Size */
    if (dlSize > 0) {
      int offset = fUpdateInfoTextLeft.getText().length();
      fUpdateInfoTextLeft.append(Messages.UpdateDialog_DL_SIZE);
      fUpdateInfoTextLeft.setStyleRange(new StyleRange(offset, fUpdateInfoTextLeft.getText().length() - offset, null, null, SWT.BOLD));
      fUpdateInfoTextRight.append(OwlUI.getSize((int) dlSize));
      fUpdateInfoTextLeft.append("\n"); //$NON-NLS-1$
      fUpdateInfoTextRight.append("\n"); //$NON-NLS-1$
    }

    /* Description */
    if (StringUtils.isSet(description)) {
      int offset = fUpdateInfoTextBottom.getText().length();
      fUpdateInfoTextBottom.append(Messages.UpdateDialog_DESCRIPTION);
      fUpdateInfoTextBottom.append("\n"); //$NON-NLS-1$
      fUpdateInfoTextBottom.setStyleRange(new StyleRange(offset, fUpdateInfoTextBottom.getText().length() - offset, null, null, SWT.BOLD));
      fUpdateInfoTextBottom.append(description);
    }
  }

  /*
   * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
   */
  @Override
  protected void createButtonsForButtonBar(Composite parent) {
    createButton(parent, IDialogConstants.OK_ID, Messages.UpdateDialog_DOWNLOAD_INSTALL, true).setFocus();
    createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
  }

  /*
   * @see org.eclipse.jface.window.Window#getShellStyle()
   */
  @Override
  protected int getShellStyle() {
    int style = SWT.TITLE | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.RESIZE | SWT.CLOSE | getDefaultOrientation();

    return style;
  }

  /*
   * @see org.eclipse.jface.dialogs.Dialog#initializeBounds()
   */
  @Override
  protected void initializeBounds() {
    super.initializeBounds();

    Shell shell = getShell();

    /* Minimum Size */
    int minWidth = convertHorizontalDLUsToPixels(OwlUI.MIN_DIALOG_WIDTH_DLU);
    int minHeight = shell.computeSize(minWidth, SWT.DEFAULT).y;

    /* Required Size */
    Point requiredSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);

    shell.setSize(Math.max(minWidth, requiredSize.x), Math.max(minHeight, requiredSize.y));
    LayoutUtils.positionShell(shell);
  }
}
TOP

Related Classes of org.rssowl.ui.internal.dialogs.UpdateDialog

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.