org.eclipse.buckminster.jnlp.MaterializationUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.buckminster.jnlp.MaterializationUtils.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2007, Cloudsmith Inc.
 * The code, documentation and other materials contained herein have been
 * licensed under the Eclipse Public License - v 1.0 by the copyright holder
 * listed above, as the Initial Contributor under such license. The text of
 * such license is available at www.eclipse.org.
 ******************************************************************************/

package org.eclipse.buckminster.jnlp;

import static org.eclipse.buckminster.jnlp.MaterializationConstants.DEFAULT_MATERIALIZATION_FOLDER;
import static org.eclipse.buckminster.jnlp.MaterializationConstants.ERROR_CODE_403_EXCEPTION;
import static org.eclipse.buckminster.jnlp.MaterializationConstants.ERROR_CODE_404_EXCEPTION;
import static org.eclipse.buckminster.jnlp.MaterializationConstants.ERROR_CODE_500_EXCEPTION;
import static org.eclipse.buckminster.jnlp.MaterializationConstants.ERROR_CODE_ARTIFACT_EXCEPTION;
import static org.eclipse.buckminster.jnlp.MaterializationConstants.ERROR_CODE_FILE_IO_EXCEPTION;
import static org.eclipse.buckminster.jnlp.MaterializationConstants.ERROR_CODE_REMOTE_IO_EXCEPTION;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.httpclient.HttpStatus;
import org.eclipse.buckminster.core.RMContext;
import org.eclipse.buckminster.core.common.model.ExpandingProperties;
import org.eclipse.buckminster.core.cspec.ICSpecData;
import org.eclipse.buckminster.core.metadata.IResolution;
import org.eclipse.buckminster.core.metadata.model.BOMNode;
import org.eclipse.buckminster.core.metadata.model.BillOfMaterials;
import org.eclipse.buckminster.core.mspec.builder.MaterializationNodeBuilder;
import org.eclipse.buckminster.core.mspec.builder.MaterializationSpecBuilder;
import org.eclipse.buckminster.jnlp.distroprovider.IRemoteDistroProvider;
import org.eclipse.buckminster.runtime.BuckminsterException;
import org.eclipse.buckminster.runtime.IOUtils;
import org.eclipse.buckminster.sax.Utils;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.xml.sax.SAXException;

/**
 * @author Karel Brezina
 * 
 */
public class MaterializationUtils {
    static class PropertyEntryByLength implements Comparable<PropertyEntryByLength> {
        private String m_key;

        private String m_value;

        public PropertyEntryByLength(String key, String value) {
            m_key = key;
            m_value = value;
        }

        public int compareTo(PropertyEntryByLength o) {
            int result = o.getKey().length() - m_key.length();

            if (result != 0)
                return result;

            return m_key.compareTo(o.getKey());
        }

        public String getKey() {
            return m_key;
        }

        public String getValue() {
            return m_value;
        }
    }

    private static Map<MaterializationSpecBuilder, Map<String, ? extends Object>> m_expandProperties = new HashMap<MaterializationSpecBuilder, Map<String, ? extends Object>>();

    private static Map<MaterializationSpecBuilder, Set<PropertyEntryByLength>> m_generalizeProperties = new HashMap<MaterializationSpecBuilder, Set<PropertyEntryByLength>>();

    private static final Map<String, String> s_humanReadableComponentTypes;

    // needs to be synchronized with the server side, new component types need to be added
    static {
        s_humanReadableComponentTypes = new HashMap<String, String>();
        s_humanReadableComponentTypes.put(null, "Any"); //$NON-NLS-1$
        s_humanReadableComponentTypes.put("unknown", "None"); //$NON-NLS-1$ //$NON-NLS-2$
        s_humanReadableComponentTypes.put("cssite", "Cloudsmith"); //$NON-NLS-1$ //$NON-NLS-2$
        s_humanReadableComponentTypes.put("osgi.bundle", "OSGi Bundle"); //$NON-NLS-1$ //$NON-NLS-2$
        s_humanReadableComponentTypes.put("eclipse.feature", "Eclipse Feature"); //$NON-NLS-1$ //$NON-NLS-2$
        s_humanReadableComponentTypes.put("maven", "Maven"); //$NON-NLS-1$ //$NON-NLS-2$
        s_humanReadableComponentTypes.put("site.feature", "Eclipse Update Manager"); //$NON-NLS-1$ //$NON-NLS-2$
        s_humanReadableComponentTypes.put("buckminster", "Buckminster"); //$NON-NLS-1$ //$NON-NLS-2$
        s_humanReadableComponentTypes.put("jar", "Java Archive"); //$NON-NLS-1$ //$NON-NLS-2$
        s_humanReadableComponentTypes.put("bom", "Bill of Materials"); //$NON-NLS-1$ //$NON-NLS-2$
    }

    /**
     * Checks HTTP response code and throws JNLPException if there is a problem
     * 
     * @param connection
     * @throws JNLPException
     * @throws IOException
     */
    public static void checkConnection(int status, String originalURL) throws JNLPException {
        if (status != HttpStatus.SC_OK) {
            String errorCode;

            switch (status) {
            case HttpStatus.SC_FORBIDDEN:

                errorCode = ERROR_CODE_403_EXCEPTION;
                break;

            case HttpStatus.SC_NOT_FOUND:

                errorCode = ERROR_CODE_404_EXCEPTION;
                break;

            case HttpStatus.SC_INTERNAL_SERVER_ERROR:

                errorCode = ERROR_CODE_500_EXCEPTION;
                break;

            default:
                errorCode = ERROR_CODE_REMOTE_IO_EXCEPTION;
                break;
            }

            throw new JNLPException(Messages.cannot_read_materialization_specification, errorCode,
                    BuckminsterException.fromMessage("%s - %s", originalURL, HttpStatus.getStatusText(status))); //$NON-NLS-1$
        }
    }

    /**
     * Checks response of IAuthenticator.register method
     * 
     * @param result
     *            result of IAuthenticator.register method
     * @throws JNLPException
     */

    public static void checkRegistrationResponse(int result) throws JNLPException {
        switch (result) {
        case IRemoteDistroProvider.REGISTER_FAIL:
            throw new JNLPException(Messages.registration_was_not_successful, null);
        case IRemoteDistroProvider.REGISTER_LOGIN_EXISTS:
            throw new JNLPException(Messages.login_name_already_exists_choose_a_different_one, null);
        case IRemoteDistroProvider.REGISTER_LOGIN_TOO_SHORT:
            throw new JNLPException(Messages.login_is_too_short_length_must_be_between_3_and_25, null);
        case IRemoteDistroProvider.REGISTER_LOGIN_CONTAINS_AT:
            throw new JNLPException(Messages.login_name_contains_at, null);
        case IRemoteDistroProvider.REGISTER_LOGIN_INVALID:
            throw new JNLPException(Messages.login_name_is_invalid, null);
        case IRemoteDistroProvider.REGISTER_PASSWORD_TOO_SHORT:
            throw new JNLPException(Messages.password_is_too_short_length_must_be_between_4_and_25, null);
        case IRemoteDistroProvider.REGISTER_EMAIL_FORMAT_ERROR:
            throw new JNLPException(Messages.email_does_not_have_standard_format, null);
        case IRemoteDistroProvider.REGISTER_EMAIL_ALREADY_VALIDATED:
            throw new JNLPException(Messages.email_is_already_verified_for_another_user, null);
        }
    }

    /**
     * Excludes CSSite components
     * 
     * @param mspec
     * @param depNode
     * @throws CoreException
     */
    public static void excludeCSsiteComponents(MaterializationSpecBuilder mspec, BOMNode depNode)
            throws CoreException {
        if (hasCSsiteReader(depNode))
            excludeComponent(mspec, depNode);

        for (BOMNode childDepNode : depNode.getChildren())
            excludeCSsiteComponents(mspec, childDepNode);
    }

    /**
     * Expands <code>IPath</code> that contains properties
     * 
     * @param mspec
     * @param installLocation
     * @return
     */
    public static IPath expandPath(MaterializationSpecBuilder mspec, IPath installLocation) {
        Map<String, ? extends Object> properties = m_expandProperties.get(mspec);

        if (properties == null) {
            properties = new RMContext(mspec.getProperties());
            m_expandProperties.put(mspec, properties);
        }

        return Path.fromOSString(ExpandingProperties.expand(properties, installLocation.toOSString(), 0));
    }

    /**
     * Generalize <code>IPath</code>
     * 
     * @param mspec
     * @param installLocation
     * @return
     */
    public static IPath generalizePath(MaterializationSpecBuilder mspec, IPath installLocation) {
        if (installLocation == null)
            return null;

        Set<PropertyEntryByLength> properties = m_generalizeProperties.get(mspec);

        if (properties == null) {
            properties = new TreeSet<PropertyEntryByLength>();
            RMContext context = new RMContext(mspec.getProperties());

            for (String key : context.keySet()) {
                String value = (String) context.get(key);

                if (value == null || value.length() == 0)
                    continue;

                // unifying file separators
                String unifiedValue = new Path(value).removeTrailingSeparator().toString();

                // changing meaning - key is value, value is key
                properties.add(new PropertyEntryByLength(unifiedValue, key));
            }

            m_generalizeProperties.put(mspec, properties);
        }

        String pathToGeneralize = installLocation.addTrailingSeparator().toString();
        int len = pathToGeneralize.length();

        for (PropertyEntryByLength entry : properties) {
            String key = entry.getKey();
            if (key.length() > len)
                continue;

            Pattern pattern = Pattern.compile("(^|/)(" + Pattern.quote(key) + ")/"); //$NON-NLS-1$ //$NON-NLS-2$
            Matcher matcher = pattern.matcher(pathToGeneralize);
            pathToGeneralize = matcher.replaceAll("$1\\${" + entry.getValue() + "}/"); //$NON-NLS-1$ //$NON-NLS-2$
        }

        return new Path(pathToGeneralize);
    }

    public static File getBackupFolder(File eclipseFolder) {
        String backupString = eclipseFolder.getPath() + ".backup"; //$NON-NLS-1$
        File backupFile = new File(backupString);

        int i = 0;
        while (backupFile.exists()) {
            backupFile = new File(backupString + String.format(".%d", Integer.valueOf(i++))); //$NON-NLS-1$
        }

        return backupFile;
    }

    /**
     * Gets default install location
     * 
     * @param artifactName
     * @return
     * @throws JNLPException
     */
    public static String getDefaultDestination(String artifactName) throws JNLPException {
        String destination = null;

        String userHome = System.getProperty("user.home"); //$NON-NLS-1$

        if (userHome != null) {
            destination = userHome + File.separator + DEFAULT_MATERIALIZATION_FOLDER;

            if (artifactName != null)
                destination += File.separator + artifactName;
        }
        return destination;
    }

    /**
     * Gets human readable component type
     * 
     * @param componentType
     *            componentType ID
     * @return human readable component type
     */
    public static String getHumanReadableComponentType(String componentType) {
        String hrType = s_humanReadableComponentTypes.get(componentType);
        if (hrType == null)
            hrType = componentType;
        return hrType;
    }

    public static Image getImage(String imageName) {
        Class<?> myClass = MaterializationUtils.class;
        String imageResource = "/icons/" + imageName; //$NON-NLS-1$
        URL imageUrl = myClass.getResource(imageResource);
        return ImageDescriptor.createFromURL(imageUrl).createImage();
    }

    /**
     * From a given path computes a path that exists in the file system.
     * 
     * @param enteredPath
     *            entered path
     * @return path that exists in the file system
     */
    public static String getKnownPath(String enteredPath) {
        IPath path = new Path(enteredPath);

        File file = null;
        String pathString = null;
        do {
            // second and other runs - remove last segment
            if (file != null)
                path = path.removeLastSegments(1);

            pathString = path.removeTrailingSeparator().toOSString();
            file = new File(pathString);
        } while (!file.exists() && pathString.length() > 0);

        if (!file.isDirectory())
            return null;

        return pathString;
    }

    public static void saveBOM(BillOfMaterials bom, File file) {
        OutputStream os = null;

        try {
            os = new FileOutputStream(file);
            Utils.serialize(bom, os);
        } catch (FileNotFoundException e1) {
            throw new JNLPException(Messages.file_cannot_be_opened_or_created, ERROR_CODE_FILE_IO_EXCEPTION, e1);
        } catch (SAXException e1) {
            throw new JNLPException(Messages.unable_to_read_BOM_specification, ERROR_CODE_ARTIFACT_EXCEPTION, e1);
        } finally {
            IOUtils.close(os);
        }
    }

    private static void excludeComponent(MaterializationSpecBuilder mspec, BOMNode depNode) throws CoreException {
        IResolution resolution = depNode.getResolution();

        if (resolution != null) {
            ICSpecData cspec = resolution.getCSpec();

            if (cspec != null) {
                String componentName = cspec.getName();
                String componentType = cspec.getComponentTypeID();

                for (MaterializationNodeBuilder builder : mspec.getNodeBuilders())
                    if ((componentType == null || componentType.equals(builder.getComponentTypeID()))
                            && builder.getNamePattern().matcher(componentName).matches())
                        builder.setExclude(true);

                MaterializationNodeBuilder nodeBuilder = mspec.addNodeBuilder();
                nodeBuilder.setNamePattern(Pattern.compile("^\\Q" + componentName + "\\E$")); //$NON-NLS-1$ //$NON-NLS-2$
                nodeBuilder.setComponentTypeID(componentType);
                nodeBuilder.setExclude(true);
            }
        }
    }

    private static boolean hasCSsiteReader(BOMNode depNode) throws CoreException {
        IResolution resolution = depNode.getResolution();

        if (resolution != null)
            if (MaterializationConstants.READER_TYPE_CSSITE.equals(resolution.getProvider().getReaderTypeId()))
                return true;

        return false;
    }
}