blob: 8747e7ee8d298983880b5479f868d65f6dd06685 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}