/** * Copyright (c) 2015, Lucee Assosication Switzerland. All rights reserved. * * This library 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 library 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 library. If not, see <http://www.gnu.org/licenses/>. * */ package lucee.runtime.engine; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Properties; import java.util.jar.Attributes; import java.util.jar.Manifest; import lucee.Info; import lucee.commons.date.TimeZoneConstants; import lucee.commons.io.IOUtil; import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.StringUtil; import lucee.runtime.PageSourceImpl; import lucee.runtime.config.Constants; import lucee.runtime.exp.PageRuntimeException; import lucee.runtime.extension.ExtensionDefintion; import lucee.runtime.extension.RHExtension; import lucee.runtime.op.Caster; import lucee.runtime.op.date.DateCaster; import lucee.runtime.osgi.OSGiUtil; import lucee.runtime.type.KeyImpl; import lucee.runtime.type.dt.DateTime; import lucee.runtime.type.util.ListUtil; import org.osgi.framework.Bundle; import org.osgi.framework.Version; /** * Info to this Version */ public final class InfoImpl implements Info { public static final int STATE_ALPHA = 2*100000000; public static final int STATE_BETA = 1*100000000; public static final int STATE_RC = 3*100000000; public static final int STATE_FINAL = 0; // Mod this private DateTime releaseDate; private String versionName; private String versionNameExplanation; private final long releaseTime; private Version version; private String level; private List<ExtensionDefintion> requiredExtensions; //private int state; //private final String strState; public InfoImpl() { this(null); } public InfoImpl(Bundle bundle) { try{ Attributes mf = getManifest(bundle).getMainAttributes(); versionName=mf.getValue("Minor-Name"); if(versionName==null)throw new RuntimeException("missing Minor-Name"); versionNameExplanation=mf.getValue("Minor-Name-Explanation"); releaseDate=DateCaster.toDateAdvanced(mf.getValue("Built-Date"), TimeZoneConstants.EUROPE_ZURICH); //state=toIntState(mf.getValue("State")); level="os"; version=OSGiUtil.toVersion(mf.getValue("Bundle-Version")); String str=mf.getValue("Require-Extension"); if(StringUtil.isEmpty(str,true)) requiredExtensions=new ArrayList<ExtensionDefintion>(); else requiredExtensions = RHExtension.toExtensionDefinitions(str); //ListUtil.trimItems(ListUtil.listToStringArray(str, ',')); } catch(Throwable t) { ExceptionUtil.rethrowIfNecessary(t); throw new PageRuntimeException(Caster.toPageException(t)); } releaseTime=releaseDate.getTime(); //strState=toStringState(state); } public static Properties getDefaultProperties(Bundle bundle) { InputStream is=null; Properties prop = new Properties(); String keyToValidate="felix.log.level"; try{ // check the bundle for the default.properties if(bundle!=null) { try { is = bundle.getEntry("default.properties").openStream(); prop.load(is); } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} finally {IOUtil.closeEL(is);} } if(prop.getProperty(keyToValidate)!=null) return prop; // try from core classloader without leading slash prop = new Properties(); Class clazz = PageSourceImpl.class; ClassLoader cl = clazz.getClassLoader(); try{ is = cl.getResourceAsStream("default.properties"); prop.load(is); } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} finally {IOUtil.closeEL(is);} if(prop.getProperty(keyToValidate)!=null) return prop; // try from core classloader with leading slash prop = new Properties(); try{ is = cl.getResourceAsStream("/default.properties"); prop.load(is); } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} finally {IOUtil.closeEL(is);} if(prop.getProperty(keyToValidate)!=null) return prop; // try from core class with leading slash prop = new Properties(); try{ is = clazz.getResourceAsStream("/default.properties"); prop.load(is); } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} finally {IOUtil.closeEL(is);} if(prop.getProperty(keyToValidate)!=null) return prop; prop = new Properties(); try{ is = clazz.getResourceAsStream("../../default.properties"); prop.load(is); } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} finally {IOUtil.closeEL(is);} if(prop.getProperty(keyToValidate)!=null) return prop; return new Properties(); } finally{ IOUtil.closeEL(is); } } public static Manifest getManifest(Bundle bundle) { InputStream is=null; Manifest manifest; try { // check the bundle for the default.properties if(bundle!=null) { try { manifest = load(bundle.getEntry("META-INF/MANIFEST.MF").openStream()); if(manifest!=null) return manifest; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} } // try from core classloader without leading slash Class clazz = PageSourceImpl.class; ClassLoader cl = clazz.getClassLoader(); manifest = load(cl.getResourceAsStream("META-INF/MANIFEST.MF")); if(manifest!=null) return manifest; // try from core classloader with leading slash manifest = load(cl.getResourceAsStream("/META-INF/MANIFEST.MF")); if(manifest!=null) return manifest; // try from core class with leading slash manifest = load( clazz.getResourceAsStream("/META-INF/MANIFEST.MF")); if(manifest!=null) return manifest; manifest = load( clazz.getResourceAsStream("../../META-INF/MANIFEST.MF")); if(manifest!=null) return manifest; // check all resources try { Enumeration<URL> e = cl.getResources("META-INF/MANIFEST.MF"); while(e.hasMoreElements()){ manifest = load(e.nextElement().openStream()); if(manifest!=null) return manifest; } } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} return null; } finally{ IOUtil.closeEL(is); } } private static Manifest load(InputStream is) { try { Manifest m = new Manifest(is); String sn = m.getMainAttributes().getValue("Bundle-SymbolicName"); if("lucee.core".equals(sn)) return m; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} finally {IOUtil.closeEL(is);} return null; } private static boolean valid(Manifest manifest) { return false; } /** * @return the level */ @Override public String getLevel() { return level; } public static int toIntVersion(String version, int defaultValue) { try{ String[] aVersion = ListUtil.toStringArray(ListUtil.listToArrayRemoveEmpty(version,'.')); int ma = Caster.toIntValue(aVersion[0]); int mi = Caster.toIntValue(aVersion[1]); int re = Caster.toIntValue(aVersion[2]); int pa = Caster.toIntValue(aVersion[3]); return (ma*1000000)+(mi*10000)+(re*100)+pa; } catch(Throwable t){ ExceptionUtil.rethrowIfNecessary(t); return defaultValue; } } // Version <version>.<major>.<minor>.<patches> /** * @return Returns the releaseDate. */ public DateTime getRealeaseDate() { return releaseDate; } /** * @return Returns the releaseTime. */ @Override public long getRealeaseTime() { return releaseTime; } @Override public Version getVersion() { return version; } public List<ExtensionDefintion> getRequiredExtension() { return requiredExtensions; } /** * @return returns the state @Override public int getStateAsInt() { return state; }*/ /** * @return returns the state @Override public String getStateAsString() { return strState; }*/ /* * * @return returns the state public static String toStringState(int state) { if(state==STATE_FINAL) return "final"; else if(state==STATE_BETA) return "beta"; else if(state==STATE_RC) return "rc"; else return "alpha"; }*/ /* * * @return returns the state public int toIntState(String state) { state=state.trim().toLowerCase(); if("final".equals(state)) return STATE_FINAL; else if("beta".equals(state)) return STATE_BETA; else if("rc".equals(state)) return STATE_RC; else return STATE_ALPHA; } */ @Override public String getVersionName() { return versionName; } @Override public String getVersionNameExplanation() { return versionNameExplanation; } @Override public long getFullVersionInfo() { return KeyImpl.createHash64(getVersion().toString());//+state; } @Override public String[] getCFMLTemplateExtensions() { return Constants.getCFMLTemplateExtensions(); } @Override public String[] getLuceeTemplateExtensions() { return Constants.getLuceeTemplateExtensions(); } @Override public String[] getCFMLComponentExtensions() { return new String[]{getCFMLComponentExtension()}; } @Override public String[] getLuceeComponentExtensions() { return new String[]{getLuceeComponentExtension()}; } @Override public String getCFMLComponentExtension() { return Constants.getCFMLComponentExtension(); } @Override public String getLuceeComponentExtension() { return Constants.getLuceeComponentExtension(); } }