org.eclipse.jst.jsf.common.facet.libraryprovider.UserLibraryVersionValidator.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.jsf.common.facet.libraryprovider.UserLibraryVersionValidator.java

Source

/*******************************************************************************
 * Copyright (c) 2001, 2008 Oracle Corporation and others.
 * 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.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jst.jsf.common.facet.libraryprovider;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jst.common.project.facet.core.libprov.user.KeyClassesValidator;
import org.eclipse.jst.common.project.facet.core.libprov.user.UserLibraryProviderInstallOperationConfig;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.facet.Messages;

/**
 * Checks that a user library is version-compatible with the facet.
 *
 * @author Debajit Adhikary
 *
 */
public abstract class UserLibraryVersionValidator extends KeyClassesValidator {
    private static final String MANIFEST_SPECIFICATION_VERSION = "Specification-Version"; //$NON-NLS-1$
    private static final String MANIFEST_IMPLEMENTATION_VERSION = "Implementation-Version"; //$NON-NLS-1$

    private final String classNameIdentifyingImplementationJar;

    /**
     * @param classNameIdentifyingImplementationJar
     */
    public UserLibraryVersionValidator(final String classNameIdentifyingImplementationJar) {
        this.classNameIdentifyingImplementationJar = classNameIdentifyingImplementationJar;
    }

    @Override
    public IStatus validate(final UserLibraryProviderInstallOperationConfig config) {
        // Check super validator
        final IStatus status = super.validate(config);
        if (status.getSeverity() != IStatus.OK)
            return status;

        // Superclass validated this lib successfully.
        // Check user library version now.
        final String facetVersion = getFacetVersion(config);
        final String libraryVersion = getLibraryVersion(config);
        return validateVersionStrings(facetVersion, libraryVersion);
    }

    /**
     * @param facetVersion
     * @param libraryVersion
     * @return the diagnostic for whether the facetVersion and libraryVersion
     *         match.
     */
    protected IStatus validateVersionStrings(final String facetVersion, final String libraryVersion) {
        if (facetVersion == null)
            throw new IllegalArgumentException("Cannot read facet version"); //$NON-NLS-1$

        if (libraryVersion == null)
            return new Status(IStatus.WARNING, JSFCommonPlugin.PLUGIN_ID,
                    Messages.UserLibraryVersionValidator_cannotReadLibraryVersion);

        if (libraryVersion.compareToIgnoreCase(facetVersion) >= 0) // JSF 2.0 lib for JSF 1.2 app, JSF 1.2 lib for JSF 1.2 app
            return Status.OK_STATUS;

        // e.g. JSF 1.2 library used for a JSF 2.0 app
        return new Status(IStatus.WARNING, JSFCommonPlugin.PLUGIN_ID,
                Messages.UserLibraryVersionValidator_possiblyIncompatibleLibrary);
    }

    private String getFacetVersion(final UserLibraryProviderInstallOperationConfig config) {
        return config.getProjectFacetVersion().getVersionString();
    }

    private String getLibraryVersion(final UserLibraryProviderInstallOperationConfig config) {
        String libraryVersion = null;

        try {
            for (final IClasspathEntry cpe : config.resolve()) {
                if (isLibrary(cpe)) {
                    final File libraryFile = cpe.getPath().toFile();

                    if (libraryFile.exists()
                            && isCorrectLibraryJar(cpe, this.classNameIdentifyingImplementationJar)) {
                        JarFile jarFile = null;
                        try {
                            jarFile = new JarFile(libraryFile);
                            libraryVersion = getLibraryVersion(jarFile);
                        } finally {
                            if (jarFile != null)
                                jarFile.close();
                        }
                    }
                }
            }
        } catch (final IOException e) {
            JSFCommonPlugin.log(e, e.getLocalizedMessage());
        }

        return libraryVersion;
    }

    private boolean isLibrary(final IClasspathEntry cpe) {
        return cpe.getEntryKind() == IClasspathEntry.CPE_LIBRARY;
    }

    private boolean isCorrectLibraryJar(final IClasspathEntry cpe, final String classNameIdentifyingJar)
            throws IOException {
        final File libraryFile = cpe.getPath().toFile();

        if (!libraryFile.exists())
            return false;

        ZipFile zipFile = null;

        try {
            zipFile = new ZipFile(libraryFile);

            for (final Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements();) {
                final ZipEntry entry = entries.nextElement();
                final String entryName = entry.getName();
                if (entryName.equals(classNameIdentifyingJar))
                    return true;
            }
        } finally {
            if (zipFile != null)
                zipFile.close();
        }

        return false;
    }

    /**
     * @param jarFile
     *            Library jar file to read
     * 
     * @return Version of the specified Jar. Uses the manifest
     *         Specification-Version entry. If that is not available, then uses
     *         the Implementation-Version entry.
     * 
     * @throws IOException
     */
    protected String getLibraryVersion(final JarFile jarFile) throws IOException {
        final Manifest manifest = jarFile.getManifest();

        if (manifest == null)
            return null;

        final Attributes attributes = manifest.getMainAttributes();

        final String specificationVersion = attributes.getValue(MANIFEST_SPECIFICATION_VERSION);
        if (specificationVersion != null)
            return specificationVersion;

        final String implementationVersion = manifest.getMainAttributes().getValue(MANIFEST_IMPLEMENTATION_VERSION);
        return implementationVersion;
    }
}