/*
* JBoss, Home of Professional Open Source
* Copyright 2010-2016, 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.tests.metamer.bean;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import javax.faces.application.ProjectStage;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import org.richfaces.log.Logger;
import org.richfaces.log.RichfacesLogger;
/**
* Vendor and version information for project Metamer.
*
* @author asmirnov@exadel.com
* @author <a href="mailto:ppitonak@redhat.com">Pavol Pitonak</a>
* @author <a href="mailto:lfryc@redhat.com">Lukas Fryc</a>
* @version $Revision: 22871 $
*/
@ManagedBean(name = "metamer")
@ApplicationScoped
public class VersionBean {
private static final Logger LOGGER = RichfacesLogger.APPLICATION.getLogger();
private static final String UNKNOWN_JSF = "Unknown version of JSF";
private String implementationVendor;
private String implementationVersion;
private String implementationTitle;
private String fullVersion;
private String shortVersion;
private String richFacesVersion;
private String jsfVersion;
private String serverVersion;
/**
* Initializes the managed bean.
*/
@PostConstruct
public void init() {
Properties properties = new Properties();
try {
InputStream inStream = getClass().getClassLoader().getResourceAsStream("version.properties");
properties.load(inStream);
} catch (Exception e) {
LOGGER
.warn(
"Unable to load version.properties using PomVersion.class.getClassLoader().getResourceAsStream(...)",
e);
}
implementationTitle = properties.getProperty("Implementation-Title");
implementationVendor = properties.getProperty("Implementation-Vendor");
implementationVersion = properties.getProperty("Implementation-Version");
serverVersion = initializeServerVersion();
}
public String getVendor() {
return implementationVendor;
}
public String getTitle() {
return implementationTitle;
}
public String getVersion() {
return implementationVersion;
}
public String getFullVersion() {
if (fullVersion != null) {
return fullVersion;
}
if (implementationVersion == null) {
implementationVersion = "Metamer, version unknown";
return implementationVersion;
}
fullVersion = implementationTitle + " by " + implementationVendor + ", version " + implementationVersion;
return fullVersion;
}
public String getShortVersion() {
if (shortVersion != null) {
return shortVersion;
}
if (implementationVersion == null) {
implementationVersion = "Metamer, version unknown";
return implementationVersion;
}
shortVersion = "Metamer " + implementationVersion;
return shortVersion;
}
public String getRichFacesVersion() {
if (richFacesVersion != null) {
return richFacesVersion;
}
org.richfaces.VersionBean rfVersionBean = new org.richfaces.VersionBean();
StringBuilder result = new StringBuilder();
result.append("RichFaces ");
result.append(rfVersionBean.getVersion().getImplementationVersion());
richFacesVersion = result.toString();
return richFacesVersion;
}
public String getJavaVersion() {
return System.getProperty("java.runtime.name") + " " + System.getProperty("java.runtime.version");
}
public String getOsVersion() {
return System.getProperty("os.name");
}
public String getJsfVersion() {
if (jsfVersion != null) {
return jsfVersion;
}
FacesContext facesContext = FacesContext.getCurrentInstance();
if (facesContext == null) {
return UNKNOWN_JSF;
}
jsfVersion = new JsfVersionFinder().getVersionString();
return jsfVersion;
}
public String getBrowserVersion() {
Object request = FacesContext.getCurrentInstance().getExternalContext().getRequest();
if (request instanceof HttpServletRequest) {
// small hack to get it working correctly in portal env
return ((HttpServletRequest) request).getHeader("user-agent");
}
return "Unknown";
}
public ProjectStage getProjectStage() {
return FacesContext.getCurrentInstance().getApplication().getProjectStage();
}
public String getServerVersion() {
return serverVersion;
}
private static String initializeServerVersion() {
String result = null;
try {
result = getJBossVersionInfo();
} catch (FailToRetrieveInfo e) {
result = e.getMessage();
}
if (result == null) {
try {
result = getJBossAS6VersionInfo();
} catch (FailToRetrieveInfo e) {
result = e.getMessage();
}
}
if (result == null) {
try {
result = getTomcatVersionInfo();
} catch (FailToRetrieveInfo e) {
result = e.getMessage();
}
}
if (result == null) {
result = "Server unknown";
}
return result;
}
public static String getTomcatVersionInfo() {
String result = (String) new InfoObtainer() {
@Override
protected Object obtainInfo() throws ClassNotFoundException, IllegalAccessException,
InstantiationException, SecurityException, NoSuchMethodException, IllegalArgumentException,
InvocationTargetException {
Class<?> clazz = Class.forName("org.apache.catalina.util.ServerInfo");
return clazz.getMethod("getServerInfo").invoke(null);
}
}.getInfo();
return result.replace("/", " ");
}
public static String getJBossAS6VersionInfo() {
String versionNumber = (String) new JBossAS6VersionInfoObtainer("getVersionNumber").getInfo();
String buildNumber = (String) new JBossAS6VersionInfoObtainer("getBuildID").getInfo();
if (versionNumber == null) {
return null;
}
StringBuilder buffer = new StringBuilder();
buffer.append("JBoss AS ");
buffer.append(versionNumber);
if (versionNumber.endsWith("SNAPSHOT")) {
buffer.append(" ");
buffer.append(buildNumber.replaceFirst("r", "r."));
}
return buffer.toString();
}
public static String getJBossVersionInfo() {
// check if it is one of JBoss-family servers (JBoss AS, WildFly, EAP)
try {
Class.forName("org.jboss.as.version.Version");
} catch (ClassNotFoundException e) {
return null;
}
String serverVersion = org.jboss.as.version.Version.AS_VERSION;
if (serverVersion.startsWith("7")) {
return "JBoss AS " + serverVersion;
} else {
return "WildFly " + serverVersion;
}
}
private static class JBossAS6VersionInfoObtainer extends InfoObtainer {
private String methodName;
public JBossAS6VersionInfoObtainer(String methodName) {
super();
this.methodName = methodName;
}
@Override
protected Object obtainInfo() throws ClassNotFoundException, IllegalAccessException, InstantiationException,
SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
Class<?> clazz = Class.forName("org.jboss.bootstrap.impl.as.server.ASVersion");
Object classInstance = clazz.getMethod("getInstance").invoke(null);
return clazz.getMethod(methodName).invoke(classInstance);
}
}
private abstract static class InfoObtainer {
protected abstract Object obtainInfo() throws ClassNotFoundException, IllegalAccessException,
InstantiationException, SecurityException, NoSuchMethodException, IllegalArgumentException,
InvocationTargetException;
public final Object getInfo() {
try {
return obtainInfo();
} catch (ClassNotFoundException e) {
return null;
} catch (IllegalAccessException e) {
throw new FailToRetrieveInfo(fail("failed to retrieve info - ", e), e);
} catch (InstantiationException e) {
throw new FailToRetrieveInfo(fail("failed to retrieve info - ", e), e);
} catch (SecurityException e) {
throw new FailToRetrieveInfo(fail("failed to access version info - ", e), e);
} catch (NoSuchMethodException e) {
throw new FailToRetrieveInfo(fail("failed to access version info - ", e), e);
} catch (IllegalArgumentException e) {
throw new FailToRetrieveInfo(fail("failed to access version info - ", e), e);
} catch (InvocationTargetException e) {
throw new FailToRetrieveInfo(fail("failed to access version info - ", e), e);
}
}
}
public static class FailToRetrieveInfo extends RuntimeException {
private static final long serialVersionUID = 4905414716987875382L;
public FailToRetrieveInfo(String message, Throwable cause) {
super(message, cause);
}
}
private static String fail(String message, Exception e) {
return message + e.getClass().getSimpleName() + e.getMessage();
}
@Override
public String toString() {
return getFullVersion();
}
/**
* Modification of org.richfaces.application.JsfVersionInspector
*/
private class JsfVersionFinder {
private 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 UNKNOWN_JSF;
}
}
private String getLogStringsImplementationVersion() {
Properties prop = new Properties();
InputStream in = getClass().getResourceAsStream("/com/sun/faces/LogStrings.properties");
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);
}
private String getPackageImplementationVersion() {
return FacesContext.getCurrentInstance().getClass().getPackage().getImplementationVersion();
}
public String getVersionString() {
if (isMojarra()) {
return "Mojarra " + getLogStringsImplementationVersion();
} else {
return "MyFaces " + getPackageImplementationVersion();
}
}
boolean isMojarra() {
try {
this.getClass().getClassLoader().loadClass("com.sun.faces.context.FacesContextImpl");
} catch (ClassNotFoundException e) {
return false;
}
return true;
}
}
}