org.richfaces.application.JsfVersionInspector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of richfaces-core Show documentation
Show all versions of richfaces-core Show documentation
The RichFaces core framework.
/*
* JBoss, Home of Professional Open Source
* Copyright 2014, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.application;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Properties;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.context.FacesContext;
/**
* In RichFaces 4.5.0 a new EPVC was intorduced that exposed a bug in Mojarra (MyFaces is Ok).
*
* This Mojarra issue was resolved in the following versions: * JAVASERVERFACES-3157 fixed in 2.1.28 and 2.1.27.redhat-9 *
* JAVASERVERFACES-3151 fixed in 2.2.6 and 2.2.5-jbossorg-3
*
* The public verifyJsfImplVersion method of this class can be used to inspect the runtime and ensure an appropriately patched
* JSF implementation is present to work with the new EPVC
*
* @author Brian Leathem
*/
public class JsfVersionInspector {
String versionString;
class Version {
final int major;
final int minor;
final int micro;
final String qualifier;
private Version(int major, int minor, int micro, String qualifier) {
this.major = major;
this.minor = minor;
this.micro = micro;
this.qualifier = qualifier;
}
}
public JsfVersionInspector() {
versionString = getPackageImplementationVersion();
if (versionString == null) {
// JBoss re-packaging of mojarra strips the implementation version
// see: https://issues.jboss.org/browse/WFLY-3488
// We'll fall back to parsing the LogStrings.properties file for the impl version
versionString = getLogStringsImplementationVersion();
}
if (versionString == null) {
// LogStrings.properties were not found, we'll check the jar manifest
// known case for this is WebSphere with custom version of MyFaces (RF-14020),
// however other systems may be affected as well
versionString = getManifestImplementationVersion();
}
}
/**
* A constructor that skips the version detection for the purpose of writing unit tests
*/
JsfVersionInspector(String versionString) {
this.versionString = versionString;
}
/**
* This method can be used to inspect the runtime and ensure an appropriately patched JSF implementation is present to work
* with the new EPVC
*/
public boolean verifyJsfImplVersion() {
if (isMojarra()) {
Version version = parseVersion(versionString);
return testVersion(version);
}
return true;
}
public String getVersionString() {
return versionString;
}
boolean testVersion(Version version) {
if (version.major < 2) {
return false;
} else if (version.major > 2) {
return true; // Future proof!
} else { // version.major == 2
if (version.minor < 1) {
return false;
} else if (version.minor == 1) {
// https://java.net/jira/browse/JAVASERVERFACES-3157 fixed in 2.1.28 and 2.1.27.redhat-9
if (version.micro < 27) {
return false;
} else if (version.micro == 27) {
return version.qualifier.equals("redhat-9");
} else { // version.micro > 27
return true;
}
} else if (version.minor == 2) {
// https://java.net/jira/browse/JAVASERVERFACES-3151 fixed in 2.2.6 and 2.2.5-jbossorg-3
if (version.micro < 5) {
return false;
} else if (version.micro == 5) {
return version.qualifier.equals("jbossorg-3");
} else { // version.micro > 5
return true;
}
} else { // version.major > 3
return true; // Future proof!
}
}
}
String getPackageImplementationVersion() {
Package facesPackage = FacesContext.getCurrentInstance().getClass().getPackage();
// if (facesPackage.getImplementationVersion() == null) {
// facesPackage = Package.getPackage("javax.faces");
// }
return facesPackage.getImplementationVersion();
}
String getLogStringsImplementationVersion() {
Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream("/com/sun/faces/LogStrings.properties");
if (in == null) {
return null;
}
try {
prop.load(in);
in.close();
} catch (IOException e) {
throw new RuntimeException("Unable to load LogStrings.properties file to determine the mojarra version", e);
}
String jbossImplString = prop.getProperty("jsf.config.listener.version");
return extractVersion(jbossImplString);
}
String getManifestImplementationVersion() {
String manifestVersion = "";
JarFile jar = null;
try {
URL url = FacesContext.class.getProtectionDomain().getCodeSource().getLocation();
jar = new JarFile(url.getFile());
manifestVersion = jar.getManifest().getMainAttributes().getValue("Implementation-version");
} catch (IOException e) {
throw new RuntimeException("Unable to open a jar to determine the JSF version", e);
} finally {
try {
jar.close();
} catch (IOException e) {
}
}
return manifestVersion;
}
String extractVersion(String string) {
Pattern pattern = Pattern.compile("([0-9][0-9\\.\\-a-z]*)");
Matcher matcher = pattern.matcher(string);
if (matcher.find()) {
return matcher.group();
} else {
return "no match";
}
}
Version parseVersion(String versionString) {
String qualifier;
String[] numbers;
if (versionString.matches("[0-9][0-9\\.]*\\-[a-zA-Z0-9\\-]*")) { // eg. 2.1.4-jbossorg-1 or 2.1.6-SNAPSHOT
// modifier is present
String[] parts = versionString.split("-", 2);
numbers = parts[0].split("\\.", 4);
qualifier = parts[1];
} else { // eg. 2.1.27.redhat-9
numbers = versionString.split("\\.", 5);
qualifier = numbers.length > 3 ? numbers[3] : "";
}
Version version;
try {
version = new Version(Integer.parseInt(numbers[0]), Integer.parseInt(numbers[1]), Integer.parseInt(numbers[2]),
qualifier);
} catch (NumberFormatException e) {
throw new RuntimeException(MessageFormat.format("Error parsing detected JSF version string: {0} ", versionString),
e);
}
return version;
}
boolean isMojarra() {
String contextClassName = FacesContext.getCurrentInstance().getClass().getName();
return ("com.sun.faces.context.FacesContextImpl".equals(contextClassName) || "com.sun.faces.config.InitFacesContext"
.equals(contextClassName));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy