com.aptana.ide.subscription.SubscriptionManager.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.ide.subscription.SubscriptionManager.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.subscription;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.equinox.security.storage.ISecurePreferences;
import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
import org.eclipse.equinox.security.storage.StorageException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.activities.IWorkbenchActivitySupport;
import org.eclipse.ui.progress.UIJob;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import com.aptana.ide.core.IdeLog;
import com.aptana.ide.core.model.AuthUtils;
import com.aptana.ide.core.model.IModelListener;
import com.aptana.ide.core.model.IModifiableObject;
import com.aptana.ide.core.model.user.AptanaUser;
import com.aptana.ide.core.model.user.User;
import com.aptana.ide.core.ui.CoreUIUtils;
import com.aptana.ide.subscription.model.SubscriptionService;

public class SubscriptionManager {

    private static final String SUBSCRIPTION_URL = "http://staging-aptanalivestaging.aptanacloud.com/subscriptions.xml"; //$NON-NLS-1$
    private static final String SECURE_PREF_NODE_SERVICES = SubscriptionPlugin.PLUGIN_ID + "/services"; //$NON-NLS-1$
    private static final String SECURE_PREF_NODE_USER = SubscriptionPlugin.PLUGIN_ID + "/user"; //$NON-NLS-1$
    private static final String PREF_LAST_USER = "LastSignedInUser"; //$NON-NLS-1$

    private static final long DAY_TIME = 1000 * 60 * 60 * 24;
    // make the default 30 days for requiring user to sign in
    private static final int ALLOWED_DAY = 30;
    // grace period of 7 days before the activities are truly turned off
    private static final int GRACE_PERIOD = 7;

    private static final Set<String> EMPTY_SET = new HashSet<String>();

    private static SubscriptionManager fManager = null;

    private static IWorkbenchActivitySupport activitySupport = PlatformUI.getWorkbench().getActivitySupport();;

    private User fUser;
    private String fCurrentUsername;

    private IModelListener fModelListener = new IModelListener() {

        public void modelChanged(IModifiableObject object) {
            if (object instanceof User) {
                if (fUser.hasCredentials()) {
                    // saves the current user
                    fCurrentUsername = fUser.getUsername();
                    getPreferenceStore().setValue(PREF_LAST_USER, fCurrentUsername);
                    // updates the subscriptions
                    update();
                } else {
                    // user signed out
                    // stores the time for the 30-day check
                    ISecurePreferences prefs = getUserSecurePreferences();
                    try {
                        prefs.putLong(fCurrentUsername, (new Date()).getTime(), true);
                    } catch (StorageException e) {
                        logError(e);
                    }
                }
            }
        }
    };

    public static SubscriptionManager getInstance() {
        if (fManager == null) {
            fManager = new SubscriptionManager();
        }
        return fManager;
    }

    public void init() {
        fUser.addListener(fModelListener);
    }

    public void shutdown() {
        fUser.removeListener(fModelListener);
    }

    public void update() {
        try {
            // access the latest remote content for the current user
            URL url = getURL(SUBSCRIPTION_URL);
            URLConnection connection = url.openConnection();
            connection.setUseCaches(false);
            connection.setConnectTimeout(1000);
            connection.addRequestProperty("Cache-Control", "no-cache"); //$NON-NLS-1$ //$NON-NLS-2$
            connection.addRequestProperty("Authorization", AuthUtils //$NON-NLS-1$
                    .getAuthorizationHeader(fUser.getUsername(), fUser.getPassword()));

            InputStream in = connection.getInputStream();
            StringBuilder text = new StringBuilder();
            byte[] bytes = new byte[1024];
            BufferedInputStream input = new BufferedInputStream(in);
            int bytesRead;
            while ((bytesRead = input.read(bytes)) != -1) {
                text.append(new String(bytes, 0, bytesRead));
            }
            // parses the content
            String content = text.toString();
            setEnabledActivityIds(parseXML(content));

            // saves the latest content
            ISecurePreferences prefs = getServicesSecurePreferences();
            prefs.put(fUser.getUsername(), content, true);
        } catch (IOException e) {
            // Failed to grab the remote content; falls back to the cached
            // version
            setEnabledActivityIds(parseCache(fUser.getUsername()));
        } catch (StorageException e) {
            logError(e);
        }
    }

    private SubscriptionManager() {
        fUser = AptanaUser.getSignedInUser();

        if (fUser.hasCredentials()) {
            // user is already signed in
            fCurrentUsername = fUser.getUsername();
            update();
        } else {
            fCurrentUsername = getPreferenceStore().getString(PREF_LAST_USER);
            // finds out when was the last time the previous user was logged in
            ISecurePreferences prefs = getUserSecurePreferences();
            try {
                long lastSignedOutTime = prefs.getLong(fCurrentUsername, 0);
                if (lastSignedOutTime == 0) {
                    // never signed in; turns off all Live activities
                    setEnabledActivityIds(new HashSet<String>());
                } else {
                    Set<String> activityIds = parseCache(fCurrentUsername);
                    if (activityIds.isEmpty()) {
                        // user has not subscribed to any Live features, so no
                        // need to warn
                        return;
                    }

                    long currentTime = (new Date()).getTime();
                    if (currentTime - lastSignedOutTime >= (ALLOWED_DAY + GRACE_PERIOD) * DAY_TIME) {
                        // grace period is passed; turns off all Live activities
                        setEnabledActivityIds(new HashSet<String>());
                    } else if (currentTime - lastSignedOutTime >= ALLOWED_DAY * DAY_TIME) {
                        // warns the user to log in or otherwise the Live
                        // activities will be turned off
                        showWarning();
                    } else {
                        setEnabledActivityIds(activityIds);
                    }
                }
            } catch (StorageException e) {
                logError(e);
            }
        }
    }

    private Set<String> parseXML(String content) {
        try {
            XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
            SubscriptionContentHandler handler = new SubscriptionContentHandler();
            reader.setContentHandler(handler);
            reader.parse(new InputSource(new StringReader(content)));

            final Set<String> activityIds = new HashSet<String>();
            SubscriptionService[] services = handler.getServices();
            String[] ids;
            for (SubscriptionService service : services) {
                ids = service.getActivityIds();
                for (String id : ids) {
                    activityIds.add(id);
                }
            }
            return activityIds;
        } catch (SAXException e) {
            logError(e);
        } catch (ParserConfigurationException e) {
            logError(e);
        } catch (IOException e) {
            logError(e);
        }
        return EMPTY_SET;
    }

    private Set<String> parseCache(String username) {
        ISecurePreferences prefs = getServicesSecurePreferences();
        try {
            String content = prefs.get(username, null);
            if (content != null) {
                return parseXML(content);
            }
        } catch (StorageException se) {
            logError(se);
        }
        return EMPTY_SET;
    }

    /**
     * Specify a set of activities to be enabled.
     * 
     * @param ids
     *            the set of activity ids being enabled
     */
    private void setEnabledActivityIds(final Set<String> ids) {
        Job job = new UIJob("Enabling Live Activities") { //$NON-NLS-1$

            @Override
            public IStatus runInUIThread(IProgressMonitor monitor) {
                activitySupport.setEnabledActivityIds(ids);
                return Status.OK_STATUS;
            }

        };
        job.setSystem(true);
        job.schedule();
    }

    private static void showWarning() {
        CoreUIUtils.getDisplay().asyncExec(new Runnable() {

            public void run() {
                MessageDialog.openWarning(CoreUIUtils.getActiveShell(), Messages.SubscriptionManager_WarningTitle,
                        MessageFormat.format(Messages.SubscriptionManager_WarningMessage, ALLOWED_DAY));
            }

        });
    }

    private static ISecurePreferences getServicesSecurePreferences() {
        ISecurePreferences root = SecurePreferencesFactory.getDefault();
        ISecurePreferences node = root.node(SECURE_PREF_NODE_SERVICES);
        return node;
    }

    private static ISecurePreferences getUserSecurePreferences() {
        ISecurePreferences root = SecurePreferencesFactory.getDefault();
        ISecurePreferences node = root.node(SECURE_PREF_NODE_USER);
        return node;
    }

    private static IPreferenceStore getPreferenceStore() {
        return SubscriptionPlugin.getDefault().getPreferenceStore();
    }

    private static URL getURL(String location) throws MalformedURLException {
        try {
            return new URL(location);
        } catch (MalformedURLException e) {
            return (new File(location)).toURI().toURL();
        }
    }

    private static void logError(Exception e) {
        IdeLog.logError(SubscriptionPlugin.getDefault(), e.getMessage(), e);
    }
}