Skip to content

Commit

Permalink
LDEV-5033 - add argument "javacast"
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeloffner committed Jul 19, 2024
1 parent c96ea77 commit a710d31
Show file tree
Hide file tree
Showing 17 changed files with 133 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import lucee.commons.digest.MD5;
import lucee.commons.digest.HashUtil;
import lucee.commons.io.res.Resource;
import lucee.commons.io.res.type.file.FileResource;
import lucee.runtime.exp.PageException;
Expand All @@ -57,8 +57,8 @@ public class ResourceClassLoader extends URLClassLoader implements Closeable {
*/
public ResourceClassLoader(Resource[] resources, ClassLoader parent) throws IOException {
super(doURLs(resources), parent);
for (int i = 0; i < resources.length; i++) {
if (resources[i] != null) this.resources.add(resources[i]);
for (Resource r: resources) {
if (r != null) this.resources.add(r);
}
}

Expand Down Expand Up @@ -136,7 +136,7 @@ public ResourceClassLoader getCustomResourceClassLoader(Resource[] resources) th
return rcl;
}

public ResourceClassLoader getCustomResourceClassLoader2(Resource[] resources) throws IOException {
public ResourceClassLoader getCustomResourceClassLoader2w(Resource[] resources) throws IOException {
if (ArrayUtil.isEmpty(resources)) return this;
String key = hash(resources);
SoftReference<ResourceClassLoader> tmp = customCLs == null ? null : customCLs.get(key);
Expand All @@ -156,7 +156,7 @@ private String hash(Resource[] resources) {
sb.append(ResourceUtil.getCanonicalPathEL(resources[i]));
sb.append(';');
}
return MD5.getDigestAsString(sb.toString(), null);
return HashUtil.create64BitHashAsString(sb.toString());
}

}
74 changes: 54 additions & 20 deletions core/src/main/java/lucee/commons/lang/ClassUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import lucee.commons.io.SystemUtil;
import lucee.commons.io.res.Resource;
import lucee.commons.io.res.util.ResourceClassLoader;
import lucee.runtime.PageContext;
import lucee.runtime.PageContextImpl;
import lucee.runtime.config.Config;
import lucee.runtime.config.ConfigPro;
import lucee.runtime.config.Identification;
Expand All @@ -65,8 +67,8 @@ public final class ClassUtil {
* @throws ClassException
* @throws PageException
*/
public static Class toClass(String className) throws ClassException {
return loadClass(className);
public static Class toClass(PageContext pc, String className) throws ClassException {
return loadClass(pc, className);
}

private static Class checkPrimaryTypesBytecodeDef(String className, Class defaultValue) {
Expand Down Expand Up @@ -231,35 +233,66 @@ public static Class loadClass(String className, Class defaultValue) {
return defaultValue;
}

public static Class loadClass(String className) throws ClassException {
return loadClass((PageContext) null, className);
}

/**
* loads a class from a String classname
*
* @param className
* @return matching Class
* @throws ClassException
*/
public static Class loadClass(String className) throws ClassException {
public static Class loadClass(PageContext pc, String className) throws ClassException {
Set<Throwable> exceptions = new HashSet<Throwable>();
// OSGI env
Class clazz = _loadClass(new OSGiBasedClassLoading(), className, null, exceptions);
if (clazz != null) {
return clazz;
}
// no ThreadLocalPageContext !!!
if (pc instanceof PageContextImpl) {
ClassLoader cl;
try {
cl = ((PageContextImpl) pc).getClassLoader();
}
catch (IOException e) {
ClassException ce = new ClassException("cannot load class through its string name");
ExceptionUtil.initCauseEL(ce, e);
throw ce;
}

// core classloader
clazz = _loadClass(new ClassLoaderBasedClassLoading(SystemUtil.getCoreClassLoader()), className, null, exceptions);
if (clazz != null) {
return clazz;
// core classloader
clazz = _loadClass(new ClassLoaderBasedClassLoading(cl), className, null, exceptions);
if (clazz != null) {
return clazz;
}
}
else {
// core classloader
clazz = _loadClass(new ClassLoaderBasedClassLoading(SystemUtil.getCoreClassLoader()), className, null, exceptions);
if (clazz != null) {
return clazz;
}

// loader classloader
clazz = _loadClass(new ClassLoaderBasedClassLoading(SystemUtil.getLoaderClassLoader()), className, null, exceptions);
if (clazz != null) {
return clazz;
// loader classloader
clazz = _loadClass(new ClassLoaderBasedClassLoading(SystemUtil.getLoaderClassLoader()), className, null, exceptions);
if (clazz != null) {
return clazz;
}
}

String msg = "cannot load class through its string name, because no definition for the class with the specified name [" + className + "] could be found";
if (exceptions.size() > 0) {

if (exceptions.size() == 1) {
Throwable t = exceptions.iterator().next();
ClassException ce = new ClassException(msg);
ExceptionUtil.initCauseEL(ce, t);
throw ce;
}

else if (exceptions.size() > 0) {
StringBuilder detail = new StringBuilder();
Iterator<Throwable> it = exceptions.iterator();
Throwable t;
Expand Down Expand Up @@ -448,8 +481,8 @@ public static Object loadInstance(Class clazz) throws ClassException {
}
}

public static Object loadInstance(String className) throws ClassException {
return loadInstance(loadClass(className));
public static Object loadInstance(PageContext pc, String className) throws ClassException {
return loadInstance(loadClass(pc, className));
}

public static Object loadInstance(ClassLoader cl, String className) throws ClassException {
Expand Down Expand Up @@ -545,8 +578,8 @@ public static Object loadInstance(Class clazz, Object[] args) throws ClassExcept
}
}

public static Object loadInstance(String className, Object[] args) throws ClassException, InvocationTargetException {
return loadInstance(loadClass(className), args);
public static Object loadInstance(PageContext pc, String className, Object[] args) throws ClassException, InvocationTargetException {
return loadInstance(loadClass(pc, className), args);
}

public static Object loadInstance(ClassLoader cl, String className, Object[] args) throws ClassException, InvocationTargetException {
Expand Down Expand Up @@ -871,11 +904,11 @@ else if (file.isDirectory()) {
* @param defaultValue - a value to return in case the source could not be determined
* @return
*/
public static String getSourcePathForClass(String className, String defaultValue) {
public static String getSourcePathForClass(PageContext pc, String className, String defaultValue) {

try {

return getSourcePathForClass(ClassUtil.loadClass(className), defaultValue);
return getSourcePathForClass(ClassUtil.loadClass(pc, className), defaultValue);
}
catch (Throwable t) {
ExceptionUtil.rethrowIfNecessary(t);
Expand Down Expand Up @@ -921,8 +954,9 @@ public static String extractName(String className) {
* @throws ClassException
* @throws BundleException
*/
public static Class loadClass(String className, String bundleName, String bundleVersion, Identification id, List<Resource> addional) throws ClassException, BundleException {
if (StringUtil.isEmpty(bundleName)) return loadClass(className);
public static Class loadClass(PageContext pc, String className, String bundleName, String bundleVersion, Identification id, List<Resource> addional)
throws ClassException, BundleException {
if (StringUtil.isEmpty(bundleName)) return loadClass(pc, className);
return loadClassByBundle(className, bundleName, bundleVersion, id, addional);
}

Expand Down
9 changes: 7 additions & 2 deletions core/src/main/java/lucee/runtime/PageContextImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
import lucee.runtime.listener.ApplicationContextSupport;
import lucee.runtime.listener.ApplicationListener;
import lucee.runtime.listener.ClassicApplicationContext;
import lucee.runtime.listener.JavaSettings;
import lucee.runtime.listener.JavaSettingsImpl;
import lucee.runtime.listener.ModernAppListenerException;
import lucee.runtime.listener.NoneAppListener;
Expand Down Expand Up @@ -3838,8 +3839,12 @@ public ClassLoader getClassLoader() throws IOException {
return getClassLoader(null);
}

public JavaSettings getJavaSettings() {
return getApplicationContext().getJavaSettings();
}

public ClassLoader getClassLoader(Resource[] reses) throws IOException {
JavaSettingsImpl js = (JavaSettingsImpl) getApplicationContext().getJavaSettings();
JavaSettingsImpl js = (JavaSettingsImpl) getJavaSettings();
if (js != null) {
// TODO FUTURE 7 we do this to avoid any kind of regression, in Lucee 7 remove this
if (!JAVA_SETTING_CLASSIC_MODE && !js.hasPoms() && !js.hasOSGis()) {
Expand All @@ -3858,7 +3863,7 @@ public ClassLoader getRPCClassLoader(boolean reload) throws IOException {

public ClassLoader getRPCClassLoader(boolean reload, ClassLoader[] parents) throws IOException {
ClassLoader cl = ((ConfigPro) config).getRPCClassLoader(reload, parents);
JavaSettingsImpl js = (JavaSettingsImpl) getApplicationContext().getJavaSettings();
JavaSettingsImpl js = (JavaSettingsImpl) getJavaSettings();
if (js != null) {
// TODO FUTURE 7 we do this to avoid any kind of regression, in Lucee 7 remove this
if (!JAVA_SETTING_CLASSIC_MODE && !js.hasPoms() && !js.hasOSGis()) {
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/lucee/runtime/component/PropertyImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import lucee.runtime.Component;
import lucee.runtime.converter.ConverterException;
import lucee.runtime.converter.ScriptConverter;
import lucee.runtime.engine.ThreadLocalPageContext;
import lucee.runtime.exp.PageException;
import lucee.runtime.op.Caster;
import lucee.runtime.op.Duplicator;
Expand Down Expand Up @@ -153,7 +154,7 @@ public Object getValue() {

@Override
public Type getASMType() throws PageException {
return ASMUtil.toType(getType(), true);
return ASMUtil.toType(ThreadLocalPageContext.get(), getType(), true);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
import lucee.runtime.Component;
import lucee.runtime.Mapping;
import lucee.runtime.MappingImpl;
import lucee.runtime.PageContext;
import lucee.runtime.cache.CacheConnection;
import lucee.runtime.cache.CacheConnectionImpl;
import lucee.runtime.cache.ServerCacheConnection;
Expand Down Expand Up @@ -3798,7 +3799,7 @@ else if (StringUtil.startsWithIgnoreCase(streamtype, "class:")) {
String classname = streamtype.substring(6);
try {

return (PrintStream) ClassUtil.loadInstance(classname);
return (PrintStream) ClassUtil.loadInstance((PageContext) null, classname);
}
catch (Throwable t) {
ExceptionUtil.rethrowIfNecessary(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static BIF use(PageContext pc, String className, String bundleName, Strin
if (!StringUtil.isEmpty(bundleName))
clazz = ClassUtil.loadClassByBundle(className, bundleName, bundleVersion, pc.getConfig().getIdentification(), JavaSettingsImpl.getBundleDirectories(pc), true);
// JAR
else clazz = ClassUtil.loadClass(className);
else clazz = ClassUtil.loadClass(pc, className);

if (Reflector.isInstaneOf(clazz, BIF.class, false)) bif = (BIF) ClassUtil.newInstance(clazz);
else bif = new BIFProxy(clazz);
Expand All @@ -79,7 +79,7 @@ public static BIF use(PageContext pc, String className) throws PageException {
if (bif != null) return bif;

try {
Class<?> clazz = ClassUtil.loadClass(className);
Class<?> clazz = ClassUtil.loadClass(pc, className);

if (Reflector.isInstaneOf(clazz, BIF.class, false)) bif = (BIF) ClassUtil.newInstance(clazz);
else bif = new BIFProxy(clazz);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private static Class toClass(PageContext pc, ClassLoader cl, Struct sct) throws
if (StringUtil.isEmpty(bundleName)) {
return ClassUtil.loadClass(cl, className);
}
return ClassUtil.loadClass(className, bundleName, bundleVersion, pc.getConfig().getIdentification(), JavaSettingsImpl.getBundleDirectories(pc));
return ClassUtil.loadClass(pc, className, bundleName, bundleVersion, pc.getConfig().getIdentification(), JavaSettingsImpl.getBundleDirectories(pc));
}

}
34 changes: 25 additions & 9 deletions core/src/main/java/lucee/runtime/functions/string/JavaCast.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
import lucee.runtime.exp.ExpressionException;
import lucee.runtime.exp.PageException;
import lucee.runtime.ext.function.Function;
import lucee.runtime.listener.JavaSettingsImpl;
import lucee.runtime.op.Caster;
import lucee.runtime.op.Decision;
import lucee.runtime.type.Struct;

public final class JavaCast implements Function {

Expand All @@ -43,19 +45,23 @@ public static Object calls(PageContext pc, String string, Object object) throws
}

public static Object call(PageContext pc, String type, Object obj) throws PageException {
return call(pc, type, obj, null);
}

public static Object call(PageContext pc, String type, Object obj, Struct javaSettings) throws PageException {
type = type.trim();
String lcType = StringUtil.toLowerCase(type);

if (type.endsWith("[]")) {

return toArray(pc, type, lcType, obj);
return toArray(pc, type, lcType, obj, javaSettings);
}
Class<?> clazz = toClass(pc, lcType, type);
Class<?> clazz = toClass(pc, lcType, type, javaSettings);
return to(pc, obj, clazz);

}

public static Object toArray(PageContext pc, String type, String lcType, Object obj) throws PageException {
public static Object toArray(PageContext pc, String type, String lcType, Object obj, Struct javaSettings) throws PageException {
// byte
if ("byte[]".equals(lcType)) {
if (obj instanceof byte[]) return obj;
Expand All @@ -68,20 +74,20 @@ else if ("char[]".equals(lcType)) {
if (obj instanceof CharSequence) return obj.toString().toCharArray();
}

return _toArray(pc, type, lcType, obj);
return _toArray(pc, type, lcType, obj, javaSettings);
}

public static Object _toArray(PageContext pc, String type, String lcType, Object obj) throws PageException {
public static Object _toArray(PageContext pc, String type, String lcType, Object obj, Struct javaSettings) throws PageException {
lcType = lcType.substring(0, lcType.length() - 2);
type = type.substring(0, type.length() - 2);

// other
Object[] arr = Caster.toList(obj).toArray();
Class<?> clazz = toClass(pc, lcType, type);
Class<?> clazz = toClass(pc, lcType, type, javaSettings);
Object trg = java.lang.reflect.Array.newInstance(clazz, arr.length);

for (int i = arr.length - 1; i >= 0; i--) {
java.lang.reflect.Array.set(trg, i, type.endsWith("[]") ? _toArray(pc, type, lcType, arr[i]) : to(pc, arr[i], clazz));
java.lang.reflect.Array.set(trg, i, type.endsWith("[]") ? _toArray(pc, type, lcType, arr[i], javaSettings) : to(pc, arr[i], clazz));
}
return trg;
}
Expand All @@ -95,7 +101,7 @@ private static Object to(PageContext pc, Object obj, Class<?> trgClass) throws P
// float ,double ,boolean ,string,null ), "+lcType+" is invalid");
}

private static Class<?> toClass(PageContext pc, String lcType, String type) throws PageException {
private static Class<?> toClass(PageContext pc, String lcType, String type, Struct javaSettings) throws PageException {

if (lcType.equals("null")) {
return null;
Expand All @@ -106,8 +112,18 @@ private static Class<?> toClass(PageContext pc, String lcType, String type) thro
if (lcType.equals("bigdecimal")) {
return BigDecimal.class;
}
if (javaSettings != null) {
JavaSettingsImpl js = (JavaSettingsImpl) JavaSettingsImpl.getInstance(pc.getConfig(), Caster.toStruct(javaSettings));
try {
return js.getResourceClassLoader(null).loadClass(type);
}
catch (Exception e) {
throw Caster.toPageException(e);
}
}
try {
return ClassUtil.toClass(type);

return ClassUtil.loadClass(pc, type);
}
catch (ClassException e) {
throw Caster.toPageException(e);
Expand Down
Loading

0 comments on commit a710d31

Please sign in to comment.