Skip to content

Commit

Permalink
Merge branch 'release/3.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
jesse-gallagher committed Sep 6, 2024
2 parents a576bd3 + 387f927 commit 2ddeb94
Show file tree
Hide file tree
Showing 105 changed files with 1,378 additions and 116 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,8 @@ public class NoSQLExample {
}
```

Certain queries, namely arbitrary searches with a sort parameter, will cause the driver to create QRP-view databases on disk. These will default to a system temp directory, but this can be overridden by specifying the `Jakarta_QRPDir` notes.ini property.

#### Accessing Views

View and folder data can be accessed by writing repository methods annotated with the `org.openntf.xsp.nosql.mapping.extension.ViewEntries` and `org.openntf.xsp.nosql.mapping.extension.ViewDocuments` annotations. For example:
Expand Down Expand Up @@ -818,6 +820,10 @@ When this library is enabled, .jsp files in the "Files" or "WebContent" parts of

As demonstrated above, this will resolve in-NSF tags via the NSF's classpath and will allow the use of CDI beans.

During page compilation, the runtime will create files on disk. These will default to a system temp directory, but this can be overridden by specifying the `Jakarta_TempDir` notes.ini property.

Additionally, this process requires deploying some DTDs to the filesystem. By default, these are deployed to (Domino data)/domino/jakarta, but this can be overridden by specifying the `Jakarta_DTDDir` notes.ini property.

### Server Faces

[Jakarta Server Faces](https://jakarta.ee/specifications/faces/) is the Jakarta EE form of JSF, the spec XPages forked off from.
Expand Down Expand Up @@ -1170,7 +1176,7 @@ Finally, you should have a Maven toolchain configured that provides JavaSE-17. F

If your Domino Java classpath has any invalid entries in it, the CDI portion of the tooling will complain and fail to load, which may cause XPages apps generally to throw an error 500.

The workaround for this is to check your classpath (jvm/lib/ext and ndext, primarily) for any files that the Domino process user can't access (usually the local system on Windows, or `notes` on Linux). Additionally, look for a `JavaUserClassesExt` entry in the server's notes.ini and make sure that all of the files or directories it references exist and are readable.
The workaround for this is to check your classpath (ndext, primarily) for any files that the Domino process user can't access (usually the local system on Windows, or `notes` on Linux). Additionally, look for a `JavaUserClassesExt` entry in the server's notes.ini and make sure that all of the files or directories it references exist and are readable.

See [COMPATIBILITY.md](COMPATIBILITY.md) for details on known incompatibilities with specific projects.

Expand Down
2 changes: 1 addition & 1 deletion eclipse/bundles/org.openntf.xsp.jakarta.cdi.extlib/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.openntf.xsp</groupId>
<artifactId>xsp-jakartaee</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>org.openntf.xsp.jakarta.cdi.extlib</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion eclipse/bundles/org.openntf.xsp.jakarta.cdi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.openntf.xsp</groupId>
<artifactId>xsp-jakartaee</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>org.openntf.xsp.jakarta.cdi</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
public interface CDIClassContributor {
public static final String EXTENSION_POINT = CDIClassContributor.class.getName();

Collection<Class<?>> getBeanClasses();
default Collection<Class<?>> getBeanClasses() {
return Collections.emptyList();
}

default Collection<Extension> getExtensions() {
return Collections.emptyList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.openntf.xsp</groupId>
<artifactId>xsp-jakartaee</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>org.openntf.xsp.jakarta.concurrency</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ Import-Package: com.ibm.commons.util,
com.ibm.xsp.util,
lotus.domino
Export-Package: org.openntf.xsp.jakarta.el;version="3.1.0",
org.openntf.xsp.jakarta.el.ext;version="3.1.0"
org.openntf.xsp.jakarta.el.ext;version="3.1.0",
org.openntf.xsp.jakarta.el.impl;version="3.1.0"
2 changes: 1 addition & 1 deletion eclipse/bundles/org.openntf.xsp.jakarta.el/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.openntf.xsp</groupId>
<artifactId>xsp-jakartaee</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>org.openntf.xsp.jakarta.el</artifactId>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.openntf.xsp.jakarta.el;

import org.openntf.xsp.jakarta.el.impl.RecordPropertyResolverFactory;
import org.openntf.xsp.jakartaee.util.LibraryUtil;

import com.ibm.xsp.application.ApplicationEx;
Expand All @@ -35,6 +36,8 @@ public void applicationCreated(ApplicationEx application) {

// Create a binding factory for default bindings
facts.setFactory(XSPELBindingFactory.IBM_PREFIX, new XSPELBindingFactory(XSPELBindingFactory.IBM_PREFIX));

facts.setFactory(RecordPropertyResolverFactory.class.getName(), RecordPropertyResolverFactory.INSTANCE);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public FacesELContext(ExpressionFactory factory) {

addELResolver(new BeanNameELResolver(new FacesBeanNameResolver()));
addELResolver(new XSPELResolver());
addELResolver(new RecordPropertyELResolver());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.openntf.xsp.jakarta.el.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;

import jakarta.el.BeanELResolver;
import jakarta.el.ELContext;
import jakarta.el.ELResolver;
import jakarta.el.PropertyNotWritableException;

public class RecordPropertyELResolver extends ELResolver {

private final BeanELResolver delegate = new BeanELResolver();

@SuppressWarnings({"removal", "deprecation"})
@Override
public Object getValue(ELContext context, Object base, Object property) {
if(base == null) {
return null;
}
if(!base.getClass().isRecord()) {
return null;
}

Objects.requireNonNull(property);
Object result = AccessController.doPrivileged((PrivilegedAction<Object>)() -> {
try {
Method m = base.getClass().getMethod(property.toString());
context.setPropertyResolved(true);
return m.invoke(base);
} catch (NoSuchMethodException e) {
return null;
} catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
});

// Handle custom methods like normal beans
if(!context.isPropertyResolved()) {
return delegate.getValue(context, base, property);
} else {
return result;
}
}

@SuppressWarnings({"removal", "deprecation"})
@Override
public Class<?> getType(ELContext context, Object base, Object property) {
Objects.requireNonNull(base);
if(!base.getClass().isRecord()) {
return null;
}

Objects.requireNonNull(property);
Class<?> result = AccessController.doPrivileged((PrivilegedAction<Class<?>>)() -> {
try {
Method m = base.getClass().getMethod(property.toString());
context.setPropertyResolved(true);
return m.getReturnType();
} catch (NoSuchMethodException e) {
return null;
} catch (SecurityException e) {
throw new RuntimeException(e);
}
});

// Handle custom methods like normal beans
if(!context.isPropertyResolved()) {
return delegate.getType(context, base, property);
} else {
return result;
}
}

@Override
public void setValue(ELContext context, Object base, Object property, Object value) {
throw new PropertyNotWritableException("Cannot write a property on a record");
}

@Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
return true;
}

@Override
public Class<?> getCommonPropertyType(ELContext context, Object base) {
if (base == null) {
return null;
}

return Object.class;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package org.openntf.xsp.jakarta.el.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.faces.el.EvaluationException;
import javax.faces.el.PropertyNotFoundException;
import javax.faces.el.PropertyResolver;

import com.ibm.xsp.el.PropertyResolverImpl;

/**
* @since 3.1.0
*/
public class RecordPropertyResolver extends PropertyResolver {
public static final RecordPropertyResolver INSTANCE = new RecordPropertyResolver();
private final PropertyResolverImpl delegate = new PropertyResolverImpl();

@SuppressWarnings({"removal", "deprecation"})
@Override
public Object getValue(Object base, Object property)
throws EvaluationException, PropertyNotFoundException {
if(base == null) {
return null;
}
if(!base.getClass().isRecord()) {
return null;
}

Objects.requireNonNull(property);
AtomicBoolean resolved = new AtomicBoolean(false);
Object result = AccessController.doPrivileged((PrivilegedAction<Object>)() -> {
try {
Method m = base.getClass().getMethod(property.toString());
resolved.set(true);
return m.invoke(base);
} catch (NoSuchMethodException e) {
return null;
} catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
});

// Handle custom methods like normal beans
if(!resolved.get()) {
return delegate.getValue(base, property);
} else {
return result;
}
}

@Override
public Object getValue(Object base, int index) throws EvaluationException, PropertyNotFoundException {
throw new PropertyNotFoundException();
}

@Override
public void setValue(Object base, Object property, Object value)
throws EvaluationException, PropertyNotFoundException {
throw new EvaluationException("Cannot set values on records");
}

@Override
public void setValue(Object base, int index, Object value)
throws EvaluationException, PropertyNotFoundException {
throw new PropertyNotFoundException();
}

@Override
public boolean isReadOnly(Object base, Object property)
throws EvaluationException, PropertyNotFoundException {
return true;
}

@Override
public boolean isReadOnly(Object base, int index) throws EvaluationException, PropertyNotFoundException {
return true;
}

@SuppressWarnings({"removal", "deprecation", "rawtypes"})
@Override
public Class getType(Object base, Object property)
throws EvaluationException, PropertyNotFoundException {
Objects.requireNonNull(base);
if(!base.getClass().isRecord()) {
return null;
}

Objects.requireNonNull(property);
AtomicBoolean resolved = new AtomicBoolean(false);
Class<?> result = AccessController.doPrivileged((PrivilegedAction<Class<?>>)() -> {
try {
Method m = base.getClass().getMethod(property.toString());
resolved.set(true);
return m.getReturnType();
} catch (NoSuchMethodException e) {
return null;
} catch (SecurityException e) {
throw new RuntimeException(e);
}
});

// Handle custom methods like normal beans
if(!resolved.get()) {
return delegate.getType(base, property);
} else {
return result;
}
}

@SuppressWarnings("rawtypes")
@Override
public Class getType(Object base, int index) throws EvaluationException, PropertyNotFoundException {
throw new PropertyNotFoundException();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.openntf.xsp.jakarta.el.impl;

import javax.faces.el.PropertyResolver;

import com.ibm.xsp.el.PropertyResolverFactory;

/**
* @since 3.1.0
*/
public class RecordPropertyResolverFactory implements PropertyResolverFactory {
public static final RecordPropertyResolverFactory INSTANCE = new RecordPropertyResolverFactory();

@Override
public PropertyResolver getPropertyResolver(Object base) {
if(base != null && base.getClass().isRecord()) {
return RecordPropertyResolver.INSTANCE;
}
return null;
}

}
2 changes: 1 addition & 1 deletion eclipse/bundles/org.openntf.xsp.jakarta.faces/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.openntf.xsp</groupId>
<artifactId>xsp-jakartaee</artifactId>
<version>3.1.0-SNAPSHOT</version>
<version>3.1.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>org.openntf.xsp.jakarta.faces</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,16 @@ public void destroy() {
ServletUtil.getListeners(ctx, ServletContextListener.class)
.forEach(l -> l.contextDestroyed(new ServletContextEvent(ctx)));

tempFiles.forEach(path -> {
try {
Files.deleteIfExists(path);
} catch (IOException e) {
// Ignore
}
});
tempFiles.clear();
synchronized(tempFiles) {
tempFiles.forEach(path -> {
try {
Files.deleteIfExists(path);
} catch (IOException e) {
// Ignore
}
});
tempFiles.clear();
}

ClassLoader cl = (ClassLoader)ctx.getAttribute(PROP_CLASSLOADER);
if(cl != null && cl instanceof Closeable) {
Expand All @@ -220,7 +222,10 @@ public void destroy() {
}
ctx.removeAttribute(PROP_CLASSLOADER);

this.delegate.destroy();
FacesServlet delegate = this.delegate;
if(delegate != null) {
delegate.destroy();
}

super.destroy();
}
Expand Down
Loading

0 comments on commit 2ddeb94

Please sign in to comment.