com.aptana.ide.update.preferences.AutomaticUpdatesPreferencePage.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.ide.update.preferences.AutomaticUpdatesPreferencePage.java

Source

/**
 * This file Copyright (c) 2005-2010 Aptana, Inc. This program is
 * dual-licensed under both the Aptana Public License and the GNU General
 * Public license. You may elect to use one or the other of these licenses.
 * 
 * This program is distributed in the hope that it will be useful, but
 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
 * NONINFRINGEMENT. Redistribution, except as permitted by whichever of
 * the GPL or APL you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or modify this
 * program under the terms of the GNU General Public License,
 * Version 3, as published by the Free Software Foundation.  You should
 * have received a copy of the GNU General Public License, Version 3 along
 * with this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Aptana provides a special exception to allow redistribution of this file
 * with certain Eclipse Public Licensed code and certain additional terms
 * pursuant to Section 7 of the GPL. You may view the exception and these
 * terms on the web at http://www.aptana.com/legal/gpl/.
 * 
 * 2. For the Aptana Public License (APL), this program and the
 * accompanying materials are made available under the terms of the APL
 * v1.0 which accompanies this distribution, and is available at
 * http://www.aptana.com/legal/apl/.
 * 
 * You may view the GPL, Aptana's exception and additional terms, and the
 * APL in the file titled license.html at the root of the corresponding
 * plugin containing this source file.
 * 
 * Any modifications to this file must keep this entire header intact.
 */
package com.aptana.ide.update.preferences;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.osgi.service.prefs.BackingStoreException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.aptana.ide.core.IdeLog;
import com.aptana.ide.core.ui.SWTUtils;
import com.aptana.ide.server.jetty.JettyPlugin;
import com.aptana.ide.update.Activator;
import com.aptana.ide.update.manager.IPluginManager;

/**
 * A preference page for automatic updates
 * 
 * @author Ingo Muschenetz
 */
public class AutomaticUpdatesPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {

    private static final String P_UPDATE_POLICY_URL = "updatePolicyURL"; //$NON-NLS-1$
    private static final String DELIMETER = ","; //$NON-NLS-1$
    private static final String ADDED_UPDATE_SITES = "ADDED_UPDATE_SITES"; //$NON-NLS-1$
    private static final String POLICY_XML_RC = "http://beta.aptana.com/beta/policy.xml"; //$NON-NLS-1$
    private static final String POLICY_XML_NIGHTLY = "http://nightly.aptana.com/nightly/policy.xml"; //$NON-NLS-1$
    private static final String POLICY_XML_DEV_START = "http://developer.aptana.com/"; //$NON-NLS-1$
    private static final String POLICY_XML_DEV_END = "/policy.xml"; //$NON-NLS-1$

    private Button currentRadio;
    private Button nextRadio;
    private Button nightlyRadio;
    private Button developerRadio;
    private Text branchText;

    /**
     * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
     */
    public void init(IWorkbench workbench) {
    }

    /**
     * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
     */
    protected Control createContents(Composite parent) {
        Composite container = new Composite(parent, SWT.NULL);
        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        container.setLayout(layout);

        Link link = new Link(container, SWT.NULL);
        link.setText(Messages.AutomaticUpdatesPreferencePage_UseP2UpdatePreferences);
        link.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                PreferencesUtil.createPreferenceDialogOn(getShell(), getPluginManager().getUpdatePreferencePageId(),
                        null, null);
            }
        });

        createSpacer(container, 1);

        Group updateTypeGroup = new Group(container, SWT.NONE);
        updateTypeGroup.setText(Messages.AutomaticUpdatesPreferencePage_WhatTypesOfUpdates);
        layout = new GridLayout();
        layout.numColumns = 3;
        updateTypeGroup.setLayout(layout);
        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        updateTypeGroup.setLayoutData(gd);

        Label basicLabel = new Label(updateTypeGroup, SWT.NONE);
        basicLabel.setText(Messages.AutomaticUpdatesPreferencePage_AptanaWillDownloadOnNextRestart);
        basicLabel.setFont(SWTUtils.getDefaultSmallFont());
        gd = new GridData();
        gd.horizontalSpan = 3;
        gd.verticalIndent = 10;
        basicLabel.setLayoutData(gd);
        //      boolean isEnabled = CoreUIPlugin.isKeyValid();
        boolean isEnabled = true;
        basicLabel.setEnabled(isEnabled);

        SelectionAdapter adapter = new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                pageChanged();
            }
        };

        currentRadio = new Button(updateTypeGroup, SWT.RADIO);
        currentRadio.setText(Messages.AutomaticUpdatesPreferencePage_StableReleasesOnly);
        gd = new GridData();
        gd.horizontalSpan = 3;
        currentRadio.setLayoutData(gd);
        currentRadio.addSelectionListener(adapter);
        currentRadio.setEnabled(isEnabled);

        nextRadio = new Button(updateTypeGroup, SWT.RADIO);
        nextRadio.setText(Messages.AutomaticUpdatesPreferencePage_NextCandidateBuilds);
        gd = new GridData();
        gd.horizontalSpan = 3;
        nextRadio.setLayoutData(gd);
        nextRadio.addSelectionListener(adapter);
        nextRadio.setEnabled(isEnabled);

        nightlyRadio = new Button(updateTypeGroup, SWT.RADIO);
        nightlyRadio.setText(Messages.AutomaticUpdatesPreferencePage_NightlyBuilds);
        gd = new GridData();
        gd.horizontalSpan = 3;
        nightlyRadio.setLayoutData(gd);
        nightlyRadio.addSelectionListener(adapter);
        nightlyRadio.setEnabled(isEnabled);

        Label developerLabel = new Label(updateTypeGroup, SWT.NONE);
        developerLabel.setText(Messages.AutomaticUpdatesPreferencePage_ForAdvancedUsers);
        developerLabel.setFont(SWTUtils.getDefaultSmallFont());
        gd = new GridData();
        gd.horizontalSpan = 3;
        gd.verticalIndent = 10;
        developerLabel.setLayoutData(gd);
        developerLabel.setEnabled(isEnabled);

        developerRadio = new Button(updateTypeGroup, SWT.RADIO);
        developerRadio.setText(Messages.AutomaticUpdatesPreferencePage_SpecifyBranchName);
        gd = new GridData();
        gd.horizontalSpan = 2;
        developerRadio.setLayoutData(gd);
        developerRadio.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                testBranchName();
            }
        });
        developerRadio.setEnabled(isEnabled);

        branchText = new Text(updateTypeGroup, SWT.BORDER);
        gd = new GridData();
        gd.grabExcessVerticalSpace = true;
        gd.horizontalAlignment = SWT.FILL;
        branchText.setLayoutData(gd);
        branchText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                testBranchName();
            }
        });
        branchText.setEnabled(isEnabled);

        initialize();

        Dialog.applyDialogFont(container);
        return container;
    }

    /**
     * 
     */
    private void testBranchName() {
        if (developerRadio.getSelection() && branchText.getText().equals("")) //$NON-NLS-1$
        {
            // developer button is selected but branch field is empty
            setValid(false);
            setErrorMessage(Messages.AutomaticUpdatesPreferencePage_MustSpecifyBranchName);
        } else {
            setValid(true);
            setErrorMessage(null);
        }
    }

    /**
     * createSpacer
     * 
     * @param composite
     * @param columnSpan
     */
    private static void createSpacer(Composite composite, int columnSpan) {
        Label label = new Label(composite, SWT.NONE);
        GridData gd = new GridData();
        gd.horizontalSpan = columnSpan;
        label.setLayoutData(gd);
    }

    private void initialize() {
        String updateUrl = Platform.getPreferencesService().getString(Activator.PLUGIN_ID, P_UPDATE_POLICY_URL, "", //$NON-NLS-1$
                null);
        if (updateUrl.equals("")) //$NON-NLS-1$
        {
            currentRadio.setSelection(true);
        } else if (updateUrl.equals(POLICY_XML_RC)) {
            nextRadio.setSelection(true);
        } else if (updateUrl.equals(POLICY_XML_NIGHTLY)) {
            nightlyRadio.setSelection(true);
        } else if (updateUrl.startsWith(POLICY_XML_DEV_START)) {
            developerRadio.setSelection(true);
            // retrieves the branch name
            int length = POLICY_XML_DEV_START.length();
            int lastSlash = updateUrl.indexOf('/', length);
            String branchName = updateUrl.substring(length, lastSlash);
            branchText.setText(branchName);
        }
        pageChanged();
    }

    private void pageChanged() {
        branchText.setEnabled(developerRadio.getSelection());
    }

    /**
     * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
     */
    protected void performDefaults() {
        super.performDefaults();
        pageChanged();
    }

    /**
     * @see org.eclipse.jface.preference.PreferencePage#performOk()
     */
    public boolean performOk() {
        String updateUrl = Platform.getPreferencesService().getString(Activator.PLUGIN_ID, P_UPDATE_POLICY_URL, "", //$NON-NLS-1$
                null);
        final String oldUpdateUrl = updateUrl;
        if (currentRadio.getSelection()) {
            updateUrl = ""; //$NON-NLS-1$
        } else if (nextRadio.getSelection()) {
            updateUrl = POLICY_XML_RC;
        } else if (nightlyRadio.getSelection()) {
            updateUrl = POLICY_XML_NIGHTLY;
        } else if (developerRadio.getSelection()) {
            updateUrl = POLICY_XML_DEV_START + branchText.getText() + POLICY_XML_DEV_END;
        }
        IEclipsePreferences prefs = (new InstanceScope()).getNode(Activator.PLUGIN_ID);
        prefs.put(P_UPDATE_POLICY_URL, updateUrl);
        try {
            prefs.flush();
        } catch (BackingStoreException e) {
        }
        savePortalUpdateType();

        doP2Scheduling(oldUpdateUrl, updateUrl);

        return true;
    }

    private void doP2Scheduling(final String oldUpdateURL, final String updateURL) {
        Job job = new Job(Messages.AutomaticUpdatesPreferencePage_Changing_update_stream_job_title) {
            @Override
            protected IStatus run(IProgressMonitor monitor) {
                // Parse the policy.xml file and add all the update sites it points to
                addPolicyFileUpdateSites();
                // Now tell P2 automatic update to check for updates (it will immediately if set to check on startup.
                // Otherwise it'll just check at next scheduled time)
                getPluginManager().checkForUpdates(false);
                return Status.OK_STATUS;
            }

            private void addPolicyFileUpdateSites() {
                if (oldUpdateURL != null && updateURL != null && (oldUpdateURL.equals(updateURL)))
                    return; // value hasn't changed.

                // wipe the last list of sites we added from our known repositories!
                wipeOutLastAddedUpdateSites();

                if (updateURL == null || updateURL.trim().length() == 0)
                    return;
                // Parse the policy.xml file and add all the update sites as repositories!
                Document doc = getPolicyXMLDocument(updateURL);
                List<String> addedSites = new ArrayList<String>();
                if (doc != null) {
                    NodeList urlMaps = doc.getElementsByTagName("url-map"); //$NON-NLS-1$
                    for (int i = 0; i < urlMaps.getLength(); i++) {
                        Element urlMap = (Element) urlMaps.item(i);
                        String updateSite = urlMap.getAttribute("url"); //$NON-NLS-1$
                        try {
                            URL updateSiteURL = new URL(updateSite);
                            if (getPluginManager().addUpdateSite(updateSiteURL)) {
                                addedSites.add(updateSite);
                            }
                        } catch (Exception e) {
                            IdeLog.logError(Activator.getDefault(), e.getMessage(), e);
                        }
                    }
                }
                // Store the added sites in a pref value so when user changes settings we can wipe the last group
                // of added ones...
                storeAddedUpdateSites(addedSites);
            }

            private void wipeOutLastAddedUpdateSites() {
                String addedSitesRaw = Platform.getPreferencesService().getString(Activator.PLUGIN_ID,
                        ADDED_UPDATE_SITES, "", //$NON-NLS-1$
                        null);
                String[] lastAdded = addedSitesRaw.split(DELIMETER);
                // TODO Load the list of URLs added from the prefs
                try {
                    for (String oldAddedURL : lastAdded) {
                        if (oldAddedURL == null || oldAddedURL.trim().length() == 0)
                            continue;
                        URL location = new URL(oldAddedURL);
                        getPluginManager().removeUpdateSite(location);
                    }
                } catch (Exception e) {
                    IdeLog.logError(Activator.getDefault(), e.getMessage(), e);
                }
            }

            private void storeAddedUpdateSites(List<String> addedSites) {
                StringBuilder builder = new StringBuilder();
                for (String addedSite : addedSites) {
                    builder.append(DELIMETER);
                    builder.append(addedSite);
                }
                if (builder.length() > 0)
                    builder.deleteCharAt(0);
                (new InstanceScope()).getNode(Activator.PLUGIN_ID).put(ADDED_UPDATE_SITES, builder.toString());
            }

            private Document getPolicyXMLDocument(final String updateURL) {
                InputStream stream = null;
                Document doc = null;
                try {
                    stream = new URL(updateURL).openStream();
                    doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream);
                } catch (Exception e) {
                    IdeLog.logError(Activator.getDefault(), e.getMessage(), e);
                } finally {
                    try {
                        if (stream != null)
                            stream.close();
                    } catch (IOException e) {
                        // ignore
                    }
                }
                return doc;
            }

        };
        job.setSystem(true);
        job.setPriority(Job.LONG);
        job.schedule();
    }

    public static void savePortalUpdateType() {
        // updates the corresponding type for the portal update structure since
        // it knows the server.jetty plugin, not vise-versa
        // the default is production
        String portalUpdateType = com.aptana.ide.server.jetty.preferences.IPreferenceConstants.PORTAL_UPDATE_RELEASE;

        String updateUrl = Platform.getPreferencesService().getString(Activator.PLUGIN_ID, P_UPDATE_POLICY_URL, "", //$NON-NLS-1$
                null);
        if (updateUrl.equals(POLICY_XML_RC)) {
            // next
            portalUpdateType = com.aptana.ide.server.jetty.preferences.IPreferenceConstants.PORTAL_UPDATE_NEXT;
        } else if (updateUrl.equals(POLICY_XML_NIGHTLY)) {
            // nightly
            portalUpdateType = com.aptana.ide.server.jetty.preferences.IPreferenceConstants.PORTAL_UPDATE_NIGHTLY;
        } else if (updateUrl.startsWith(POLICY_XML_DEV_START)) {
            // retrieves the branch name
            int length = POLICY_XML_DEV_START.length();
            int lastSlash = updateUrl.indexOf('/', length);
            portalUpdateType = updateUrl.substring(length, lastSlash);
        }

        JettyPlugin.getDefault().getPreferenceStore().setValue(
                com.aptana.ide.server.jetty.preferences.IPreferenceConstants.PORTAL_UPDATE_TYPE, portalUpdateType);
    }

    private static IPluginManager getPluginManager() {
        return Activator.getDefault().getPluginManager();
    }
}