From 0d24bbb21175b2c62fea6f81e2ab953bf86c37fe Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 18 Jul 2024 17:04:56 -0400 Subject: [PATCH 01/25] Add (currently failing) test for retrieving a single record for a query in NoSQL (Issue #541) --- .../odp/Code/Java/model/PersonRepository.java | 2 + .../odp/Code/Java/rest/NoSQLExample.java | 8 ++++ .../xsp/jakartaee/nsf/nosql/TestNoSQL.java | 43 +++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/PersonRepository.java b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/PersonRepository.java index 3cf9a9ba..5b935ae6 100644 --- a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/PersonRepository.java +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/PersonRepository.java @@ -45,6 +45,8 @@ public interface PersonRepository extends DominoRepository { @ViewEntries(VIEW_PERSONS) Optional findByKey(ViewQuery viewQuery); + Optional findByEmail(String email); + @ViewEntries(VIEW_PERSONS) Stream findByKeyMulti(ViewQuery viewQuery, Sort sorts, PageRequest pagination); diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExample.java b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExample.java index 34fdfa04..f2c9b3eb 100644 --- a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExample.java +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExample.java @@ -402,6 +402,14 @@ public Person getPerson(@PathParam("id") String id) { .orElseThrow(() -> new NotFoundException("Unable to find Person for ID " + id)); } + @Path("byEmail/{email}") + @GET + @Produces(MediaType.APPLICATION_JSON) + public Person getPersonByEmail(@PathParam("email") String email) { + return personRepository.findByEmail(email) + .orElseThrow(() -> new NotFoundException("Unable to find Person for email address " + email)); + } + @Path("{id}") @GET @Controller diff --git a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQL.java b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQL.java index 52675244..d0705ee5 100644 --- a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQL.java +++ b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQL.java @@ -218,6 +218,49 @@ public void testQueryNoteID() throws UnsupportedEncodingException { assertEquals(lastName, result.getString("lastName")); } + @Test + public void testQueryEmail() throws UnsupportedEncodingException { + Client client = getAdminClient(); + + String lastName; + String email; + String unid; + { + WebTarget postTarget = client.target(getRestUrl(null, TestDatabase.MAIN) + "/nosql/create"); //$NON-NLS-1$ + + lastName = "Fooson" + System.nanoTime(); + email = "foo" + System.nanoTime() + "@foo.com"; + MultipartFormDataOutput payload = new MultipartFormDataOutput(); + payload.addFormData("firstName", "Foo" + System.nanoTime(), MediaType.TEXT_PLAIN_TYPE); + payload.addFormData("lastName", lastName, MediaType.TEXT_PLAIN_TYPE); + payload.addFormData("email", email, MediaType.TEXT_PLAIN_TYPE); + + Response response = postTarget.request() + .accept(MediaType.APPLICATION_JSON_TYPE) + .post(Entity.entity(payload, MediaType.MULTIPART_FORM_DATA_TYPE)); + checkResponse(200, response); + String json = response.readEntity(String.class); + + JsonObject person = Json.createReader(new StringReader(json)).readObject(); + unid = person.getString("unid"); + assertNotNull(unid); + assertFalse(unid.isEmpty()); + } + + // Find by note ID + WebTarget queryTarget = client.target(getRestUrl(null, TestDatabase.MAIN) + "/nosql/byEmail/" + URLEncoder.encode(email, "UTF-8")); + + Response response = queryTarget.request() + .accept(MediaType.APPLICATION_JSON_TYPE) + .get(); + checkResponse(200, response); + String json = response.readEntity(String.class); + + JsonObject result = Json.createReader(new StringReader(json)).readObject(); + assertEquals(email, result.getString("email")); + assertEquals(lastName, result.getString("lastName")); + } + @Test public void testQueryNoteIDInt() throws UnsupportedEncodingException { Client client = getAdminClient(); From 1bb1d0fcbdea04696295751907dd6176dd49ed3a Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 18 Jul 2024 17:25:06 -0400 Subject: [PATCH 02/25] Modify DominoDocumentRepositoryProject to handle Stream -> Optional case (Issue #541) --- .../impl/DominoDocumentRepositoryProxy.java | 9 ++++++++- .../odp/Code/Java/rest/NoSQLExample.java | 13 +++++++++---- .../openntf/xsp/jakartaee/nsf/nosql/TestNoSQL.java | 2 ++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/mapping/extension/impl/DominoDocumentRepositoryProxy.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/mapping/extension/impl/DominoDocumentRepositoryProxy.java index 6f4dc8b2..a5f87312 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/mapping/extension/impl/DominoDocumentRepositoryProxy.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/mapping/extension/impl/DominoDocumentRepositoryProxy.java @@ -277,7 +277,14 @@ public Object invoke(Object o, Method method, Object[] args) throws Throwable { } try { - return super.invoke(o, method, args); + Object result = super.invoke(o, method, args); + // Upstream doesn't seem to check for Optional values and returns + // a Stream, so check for that + if(result instanceof Stream && Optional.class.isAssignableFrom(method.getReturnType())) { + return ((Stream)result).findFirst(); + } else { + return result; + } } catch(InvocationTargetException e) { if(e.getCause() instanceof ConstraintViolationException ve) { throw ve; diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExample.java b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExample.java index f2c9b3eb..48327510 100644 --- a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExample.java +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExample.java @@ -147,7 +147,7 @@ public String createPerson( transaction.begin(); try { Person person = new Person(); - composePerson(person, firstName, lastName, birthday, favoriteTime, added, customProperty); + composePerson(person, firstName, lastName, birthday, favoriteTime, added, customProperty, null); person.setEmail(email); personRepository.save(person); @@ -237,7 +237,7 @@ public String createPerson(MimeMultipart body) throws Exception { transaction.begin(); try { Person person = new Person(); - composePerson(person, firstName, lastName, birthday, favoriteTime, added, customProperty); + composePerson(person, firstName, lastName, birthday, favoriteTime, added, customProperty, null); person.setAttachments(attachments); personRepository.save(person); @@ -263,6 +263,7 @@ public Person createPersonJson(MimeMultipart body) throws MessagingException, IO String favoriteTime = ""; String added = ""; String customProperty = ""; + String email = ""; List attachments = new ArrayList<>(); for(int i = 0; i < body.getCount(); i++) { @@ -290,6 +291,9 @@ public Person createPersonJson(MimeMultipart body) throws MessagingException, IO case "customProperty": customProperty = StreamUtil.readString(part.getInputStream()); break; + case "email": + email = StreamUtil.readString(part.getInputStream()); + break; case "attachment": String fileName = disposition.getParameter("filename"); if(StringUtil.isEmpty(fileName)) { @@ -322,7 +326,7 @@ public Person createPersonJson(MimeMultipart body) throws MessagingException, IO } Person person = new Person(); - composePerson(person, firstName, lastName, birthday, favoriteTime, added, customProperty); + composePerson(person, firstName, lastName, birthday, favoriteTime, added, customProperty, email); person.setAttachments(attachments); return personRepository.save(person); @@ -665,7 +669,7 @@ public List queryByEmailEntries(@QueryParam("q") @NotEmpty String search return personRepository.readViewEntries("PersonEmail", -1, false, query, null, null).collect(Collectors.toList()); } - private void composePerson(Person person, String firstName, String lastName, String birthday, String favoriteTime, String added, String customProperty) { + private void composePerson(Person person, String firstName, String lastName, String birthday, String favoriteTime, String added, String customProperty, String email) { person.setFirstName(firstName); person.setLastName(lastName); if(StringUtil.isNotEmpty(birthday)) { @@ -687,6 +691,7 @@ private void composePerson(Person person, String firstName, String lastName, Str } else { person.setAdded(null); } + person.setEmail(email); CustomPropertyType prop = new CustomPropertyType(); prop.setValue(customProperty); diff --git a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQL.java b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQL.java index d0705ee5..b83781a0 100644 --- a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQL.java +++ b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQL.java @@ -245,6 +245,8 @@ public void testQueryEmail() throws UnsupportedEncodingException { unid = person.getString("unid"); assertNotNull(unid); assertFalse(unid.isEmpty()); + assertEquals(lastName, person.getString("lastName", null)); + assertEquals(email, person.getString("email", null)); } // Find by note ID From bcfef8f3f23a7989a41bed230819c25cd3949bc4 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 18 Jul 2024 18:53:35 -0400 Subject: [PATCH 03/25] Bump JNoSQL to 1.1.1 and add some first-steps support work towards Records (Issue #544) --- ...g.eclipse.jnosql.communication.ValueReader | 3 +- .../driver/impl/IterableValueReader.java | 23 +++++++++++ .../nosql/weaving/NoSQLWeavingHook.java | 38 ++++++++++++++++++- osgi-deps/pom.xml | 2 +- 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IterableValueReader.java diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/services/org.eclipse.jnosql.communication.ValueReader b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/services/org.eclipse.jnosql.communication.ValueReader index 9978fac0..a5b5d7c2 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/services/org.eclipse.jnosql.communication.ValueReader +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/services/org.eclipse.jnosql.communication.ValueReader @@ -1 +1,2 @@ -org.openntf.xsp.jakarta.nosql.communication.driver.impl.InstantValueReader \ No newline at end of file +org.openntf.xsp.jakarta.nosql.communication.driver.impl.InstantValueReader +org.openntf.xsp.jakarta.nosql.communication.driver.impl.IterableValueReader diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IterableValueReader.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IterableValueReader.java new file mode 100644 index 00000000..cfb8455f --- /dev/null +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IterableValueReader.java @@ -0,0 +1,23 @@ +package org.openntf.xsp.jakarta.nosql.communication.driver.impl; + +import java.util.Collections; + +import org.eclipse.jnosql.communication.ValueReader; + +public class IterableValueReader implements ValueReader { + + @Override + public boolean test(Class t) { + return Iterable.class.isAssignableFrom(t); + } + + @SuppressWarnings("unchecked") + @Override + public T read(Class type, Object value) { + if(value instanceof Iterable i) { + return (T)i; + } + return (T)Collections.singleton(value); + } + +} diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/weaving/NoSQLWeavingHook.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/weaving/NoSQLWeavingHook.java index ee5ad73f..fb6a3c61 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/weaving/NoSQLWeavingHook.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/weaving/NoSQLWeavingHook.java @@ -49,11 +49,12 @@ public void weave(WovenClass c) { switch(c.getClassName()) { case "org.eclipse.jnosql.mapping.metadata.ClassScanner" -> processClassScanner(c); //$NON-NLS-1$ case "org.eclipse.jnosql.mapping.metadata.ClassConverter" -> processClassConverter(c); //$NON-NLS-1$ - case "org.eclipse.jnosql.communication.ValueReaderDecorator" -> processValueReader(c); //$NON-NLS-1$ + case "org.eclipse.jnosql.communication.ValueReaderDecorator" -> processValueReaderDecorator(c); //$NON-NLS-1$ case "org.eclipse.jnosql.communication.ValueWriter" -> processValueWriter(c); //$NON-NLS-1$ case "org.eclipse.jnosql.communication.ValueWriterDecorator" -> processValueWriterDecorator(c); //$NON-NLS-1$ case "org.eclipse.jnosql.communication.TypeReferenceReaderDecorator" -> processTypeReferenceReader(c); //$NON-NLS-1$ case "org.eclipse.jnosql.mapping.reflection.DefaultGenericFieldMetadata" -> processGenericFieldMapping(c); //$NON-NLS-1$ + case "org.eclipse.jnosql.mapping.metadata.ConstructorBuilder" -> processConstructorBuilder(c); //$NON-NLS-1$ } } @@ -76,7 +77,7 @@ private void processClassScanner(WovenClass c) { } @SuppressWarnings("nls") - private void processValueReader(WovenClass c) { + private void processValueReaderDecorator(WovenClass c) { CtClass cc = defrost(c, ValueReader.class); try { @@ -106,6 +107,7 @@ private void processValueReader(WovenClass c) { return $1.cast($2); } java.lang.Iterable instances = org.glassfish.hk2.osgiresourcelocator.ServiceLoader.lookupProviderInstances(org.eclipse.jnosql.communication.ValueReader.class); + System.out.println("got instances: " + instances); java.util.List readers = java.util.stream.StreamSupport.stream(instances.spliterator(), false).toList(); for(int i = 0; i < readers.size(); i++) { org.eclipse.jnosql.communication.ValueReader r = (org.eclipse.jnosql.communication.ValueReader)readers.get(i); @@ -308,4 +310,36 @@ private void processGenericFieldMapping(WovenClass c) { t.printStackTrace(); } } + + @SuppressWarnings("nls") + private void processConstructorBuilder(WovenClass c) { + ClassPool pool = new ClassPool(); + pool.appendClassPath(new LoaderClassPath(ClassLoader.getSystemClassLoader())); + pool.appendClassPath(new LoaderClassPath(c.getBundleWiring().getClassLoader())); + CtClass cc; + try(InputStream is = new ByteArrayInputStream(c.getBytes())) { + cc = pool.makeClass(is); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + cc.defrost(); + + try { + // ConstructorBuilder of(ConstructorMetadata constructor) + { + String body = """ + { + java.lang.Iterable instances = org.glassfish.hk2.osgiresourcelocator.ServiceLoader.lookupProviderInstances(org.eclipse.jnosql.mapping.metadata.ConstructorBuilderSupplier.class); + org.eclipse.jnosql.mapping.metadata.ConstructorBuilderSupplier supplier = (org.eclipse.jnosql.mapping.metadata.ConstructorBuilderSupplier)instances.iterator().next(); + return supplier.apply($1); + }"""; + CtMethod m = cc.getDeclaredMethod("of"); //$NON-NLS-1$ + m.setBody(body); + } + + c.setBytes(cc.toBytecode()); + } catch(Throwable t) { + t.printStackTrace(); + } + } } diff --git a/osgi-deps/pom.xml b/osgi-deps/pom.xml index 02161c18..5f9f6c36 100644 --- a/osgi-deps/pom.xml +++ b/osgi-deps/pom.xml @@ -43,7 +43,7 @@ 5.1.2.Final 6.2.8.Final 2.1.5.Final - 1.1.1-RC1 + 1.1.1 1.1.1 10.1.23 From cdd7cd097dd1170bfa3b7e2e42c266b50f26e469 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Fri, 19 Jul 2024 12:34:10 -0400 Subject: [PATCH 04/25] Add support for records in NoSQL, EL, and Pages (Issue #544) --- .../META-INF/MANIFEST.MF | 3 +- .../xsp/jakarta/el/impl/FacesELContext.java | 1 + .../el/impl/RecordPropertyELResolver.java | 97 +++++++++++++++++++ .../META-INF/MANIFEST.MF | 3 +- ...g.eclipse.jnosql.communication.ValueReader | 3 +- .../driver/impl/IntValueReader.java | 26 +++++ .../driver/impl/IterableValueReader.java | 23 ----- .../driver/impl/ListValueReader.java | 27 ++++++ .../nosql/weaving/NoSQLWeavingHook.java | 40 +++++++- .../META-INF/MANIFEST.MF | 1 + .../xsp/jakarta/pages/el/NSFELResolver.java | 2 + .../META-INF/MANIFEST.MF | 1 + .../osgiresourcelocator/ServiceLoader.java | 35 ++++++- 13 files changed, 234 insertions(+), 28 deletions(-) create mode 100644 eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyELResolver.java create mode 100644 eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IntValueReader.java delete mode 100644 eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IterableValueReader.java create mode 100644 eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/ListValueReader.java diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.el/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakarta.el/META-INF/MANIFEST.MF index 2da2ddfa..9e78a4b5 100755 --- a/eclipse/bundles/org.openntf.xsp.jakarta.el/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakarta.el/META-INF/MANIFEST.MF @@ -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" diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/FacesELContext.java b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/FacesELContext.java index 5d2e8480..203a3a57 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/FacesELContext.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/FacesELContext.java @@ -53,6 +53,7 @@ public FacesELContext(ExpressionFactory factory) { addELResolver(new BeanNameELResolver(new FacesBeanNameResolver())); addELResolver(new XSPELResolver()); + addELResolver(new RecordPropertyELResolver()); } @Override diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyELResolver.java b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyELResolver.java new file mode 100644 index 00000000..f2f54115 --- /dev/null +++ b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyELResolver.java @@ -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)() -> { + 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>)() -> { + 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; + } + +} diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/MANIFEST.MF index 09925494..6cd50c48 100755 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/MANIFEST.MF @@ -6,7 +6,8 @@ Automatic-Module-Name: org.openntf.xsp.jakarta.nosql.driver Bundle-Version: 3.1.0.qualifier Bundle-Vendor: OpenNTF Bundle-RequiredExecutionEnvironment: JavaSE-17 -Import-Package: jakarta.data, +Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)", + jakarta.data, jakarta.data.page, jakarta.data.repository, jakarta.enterprise.context;version="3.0.0", diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/services/org.eclipse.jnosql.communication.ValueReader b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/services/org.eclipse.jnosql.communication.ValueReader index a5b5d7c2..c0156f52 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/services/org.eclipse.jnosql.communication.ValueReader +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/META-INF/services/org.eclipse.jnosql.communication.ValueReader @@ -1,2 +1,3 @@ org.openntf.xsp.jakarta.nosql.communication.driver.impl.InstantValueReader -org.openntf.xsp.jakarta.nosql.communication.driver.impl.IterableValueReader +org.openntf.xsp.jakarta.nosql.communication.driver.impl.ListValueReader +org.openntf.xsp.jakarta.nosql.communication.driver.impl.IntValueReader diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IntValueReader.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IntValueReader.java new file mode 100644 index 00000000..0ecc8187 --- /dev/null +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IntValueReader.java @@ -0,0 +1,26 @@ +package org.openntf.xsp.jakarta.nosql.communication.driver.impl; + +import jakarta.annotation.Priority; +import org.eclipse.jnosql.communication.ValueReader; + +@Priority(1) +public class IntValueReader implements ValueReader { + + @Override + public boolean test(Class t) { + return Integer.class.equals(t) || int.class.equals(t); + } + + @SuppressWarnings("unchecked") + @Override + public T read(Class type, Object value) { + if(value instanceof Number v) { + return (T)Integer.valueOf(v.intValue()); + } else if(int.class.equals(type)) { + return (T)Integer.valueOf(0); + } else { + return (T)null; + } + } + +} diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IterableValueReader.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IterableValueReader.java deleted file mode 100644 index cfb8455f..00000000 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/IterableValueReader.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.openntf.xsp.jakarta.nosql.communication.driver.impl; - -import java.util.Collections; - -import org.eclipse.jnosql.communication.ValueReader; - -public class IterableValueReader implements ValueReader { - - @Override - public boolean test(Class t) { - return Iterable.class.isAssignableFrom(t); - } - - @SuppressWarnings("unchecked") - @Override - public T read(Class type, Object value) { - if(value instanceof Iterable i) { - return (T)i; - } - return (T)Collections.singleton(value); - } - -} diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/ListValueReader.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/ListValueReader.java new file mode 100644 index 00000000..2dc509f5 --- /dev/null +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/ListValueReader.java @@ -0,0 +1,27 @@ +package org.openntf.xsp.jakarta.nosql.communication.driver.impl; + +import java.util.Collections; +import java.util.List; +import java.util.stream.StreamSupport; + +import org.eclipse.jnosql.communication.ValueReader; + +public class ListValueReader implements ValueReader { + + @Override + public boolean test(Class t) { + return List.class.isAssignableFrom(t); + } + + @SuppressWarnings("unchecked") + @Override + public T read(Class type, Object value) { + if(value instanceof List i) { + return (T)i; + } else if(value instanceof Iterable i) { + return (T)StreamSupport.stream(i.spliterator(), false).toList(); + } + return (T)Collections.singletonList(value); + } + +} diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/weaving/NoSQLWeavingHook.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/weaving/NoSQLWeavingHook.java index fb6a3c61..d99ba23a 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/weaving/NoSQLWeavingHook.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/weaving/NoSQLWeavingHook.java @@ -55,6 +55,7 @@ public void weave(WovenClass c) { case "org.eclipse.jnosql.communication.TypeReferenceReaderDecorator" -> processTypeReferenceReader(c); //$NON-NLS-1$ case "org.eclipse.jnosql.mapping.reflection.DefaultGenericFieldMetadata" -> processGenericFieldMapping(c); //$NON-NLS-1$ case "org.eclipse.jnosql.mapping.metadata.ConstructorBuilder" -> processConstructorBuilder(c); //$NON-NLS-1$ + case "org.eclipse.jnosql.mapping.reflection.DefaultConstructorBuilder" -> processDefaultConstructorBuilder(c); //$NON-NLS-1$ } } @@ -107,7 +108,6 @@ private void processValueReaderDecorator(WovenClass c) { return $1.cast($2); } java.lang.Iterable instances = org.glassfish.hk2.osgiresourcelocator.ServiceLoader.lookupProviderInstances(org.eclipse.jnosql.communication.ValueReader.class); - System.out.println("got instances: " + instances); java.util.List readers = java.util.stream.StreamSupport.stream(instances.spliterator(), false).toList(); for(int i = 0; i < readers.size(); i++) { org.eclipse.jnosql.communication.ValueReader r = (org.eclipse.jnosql.communication.ValueReader)readers.get(i); @@ -342,4 +342,42 @@ private void processConstructorBuilder(WovenClass c) { t.printStackTrace(); } } + + @SuppressWarnings("nls") + private void processDefaultConstructorBuilder(WovenClass c) { + ClassPool pool = new ClassPool(); + pool.appendClassPath(new LoaderClassPath(ClassLoader.getSystemClassLoader())); + pool.appendClassPath(new LoaderClassPath(c.getBundleWiring().getClassLoader())); + CtClass cc; + try(InputStream is = new ByteArrayInputStream(c.getBytes())) { + cc = pool.makeClass(is); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + cc.defrost(); + + try { + // void addEmptyParameter() + { + String body = """ + { + java.lang.reflect.Constructor constructor = ((org.eclipse.jnosql.mapping.reflection.DefaultConstructorMetadata) this.metadata).constructor(); + Class type = constructor.getParameterTypes()[this.values.size()]; + if(boolean.class.equals(type)) { + this.values.add(Boolean.TRUE); + } else if(type.isPrimitive()) { + this.values.add(Integer.valueOf(0)); + } else { + this.values.add(null); + } + }"""; + CtMethod m = cc.getDeclaredMethod("addEmptyParameter"); //$NON-NLS-1$ + m.setBody(body); + } + + c.setBytes(cc.toBytecode()); + } catch(Throwable t) { + t.printStackTrace(); + } + } } diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.pages/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakarta.pages/META-INF/MANIFEST.MF index 6fddad5e..a6340cf1 100755 --- a/eclipse/bundles/org.openntf.xsp.jakarta.pages/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakarta.pages/META-INF/MANIFEST.MF @@ -30,5 +30,6 @@ Import-Package: com.ibm.commons.util, javax.servlet.http;version="2.5.0", org.eclipse.core.runtime;version="3.5.0", org.eclipse.osgi.util, + org.openntf.xsp.jakarta.el.impl;version="3.1.0", org.osgi.framework;version="1.8.0" Export-Package: org.openntf.xsp.jakarta.pages.webapp;version="3.1.0" diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/el/NSFELResolver.java b/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/el/NSFELResolver.java index 4568ea46..219c12b9 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/el/NSFELResolver.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/el/NSFELResolver.java @@ -21,6 +21,7 @@ import jakarta.enterprise.inject.literal.NamedLiteral; import jakarta.enterprise.inject.spi.CDI; import jakarta.servlet.jsp.el.ImplicitObjectELResolver; +import org.openntf.xsp.jakarta.el.impl.RecordPropertyELResolver; public class NSFELResolver extends CompositeELResolver { public static final NSFELResolver instance = new NSFELResolver(); @@ -28,6 +29,7 @@ public class NSFELResolver extends CompositeELResolver { public NSFELResolver() { add(new ImplicitObjectELResolver()); add(new BeanNameELResolver(new CDIBeanResolver())); + add(new RecordPropertyELResolver()); } public static class CDIBeanResolver extends BeanNameResolver { diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/META-INF/MANIFEST.MF index a75bb780..3acf9389 100755 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-17 Export-Package: org.glassfish.hk2.osgiresourcelocator Import-Package: com.ibm.designer.runtime.domino.adapter, com.ibm.domino.xsp.module.nsf, + jakarta.annotation;version="[2.1.0,3.0.0)", org.osgi.framework;version="1.8.0" Bundle-ActivationPolicy: lazy Bundle-Activator: org.glassfish.hk2.osgiresourcelocator.Activator diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/src/org/glassfish/hk2/osgiresourcelocator/ServiceLoader.java b/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/src/org/glassfish/hk2/osgiresourcelocator/ServiceLoader.java index 8229b7c5..fb747184 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/src/org/glassfish/hk2/osgiresourcelocator/ServiceLoader.java +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/src/org/glassfish/hk2/osgiresourcelocator/ServiceLoader.java @@ -27,10 +27,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -42,6 +44,8 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; +import jakarta.annotation.Priority; + import com.ibm.designer.runtime.domino.adapter.ComponentModule; import com.ibm.domino.xsp.module.nsf.NotesContext; @@ -118,7 +122,9 @@ public static Iterable lookupProviderClasses(Class serviceClass) { // TODO support OSGi NotesContext - return result; + return result.stream() + .sorted(ClassPriorityComparator.DESCENDING) + .toList(); } // ******************************************************************************* @@ -226,4 +232,31 @@ private static Stream parseServiceClassNames(URL url) { } return result.stream(); } + + @SuppressWarnings("rawtypes") + public enum ClassPriorityComparator implements Comparator { + ASCENDING(true), DESCENDING(false); + + private final boolean ascending; + + private ClassPriorityComparator(boolean ascending) { + this.ascending = ascending; + } + + @Override + public int compare(Class a, Class b) { + int priorityA = Optional.ofNullable(((Class)a).getAnnotation(Priority.class)) + .map(Priority::value) + .orElse(ascending ? Integer.MAX_VALUE : 0); + int priorityB = Optional.ofNullable(((Class)b).getAnnotation(Priority.class)) + .map(Priority::value) + .orElse(ascending ? Integer.MAX_VALUE : 0); + if(ascending) { + return Integer.compare(priorityA, priorityB); + } else { + return Integer.compare(priorityB, priorityA); + } + } + + } } From 9666183cdfe5562e19c444a47f2667f39628f413 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Fri, 19 Jul 2024 13:52:30 -0400 Subject: [PATCH 05/25] Fix Data Query language in PersonRepository --- .../odp/Code/Java/model/PersonRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/PersonRepository.java b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/PersonRepository.java index 5b935ae6..17157689 100644 --- a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/PersonRepository.java +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/PersonRepository.java @@ -50,7 +50,7 @@ public interface PersonRepository extends DominoRepository { @ViewEntries(VIEW_PERSONS) Stream findByKeyMulti(ViewQuery viewQuery, Sort sorts, PageRequest pagination); - @Query("select * from Person where modified >= @modified") + @Query("where modified >= :modified") Stream findModifiedSince(@Param("modified") Instant modified); @ViewDocuments(VIEW_PERSONS_CAT) From 39fb41db375a902d56574bd9ea6c9157b3150db0 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Fri, 19 Jul 2024 14:29:26 -0400 Subject: [PATCH 06/25] Remove outdated XPages library service document --- .../res/META-INF/services/com.ibm.xsp.Library | 1 - 1 file changed, 1 deletion(-) delete mode 100644 eclipse/bundles/org.openntf.xsp.jakarta.el/res/META-INF/services/com.ibm.xsp.Library diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.el/res/META-INF/services/com.ibm.xsp.Library b/eclipse/bundles/org.openntf.xsp.jakarta.el/res/META-INF/services/com.ibm.xsp.Library deleted file mode 100644 index a1748a97..00000000 --- a/eclipse/bundles/org.openntf.xsp.jakarta.el/res/META-INF/services/com.ibm.xsp.Library +++ /dev/null @@ -1 +0,0 @@ -org.openntf.xsp.jakarta.el.ELLibrary \ No newline at end of file From 2cf3bb0625e3bcf9533255dda98702a443e36454 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Mon, 29 Jul 2024 10:11:38 -0400 Subject: [PATCH 07/25] Improve record handling in REST, Pages, and XPages (Issue #546) --- .../xsp/jakarta/el/ELApplicationListener.java | 3 + .../el/impl/RecordPropertyResolver.java | 121 ++++++++++++++++++ .../impl/RecordPropertyResolverFactory.java | 21 +++ .../odp/Code/Java/bean/RecordProducer.java | 17 +++ .../Java/bean/RecordProducer.java.metadata | 12 ++ .../odp/Code/Java/model/RecordExample.java | 24 ++++ .../Java/model/RecordExample.java.metadata | 12 ++ .../Code/Java/rest/NoSQLRecordExample.java | 33 +++++ .../rest/NoSQLRecordExample.java.metadata | 12 ++ .../odp/WebContent/recordExample.jsp | 28 ++++ .../odp/WebContent/recordExample.xhtml | 30 +++++ .../odp/XPages/recordExample.xsp | 4 + .../odp/XPages/recordExample.xsp.metadata | 12 ++ .../odp/XPages/records.xsp.metadata | 12 ++ eclipse/nsfs/nsf-jakartaee-example/pom.xml | 2 +- .../xsp/jakartaee/nsf/el/TestElRecords.java | 46 +++++++ .../xsp/jakartaee/nsf/jsf/TestJsfRecords.java | 48 +++++++ .../xsp/jakartaee/nsf/jsp/TestJspRecords.java | 46 +++++++ .../jakartaee/nsf/nosql/TestNoSQLRecords.java | 80 ++++++++++++ 19 files changed, 562 insertions(+), 1 deletion(-) create mode 100644 eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyResolver.java create mode 100644 eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyResolverFactory.java create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/bean/RecordProducer.java create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/bean/RecordProducer.java.metadata create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/RecordExample.java create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/RecordExample.java.metadata create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLRecordExample.java create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLRecordExample.java.metadata create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/WebContent/recordExample.jsp create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/WebContent/recordExample.xhtml create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/XPages/recordExample.xsp create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/XPages/recordExample.xsp.metadata create mode 100644 eclipse/nsfs/nsf-jakartaee-example/odp/XPages/records.xsp.metadata create mode 100644 eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/el/TestElRecords.java create mode 100644 eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/jsf/TestJsfRecords.java create mode 100644 eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/jsp/TestJspRecords.java create mode 100644 eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLRecords.java diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/ELApplicationListener.java b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/ELApplicationListener.java index 03365c54..35cef688 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/ELApplicationListener.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/ELApplicationListener.java @@ -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; @@ -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); } } diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyResolver.java b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyResolver.java new file mode 100644 index 00000000..f0555787 --- /dev/null +++ b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyResolver.java @@ -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)() -> { + 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>)() -> { + 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(); + } + +} diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyResolverFactory.java b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyResolverFactory.java new file mode 100644 index 00000000..bfbfc820 --- /dev/null +++ b/eclipse/bundles/org.openntf.xsp.jakarta.el/src/org/openntf/xsp/jakarta/el/impl/RecordPropertyResolverFactory.java @@ -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; + } + +} diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/bean/RecordProducer.java b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/bean/RecordProducer.java new file mode 100644 index 00000000..1a5879af --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/bean/RecordProducer.java @@ -0,0 +1,17 @@ +package bean; + +import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Named; +import model.RecordExample; + +/** + * This bean is used by tests to ensure that reading record properties in + * XPages, JSP, and Faces contexts works. + */ +@RequestScoped +@Named("RecordProducer") +public class RecordProducer { + public RecordExample getRecordExample() { + return new RecordExample("1111", "I am the example", 3); + } +} diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/bean/RecordProducer.java.metadata b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/bean/RecordProducer.java.metadata new file mode 100644 index 00000000..c03f6215 --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/bean/RecordProducer.java.metadata @@ -0,0 +1,12 @@ + + + + bean/RecordProducer.java + + + 34567Cg~[ + + + bean/RecordProducer.java + + diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/RecordExample.java b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/RecordExample.java new file mode 100644 index 00000000..c046de9a --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/RecordExample.java @@ -0,0 +1,24 @@ +package model; + +import java.util.Optional; + +import org.openntf.xsp.jakarta.nosql.mapping.extension.DominoRepository; + +import jakarta.nosql.Column; +import jakarta.nosql.Entity; +import jakarta.nosql.Id; + +@Entity("RecordExample") +public record RecordExample( + @Id + String unid, + @Column + String name, + @Column + int index + ) { + + public interface Repository extends DominoRepository { + Optional findByName(String name); + } +} diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/RecordExample.java.metadata b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/RecordExample.java.metadata new file mode 100644 index 00000000..393df870 --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/model/RecordExample.java.metadata @@ -0,0 +1,12 @@ + + + + model/RecordExample.java + + + 34567Cg~[ + + + model/RecordExample.java + + diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLRecordExample.java b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLRecordExample.java new file mode 100644 index 00000000..a0867d5f --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLRecordExample.java @@ -0,0 +1,33 @@ +package rest; + +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import model.RecordExample; + +@Path("nosqlRecordDocs") +public class NoSQLRecordExample { + @Inject + private RecordExample.Repository repository; + + @Path("byName/{name}") + @GET + @Produces(MediaType.APPLICATION_JSON) + public RecordExample getByKey(@PathParam("name") String name) { + return repository.findByName(name.replace('+', ' ')) + .orElseThrow(() -> new NotFoundException("No record found for name " + name)); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public RecordExample create(RecordExample entity) { + return repository.insert(entity); + } +} diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLRecordExample.java.metadata b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLRecordExample.java.metadata new file mode 100644 index 00000000..ad429f4c --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLRecordExample.java.metadata @@ -0,0 +1,12 @@ + + + + rest/NoSQLRecordExample.java + + + 34567Cg~[ + + + rest/NoSQLRecordExample.java + + diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/WebContent/recordExample.jsp b/eclipse/nsfs/nsf-jakartaee-example/odp/WebContent/recordExample.jsp new file mode 100644 index 00000000..67190121 --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/WebContent/recordExample.jsp @@ -0,0 +1,28 @@ +<%-- + + Copyright (c) 2018-2024 Contributors to the XPages Jakarta EE Support Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--%> +<%@page contentType="text/html" pageEncoding="UTF-8" trimDirectiveWhitespaces="true" %> +<%@taglib prefix="c" uri="jakarta.tags.core" %> + + + + Record Example + + + + + \ No newline at end of file diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/WebContent/recordExample.xhtml b/eclipse/nsfs/nsf-jakartaee-example/odp/WebContent/recordExample.xhtml new file mode 100644 index 00000000..dde7f84d --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/WebContent/recordExample.xhtml @@ -0,0 +1,30 @@ + + + + + + + Record Example + + + + + \ No newline at end of file diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/XPages/recordExample.xsp b/eclipse/nsfs/nsf-jakartaee-example/odp/XPages/recordExample.xsp new file mode 100644 index 00000000..5e31a4cd --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/XPages/recordExample.xsp @@ -0,0 +1,4 @@ + + + + diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/XPages/recordExample.xsp.metadata b/eclipse/nsfs/nsf-jakartaee-example/odp/XPages/recordExample.xsp.metadata new file mode 100644 index 00000000..fa2c00cb --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/XPages/recordExample.xsp.metadata @@ -0,0 +1,12 @@ + + + + recordExample.xsp + + + gC~4K + + + recordExample.xsp + + diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/XPages/records.xsp.metadata b/eclipse/nsfs/nsf-jakartaee-example/odp/XPages/records.xsp.metadata new file mode 100644 index 00000000..9faa6f2f --- /dev/null +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/XPages/records.xsp.metadata @@ -0,0 +1,12 @@ + + + + records.xsp + + + gC~4K + + + records.xsp + + diff --git a/eclipse/nsfs/nsf-jakartaee-example/pom.xml b/eclipse/nsfs/nsf-jakartaee-example/pom.xml index 8b708928..fdb90ec9 100644 --- a/eclipse/nsfs/nsf-jakartaee-example/pom.xml +++ b/eclipse/nsfs/nsf-jakartaee-example/pom.xml @@ -20,7 +20,7 @@ ${project.baseDir}/../../../releng/org.openntf.xsp.jakartaee.updatesite/target/repository XPages Jakarta EE Example - 17 + 17 JavaSE-17 diff --git a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/el/TestElRecords.java b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/el/TestElRecords.java new file mode 100644 index 00000000..c64f1f8a --- /dev/null +++ b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/el/TestElRecords.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018-2024 Contributors to the XPages Jakarta EE Support Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package it.org.openntf.xsp.jakartaee.nsf.el; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import it.org.openntf.xsp.jakartaee.AbstractWebClientTest; +import it.org.openntf.xsp.jakartaee.BrowserArgumentsProvider; +import it.org.openntf.xsp.jakartaee.TestDatabase; + +@SuppressWarnings("nls") +public class TestElRecords extends AbstractWebClientTest { + @ParameterizedTest + @ArgumentsSource(BrowserArgumentsProvider.class) + public void testXPagesResolution(WebDriver driver) { + driver.get(getRootUrl(driver, TestDatabase.MAIN) + "/recordExample.xsp"); + + try { + WebElement dd = driver.findElement(By.cssSelector(".text-output")); + assertEquals("I am the example", dd.getText()); + } catch(NoSuchElementException e) { + fail("Encountered exception with HTML: " + driver.getPageSource(), e); + } + } +} diff --git a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/jsf/TestJsfRecords.java b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/jsf/TestJsfRecords.java new file mode 100644 index 00000000..2acaf5d1 --- /dev/null +++ b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/jsf/TestJsfRecords.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2018-2024 Contributors to the XPages Jakarta EE Support Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package it.org.openntf.xsp.jakartaee.nsf.jsf; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import it.org.openntf.xsp.jakartaee.AbstractWebClientTest; +import it.org.openntf.xsp.jakartaee.BrowserArgumentsProvider; +import it.org.openntf.xsp.jakartaee.TestDatabase; + +@SuppressWarnings("nls") +public class TestJsfRecords extends AbstractWebClientTest { + @ParameterizedTest + @ArgumentsSource(BrowserArgumentsProvider.class) + @Disabled("Disable until JEE 11 and official records support") + public void testResolution(WebDriver driver) { + driver.get(getRootUrl(driver, TestDatabase.MAIN) + "/recordExample.xhtml"); + + try { + WebElement dd = driver.findElement(By.cssSelector(".text-output")); + assertEquals("I am the example", dd.getText()); + } catch(NoSuchElementException e) { + fail("Encountered exception with HTML: " + driver.getPageSource(), e); + } + } +} diff --git a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/jsp/TestJspRecords.java b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/jsp/TestJspRecords.java new file mode 100644 index 00000000..f4f7673d --- /dev/null +++ b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/jsp/TestJspRecords.java @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2018-2024 Contributors to the XPages Jakarta EE Support Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package it.org.openntf.xsp.jakartaee.nsf.jsp; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import it.org.openntf.xsp.jakartaee.AbstractWebClientTest; +import it.org.openntf.xsp.jakartaee.BrowserArgumentsProvider; +import it.org.openntf.xsp.jakartaee.TestDatabase; + +@SuppressWarnings("nls") +public class TestJspRecords extends AbstractWebClientTest { + @ParameterizedTest + @ArgumentsSource(BrowserArgumentsProvider.class) + public void testResolution(WebDriver driver) { + driver.get(getRootUrl(driver, TestDatabase.MAIN) + "/recordExample.jsp"); + + try { + WebElement dd = driver.findElement(By.cssSelector(".text-output")); + assertEquals("I am the example", dd.getText()); + } catch(NoSuchElementException e) { + fail("Encountered exception with HTML: " + driver.getPageSource(), e); + } + } +} diff --git a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLRecords.java b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLRecords.java new file mode 100644 index 00000000..717152ea --- /dev/null +++ b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLRecords.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2018-2024 Contributors to the XPages Jakarta EE Support Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package it.org.openntf.xsp.jakartaee.nsf.nosql; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.io.StringReader; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +import org.junit.jupiter.api.Test; + +import it.org.openntf.xsp.jakartaee.AbstractWebClientTest; +import it.org.openntf.xsp.jakartaee.TestDatabase; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.Response; + +@SuppressWarnings("nls") +public class TestNoSQLRecords extends AbstractWebClientTest { + @Test + public void testRecordDoc() throws UnsupportedEncodingException { + Client client = getAnonymousClient(); + + // Create a new doc + String unid; + String name; + { + name = "Some Key " + System.currentTimeMillis(); + JsonObject payload = Json.createObjectBuilder() + .add("name", name) + .add("index", 4) + .build(); + + WebTarget postTarget = client.target(getRestUrl(null, TestDatabase.MAIN) + "/nosqlRecordDocs"); + Response response = postTarget.request().post(Entity.json(payload)); + checkResponse(200, response); + + String json = response.readEntity(String.class); + JsonObject jsonObject = Json.createReader(new StringReader(json)).readObject(); + unid = jsonObject.getString("unid", null); + assertNotNull(unid); + assertFalse(unid.isEmpty()); + assertEquals(name, jsonObject.getString("name", null)); + assertEquals(4, jsonObject.getInt("index", 0)); + } + + // Fetch the doc + { + WebTarget target = client.target(getRestUrl(null, TestDatabase.MAIN) + "/nosqlRecordDocs/byName/" + URLEncoder.encode(name, "UTF-8")); + Response response = target.request().get(); + checkResponse(200, response); + String json = response.readEntity(String.class); + + JsonObject jsonObject = Json.createReader(new StringReader(json)).readObject(); + + assertEquals(unid, jsonObject.getString("unid")); + assertEquals(name, jsonObject.getString("name", null)); + assertEquals(4, jsonObject.getInt("index", 0)); + } + } +} From 6de70cc103bb20c5940a42a28a86e74f926e6a73 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Mon, 19 Aug 2024 10:04:31 -0400 Subject: [PATCH 08/25] Make CDClassContributor#getBeanClasses default to an empty list --- .../xsp/jakarta/cdi/discovery/CDIClassContributor.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.cdi/src/org/openntf/xsp/jakarta/cdi/discovery/CDIClassContributor.java b/eclipse/bundles/org.openntf.xsp.jakarta.cdi/src/org/openntf/xsp/jakarta/cdi/discovery/CDIClassContributor.java index 38b0a789..74aac5ef 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.cdi/src/org/openntf/xsp/jakarta/cdi/discovery/CDIClassContributor.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.cdi/src/org/openntf/xsp/jakarta/cdi/discovery/CDIClassContributor.java @@ -23,7 +23,9 @@ public interface CDIClassContributor { public static final String EXTENSION_POINT = CDIClassContributor.class.getName(); - Collection> getBeanClasses(); + default Collection> getBeanClasses() { + return Collections.emptyList(); + } default Collection getExtensions() { return Collections.emptyList(); From 1017ff6ec45936820a09d1a1a01559fcc7a946a3 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Mon, 19 Aug 2024 10:05:05 -0400 Subject: [PATCH 09/25] Expand DominoContainer timeout duration for slow-server scenarios --- .../it/org/openntf/xsp/jakartaee/docker/DominoContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/docker/DominoContainer.java b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/docker/DominoContainer.java index 3c04720e..62485a57 100644 --- a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/docker/DominoContainer.java +++ b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/docker/DominoContainer.java @@ -181,7 +181,7 @@ public DominoContainer() { withImagePullPolicy(imageName -> false); withExposedPorts(80, JACOCO_PORT); - withStartupTimeout(Duration.ofMinutes(4)); + withStartupTimeout(Duration.ofMinutes(10)); waitingFor( new WaitAllStrategy() .withStrategy(new LogMessageWaitStrategy() From 2bd45d86ff9572fadc0b43f9e3b6dac1ff732d75 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Mon, 19 Aug 2024 10:06:02 -0400 Subject: [PATCH 10/25] Make LibraryUtil.findExtensions synchronize on the internal cache (Issue #542) --- .../src/org/openntf/xsp/jakartaee/util/LibraryUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java index 65301033..9c065205 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java @@ -302,7 +302,9 @@ public static Properties getXspProperties(ComponentModule module) { */ @SuppressWarnings("unchecked") public static List findExtensions(Class extensionClass) { - return (List)EXTENSION_CACHE.computeIfAbsent(extensionClass, LibraryUtil::findExtensionsUncached); + synchronized(EXTENSION_CACHE) { + return (List)EXTENSION_CACHE.computeIfAbsent(extensionClass, LibraryUtil::findExtensionsUncached); + } } /** From 52737dcf3854c17f7d35a61ffc2307dc26f5f47a Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Mon, 19 Aug 2024 10:06:28 -0400 Subject: [PATCH 11/25] Modify MetricsExtensionContributor to always provide the extension when MP is enabled (Issue #547) --- .../metrics/MetricsExtensionContributor.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/eclipse/bundles/org.openntf.xsp.microprofile.metrics/src/org/openntf/xsp/microprofile/metrics/MetricsExtensionContributor.java b/eclipse/bundles/org.openntf.xsp.microprofile.metrics/src/org/openntf/xsp/microprofile/metrics/MetricsExtensionContributor.java index 00c951cf..b8316708 100644 --- a/eclipse/bundles/org.openntf.xsp.microprofile.metrics/src/org/openntf/xsp/microprofile/metrics/MetricsExtensionContributor.java +++ b/eclipse/bundles/org.openntf.xsp.microprofile.metrics/src/org/openntf/xsp/microprofile/metrics/MetricsExtensionContributor.java @@ -26,22 +26,13 @@ public class MetricsExtensionContributor implements CDIClassContributor { - @Override - public Collection> getBeanClasses() { - return Collections.emptySet(); - } - @Override public Collection getExtensions() { if(LibraryUtil.isLibraryActive(LibraryUtil.LIBRARY_MICROPROFILE)) { - if(true || !"false".equals(LibraryUtil.getApplicationProperty(MetricsResourceContributor.PROP_ENABLED, "true"))) { //$NON-NLS-1$ //$NON-NLS-2$ - return Collections.singleton(new LegacyMetricsExtension()); - } else { - return Collections.emptySet(); - } + // Include the extension even when the endpoint is disabled, as Fault Tolerance uses it + return Collections.singleton(new LegacyMetricsExtension()); } else { return Collections.emptySet(); } } - } From 8e0948b80e5c66a63e7b166c2148cfe9bc1ccb9e Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Mon, 19 Aug 2024 10:06:40 -0400 Subject: [PATCH 12/25] Bump SmallRye Fault Tolerance version (Issue #547) --- osgi-deps/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osgi-deps/pom.xml b/osgi-deps/pom.xml index 5f9f6c36..6d6fb473 100644 --- a/osgi-deps/pom.xml +++ b/osgi-deps/pom.xml @@ -784,16 +784,16 @@ - io.smallrye:smallrye-fault-tolerance:6.2.6 + io.smallrye:smallrye-fault-tolerance:6.4.0 true true org.openntf.io.smallrye.fault-tolerance - 6.2.6.${osgi.qualifier} + 6.4.0.${osgi.qualifier} org.jboss.weld.* - *;version="6.2.6" + *;version="6.4.0" From 01daf5be69bf21ca76574dbc0dbc1c21b34fe164 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Tue, 3 Sep 2024 11:14:33 -0400 Subject: [PATCH 13/25] Add Provide-Capability to fool SLF4J (Issue #552) --- .../META-INF/MANIFEST.MF | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/META-INF/MANIFEST.MF index 3acf9389..70f15f5a 100755 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/META-INF/MANIFEST.MF @@ -13,3 +13,6 @@ Import-Package: com.ibm.designer.runtime.domino.adapter, org.osgi.framework;version="1.8.0" Bundle-ActivationPolicy: lazy Bundle-Activator: org.glassfish.hk2.osgiresourcelocator.Activator +Provide-Capability: osgi.extender;osgi.extender="osgi.serviceloader.re + gistrar";version:Version="1.0",osgi.extender;osgi.extender="osgi.serv + iceloader.processor";version:Version="1.0" From ba75b31bd544b44d71bbe71a0cf0eedec4411b04 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Tue, 3 Sep 2024 12:06:58 -0400 Subject: [PATCH 14/25] Remove unnecessary magic string use in LibraryUtil --- .../src/org/openntf/xsp/jakartaee/util/LibraryUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java index 9c065205..923c253b 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java @@ -487,8 +487,9 @@ public static String toClassName(String resourceName) { return null; } + // Remove .class suffix and convert slashes to dots return resourceName - .substring(0, resourceName.length()-".class".length()) //$NON-NLS-1$ + .substring(0, resourceName.length()-6) .replace('/', '.'); } From a07a71efb6425b60c9a20a67c161a5795ad95473 Mon Sep 17 00:00:00 2001 From: monstermichl Date: Wed, 4 Sep 2024 12:13:14 +0200 Subject: [PATCH 15/25] Make sure an array is passed to DQL.item.contains --- .../driver/impl/QueryConverter.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java index 6951b352..b06ce8dc 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java @@ -20,7 +20,9 @@ import java.time.temporal.Temporal; import java.util.EnumSet; import java.util.List; +import java.util.ArrayList; import java.util.Set; +import java.lang.Iterable; import org.eclipse.jnosql.communication.Condition; import org.eclipse.jnosql.communication.TypeReference; @@ -148,8 +150,23 @@ public static DQLTerm getCondition(CriteriaCondition condition) { case IN: if(value instanceof Number) { throw new IllegalArgumentException("Unable to perform IN query on a number"); - } else { - return DQL.item(name).contains(value == null ? "" : value.toString()); //$NON-NLS-1$ + } else { + List valueHelper = new ArrayList<>(); + + // Make sure value is valid. + if (value == null) { + value = ""; + } else if (value.getClass().isArray()) { + value = Arrays.asList(value); + } + + // If value is an Iterable, convert all entries to String. + if (value instanceof Iterable) { + ((Iterable)value).forEach(item -> valueHelper.add(item.toString())); + } else { + valueHelper.add(value.toString()); + } + return DQL.item(name).contains(valueHelper.toArray(new String[valueHelper.size()])); //$NON-NLS-1$ } case AND: { List conditions = document.get(new TypeReference>() {}); From 29fb90125dd0a1f931b39a7a54dee1a2eca82593 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 5 Sep 2024 10:18:20 -0400 Subject: [PATCH 16/25] Start of temp dir code (Issue #554) --- .../xsp/jakartaee/JakartaActivator.java | 11 ++++++++ .../xsp/jakartaee/util/LibraryUtil.java | 27 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/JakartaActivator.java b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/JakartaActivator.java index d67d23d6..0cb1558f 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/JakartaActivator.java +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/JakartaActivator.java @@ -37,6 +37,12 @@ import jakarta.mail.Multipart; public class JakartaActivator implements BundleActivator { + /** + * notes.ini property that can be set to specify a temp directory. + * @since 3.1.0 + */ + public static final String PROP_OVERRIDETEMPDIR = "JakartaTempDir"; //$NON-NLS-1$ + private final List> regs = new ArrayList<>(); @SuppressWarnings("deprecation") @@ -67,6 +73,11 @@ public void start(BundleContext context) throws Exception { // Allow UTF-8-encoded filenames in MimeMultipart // https://github.com/OpenNTF/org.openntf.xsp.jakartaee/issues/501 LibraryUtil.setSystemProperty("mail.mime.allowutf8", "true"); //$NON-NLS-1$ //$NON-NLS-2$ + + + // Look for a custom temporary directory path + // https://github.com/OpenNTF/org.openntf.xsp.jakartaee/issues/554 + } @Override diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java index 923c253b..6d940f48 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java @@ -112,6 +112,13 @@ public enum LibraryUtil { */ public static final String PROP_XSPPROPS = LibraryUtil.class.getName() + "_xspprops"; //$NON-NLS-1$ + /** + * Optional setting for a directory to be returned by {@link #getTempDirectory()} instead + * of the system default. + * @since 3.1.0 + */ + private static Path OVERRIDE_TEMP_DIR; + /** * Attempts to determine whether the given XPages Library is active for the * current application. @@ -454,11 +461,18 @@ public static Optional getBundle(String symbolicName) { * equivalent to System.getProperty("java.io.tmpdir"). On * Linux, however, since this seems to return the data directory in some * cases, it uses /tmp. + * + *

This default can be overridden with {@link #setTempDirectory(Path)}.

* * @return an appropriate temp directory for the system * @since 2.4.0 */ public static Path getTempDirectory() { + Path override = OVERRIDE_TEMP_DIR; + if(override != null) { + return override; + } + String osName = getSystemProperty("os.name"); //$NON-NLS-1$ if (osName.startsWith("Linux") || osName.startsWith("LINUX")) { //$NON-NLS-1$ //$NON-NLS-2$ return Paths.get("/tmp"); //$NON-NLS-1$ @@ -468,6 +482,19 @@ public static Path getTempDirectory() { } } + /** + * Sets the directory to be used for temp files, instead of the system default. + * + *

This path must be on the primary local filesystem.

+ * + * @param dir a local-filesystem path to use, or {@code null} to un-set an + * existing value + * @since 3.1.0 + */ + public static void setTempDirectory(Path dir) { + OVERRIDE_TEMP_DIR = dir; + } + /** * Converts an in-bundle resource name to a class name. * From 4f7071c5582b0073a799464c6b12392f829ab861 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 5 Sep 2024 10:56:28 -0400 Subject: [PATCH 17/25] Swap order for form name in DQL queries (Issue #556) --- .../jakarta/nosql/communication/driver/impl/QueryConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java index 6951b352..5b3d664c 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java @@ -212,7 +212,7 @@ private static DQLTerm applyFormName(DQLTerm condition, String formName) { if(condition == null) { return DQL.item(DominoConstants.FIELD_NAME).isEqualTo(formName); } else { - return DQL.and(condition, DQL.item(DominoConstants.FIELD_NAME).isEqualTo(formName)); + return DQL.and(DQL.item(DominoConstants.FIELD_NAME).isEqualTo(formName), condition); } } } From a7386e46d9452219dbc8d380a3ec61b736308a24 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 5 Sep 2024 12:31:18 -0400 Subject: [PATCH 18/25] Add test cases for fixed query IN support --- .../driver/impl/QueryConverter.java | 5 +- .../META-INF/MANIFEST.MF | 6 +- .../odp/Code/Java/rest/NoSQLExampleDocs.java | 45 +++++++ .../nsf/nosql/TestNoSQLExampleDocs.java | 115 ++++++++++++++++++ 4 files changed, 167 insertions(+), 4 deletions(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java index b06ce8dc..7b78b02b 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/src/org/openntf/xsp/jakarta/nosql/communication/driver/impl/QueryConverter.java @@ -21,6 +21,7 @@ import java.util.EnumSet; import java.util.List; import java.util.ArrayList; +import java.util.Arrays; import java.util.Set; import java.lang.Iterable; @@ -155,7 +156,7 @@ public static DQLTerm getCondition(CriteriaCondition condition) { // Make sure value is valid. if (value == null) { - value = ""; + value = ""; //$NON-NLS-1$ } else if (value.getClass().isArray()) { value = Arrays.asList(value); } @@ -166,7 +167,7 @@ public static DQLTerm getCondition(CriteriaCondition condition) { } else { valueHelper.add(value.toString()); } - return DQL.item(name).contains(valueHelper.toArray(new String[valueHelper.size()])); //$NON-NLS-1$ + return DQL.item(name).contains(valueHelper.toArray(new String[valueHelper.size()])); } case AND: { List conditions = document.get(new TypeReference>() {}); diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/META-INF/MANIFEST.MF index d7b83cce..ad7606f3 100755 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/META-INF/MANIFEST.MF @@ -13,10 +13,12 @@ Require-Bundle: com.ibm.designer.lib.jsf;bundle-version="9.0.0", org.openntf.org.eclipse.jnosql.mapping.semistructured;bundle-version="1.1.0", org.openntf.org.eclipse.jnosql.mapping.validation;bundle-version="1.1.0", org.openntf.org.eclipse.jnosql.communication.core;bundle-version="1.0.0";visibility:=reexport, - org.openntf.org.eclipse.jnosql.communication.semistructured;bundle-version="1.1.1", + org.openntf.org.eclipse.jnosql.communication.semistructured;bundle-version="1.1.1";visibility:=reexport, org.openntf.xsp.jakarta.nosql.driver;bundle-version="3.0.0";visibility:=reexport, org.openntf.xsp.jakarta.nosql.driver.lsxbe;bundle-version="3.0.0";visibility:=reexport, - org.openntf.org.eclipse.jnosql.mapping.reflection;bundle-version="1.0.2" + org.openntf.org.eclipse.jnosql.mapping.semistructured;bundle-version="1.1.1";visibility:=reexport, + org.openntf.org.eclipse.jnosql.mapping.document;bundle-version="1.1.0";visibility:=reexport, + org.openntf.org.eclipse.jnosql.mapping.reflection;bundle-version="1.1.0" Import-Package: com.ibm.designer.runtime.domino.adapter, com.ibm.domino.xsp.module.nsf, com.ibm.xsp.application, diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExampleDocs.java b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExampleDocs.java index 23d21e6d..6bca90b5 100644 --- a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExampleDocs.java +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExampleDocs.java @@ -21,8 +21,12 @@ import java.util.Map; import java.util.stream.Collectors; +import org.openntf.xsp.jakarta.nosql.mapping.extension.DominoTemplate; + import bean.TransactionBean; import jakarta.inject.Inject; +import jakarta.inject.Named; +import jakarta.nosql.Template; import jakarta.transaction.HeuristicMixedException; import jakarta.transaction.HeuristicRollbackException; import jakarta.transaction.NotSupportedException; @@ -40,6 +44,9 @@ import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; +import lotus.domino.Database; +import lotus.domino.NotesException; +import lotus.domino.Session; import model.ExampleDoc; import model.ExampleDocRepository; import model.Person; @@ -59,6 +66,16 @@ public class NoSQLExampleDocs { @Inject private TransactionBean transactionBean; + @Inject + private DominoTemplate template; + + @Inject + @Named("dominoSessionAsSigner") + private Session sessionAsSigner; + + @Inject + private Database database; + @GET @Produces(MediaType.APPLICATION_JSON) public List get() { @@ -204,4 +221,32 @@ public Map createExampleDocDontRollback() throws NotSupportedExc transaction.commit(); return Collections.singletonMap("created", true); } + + /** + * Used to test the use of the DQL "contains" operation with a list + * + * @param titles the titles to include + * @return the matching documents + */ + @Path("exampleDocsInTitle") + @GET + @Produces(MediaType.APPLICATION_JSON) + public List getTitles(@QueryParam("title") List titles) { + return template.select(ExampleDoc.class) + .where("title").in(titles) //$NON-NLS-1$ + .result(); + } + + /** + * Utility method to make sure that the FT index is updated for use with + * DQL contains + * + * @throws NotesException if there is a problem updating the FT index + */ + @Path("updateExampleDocFtIndex") + @POST + public void updateExampleDocFtIndex() throws NotesException { + Database databaseAsSigner = sessionAsSigner.getDatabase(database.getServer(), database.getFilePath()); + databaseAsSigner.updateFTIndex(true); + } } diff --git a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLExampleDocs.java b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLExampleDocs.java index 642e8cd1..3033e41c 100644 --- a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLExampleDocs.java +++ b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLExampleDocs.java @@ -1071,4 +1071,119 @@ public void testJsonbTransientField() { } } + + @Test + public void testExampleDocInCategories() { + Client client = getAnonymousClient(); + + String prefix13 = "fooddddd"; + String title1 = prefix13 + System.currentTimeMillis(); + String title2 = "bar" + System.currentTimeMillis(); + String title3 = prefix13 + System.nanoTime(); + + // Create two new docs + final String unid1; + { + MultivaluedMap payload = new MultivaluedHashMap<>(); + payload.putSingle("title", title1); + + WebTarget postTarget = client.target(getRestUrl(null, TestDatabase.MAIN) + "/exampleDocs"); + Response response = postTarget.request().post(Entity.form(payload)); + checkResponse(200, response); + + String json = response.readEntity(String.class); + JsonObject jsonObject = Json.createReader(new StringReader(json)).readObject(); + unid1 = jsonObject.getString("unid"); + assertNotNull(unid1); + assertFalse(unid1.isEmpty()); + } + final String unid2; + { + MultivaluedMap payload = new MultivaluedHashMap<>(); + payload.putSingle("title", title2); + + WebTarget postTarget = client.target(getRestUrl(null, TestDatabase.MAIN) + "/exampleDocs"); + Response response = postTarget.request().post(Entity.form(payload)); + checkResponse(200, response); + + String json = response.readEntity(String.class); + JsonObject jsonObject = Json.createReader(new StringReader(json)).readObject(); + unid2 = jsonObject.getString("unid"); + assertNotNull(unid2); + assertFalse(unid2.isEmpty()); + } + final String unid3; + { + MultivaluedMap payload = new MultivaluedHashMap<>(); + payload.putSingle("title", title3); + + WebTarget postTarget = client.target(getRestUrl(null, TestDatabase.MAIN) + "/exampleDocs"); + Response response = postTarget.request().post(Entity.form(payload)); + checkResponse(200, response); + + String json = response.readEntity(String.class); + JsonObject jsonObject = Json.createReader(new StringReader(json)).readObject(); + unid3 = jsonObject.getString("unid"); + assertNotNull(unid3); + assertFalse(unid3.isEmpty()); + } + + // Update the FT index, to make sure + { + WebTarget target = client.target(getRestUrl(null, TestDatabase.MAIN) + "/exampleDocs/updateExampleDocFtIndex"); + Response response = target.request().post(Entity.text("")); + checkResponse(204, response); + } + + // Fetch the first two titles, which should include both + { + WebTarget target = client.target(getRestUrl(null, TestDatabase.MAIN) + "/exampleDocs/exampleDocsInTitle"); + Response response = target.queryParam("title", title1, title2).request().get(); + checkResponse(200, response); + + String json = response.readEntity(String.class); + try { + JsonArray entities = Json.createReader(new StringReader(json)).readArray(); + assertEquals(2, entities.size()); + assertTrue(entities.stream().map(JsonObject.class::cast).anyMatch(obj -> unid1.equals(obj.getString("unid")))); + assertTrue(entities.stream().map(JsonObject.class::cast).anyMatch(obj -> unid2.equals(obj.getString("unid")))); + } catch(Exception e) { + fail("Encountered exception with JSON " + json, e); + } + } + + // Fetch the second two categories, which should also include both + { + WebTarget target = client.target(getRestUrl(null, TestDatabase.MAIN) + "/exampleDocs/exampleDocsInTitle"); + Response response = target.queryParam("title", title2, title3).request().get(); + checkResponse(200, response); + + String json = response.readEntity(String.class); + try { + JsonArray entities = Json.createReader(new StringReader(json)).readArray(); + assertEquals(2, entities.size()); + assertTrue(entities.stream().map(JsonObject.class::cast).anyMatch(obj -> unid2.equals(obj.getString("unid")))); + assertTrue(entities.stream().map(JsonObject.class::cast).anyMatch(obj -> unid3.equals(obj.getString("unid")))); + } catch(Exception e) { + fail("Encountered exception with JSON " + json, e); + } + } + + // Fetch the prefix + { + WebTarget target = client.target(getRestUrl(null, TestDatabase.MAIN) + "/exampleDocs/exampleDocsInTitle"); + Response response = target.queryParam("title", prefix13 + "*").request().get(); + checkResponse(200, response); + + String json = response.readEntity(String.class); + try { + JsonArray entities = Json.createReader(new StringReader(json)).readArray(); + assertEquals(2, entities.size()); + assertTrue(entities.stream().map(JsonObject.class::cast).anyMatch(obj -> unid1.equals(obj.getString("unid")))); + assertTrue(entities.stream().map(JsonObject.class::cast).anyMatch(obj -> unid3.equals(obj.getString("unid")))); + } catch(Exception e) { + fail("Encountered exception with JSON " + json, e); + } + } + } } From ad07413d555705286feaeb78bbf0158441a0226b Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 5 Sep 2024 12:42:56 -0400 Subject: [PATCH 19/25] Rename named-doc test methods to be more generic --- .../xsp/jakartaee/nsf/nosql/TestNoSQLNamedAndProfileDocs.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLNamedAndProfileDocs.java b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLNamedAndProfileDocs.java index 1991d02a..031ad0cf 100644 --- a/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLNamedAndProfileDocs.java +++ b/eclipse/tests/it-xsp-jakartaee/src/test/java/it/org/openntf/xsp/jakartaee/nsf/nosql/TestNoSQLNamedAndProfileDocs.java @@ -53,7 +53,7 @@ public class TestNoSQLNamedAndProfileDocs extends AbstractWebClientTest { PART_NAMED + "," + NAME_NAMED + "," + USERNAME_NAMED + "," + USERNAME2_NAMED + "," + FIELD_NAMED, PART_PROFILE + "," + NAME_PROFILE + "," + USERNAME_PROFILE + "," + USERNAME2_PROFILE + "," + FIELD_PROFILE }) - public void testNamedDoc(String part, String name, String username, String username2, String field) throws UnsupportedEncodingException { + public void testDoc(String part, String name, String username, String username2, String field) throws UnsupportedEncodingException { Client client = getAnonymousClient(); WebTarget target = client.target(getRestUrl(null, TestDatabase.MAIN) + "/" + part + "/" + name); @@ -145,7 +145,7 @@ public void testNamedDoc(String part, String name, String username, String usern PART_NAMED + "," + NAME_NAMED + "," + USERNAME_NAMED + "," + USERNAME2_NAMED + "," + FIELD_NAMED, PART_PROFILE + "," + NAME_PROFILE + "," + USERNAME_PROFILE + "," + USERNAME2_PROFILE + "," + FIELD_PROFILE }) - public void testNamedQualifiedDoc(String part, String name, String username, String username2, String field) throws UnsupportedEncodingException { + public void testQualifiedDoc(String part, String name, String username, String username2, String field) throws UnsupportedEncodingException { Client client = getAnonymousClient(); WebTarget target = client.target(getRestUrl(null, TestDatabase.MAIN) + "/" + part + "/" + name + "/" + URLEncoder.encode(username, "UTF-8")); From 901757fa242c5ca8c2afed8dd6f76f03a716ccbd Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 5 Sep 2024 12:45:26 -0400 Subject: [PATCH 20/25] Remove unused import --- .../odp/Code/Java/rest/NoSQLExampleDocs.java | 1 - 1 file changed, 1 deletion(-) diff --git a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExampleDocs.java b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExampleDocs.java index 6bca90b5..fed677f1 100644 --- a/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExampleDocs.java +++ b/eclipse/nsfs/nsf-jakartaee-example/odp/Code/Java/rest/NoSQLExampleDocs.java @@ -26,7 +26,6 @@ import bean.TransactionBean; import jakarta.inject.Inject; import jakarta.inject.Named; -import jakarta.nosql.Template; import jakarta.transaction.HeuristicMixedException; import jakarta.transaction.HeuristicRollbackException; import jakarta.transaction.NotSupportedException; From 2ababb50a30d0d983e2e1a8b667a0b2b092e1594 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 5 Sep 2024 14:11:03 -0400 Subject: [PATCH 21/25] Add Jakarta_TempDir and Jakarta_QRPDir notes.ino parameters (Issue #554) --- README.md | 6 +- .../META-INF/MANIFEST.MF | 3 +- ...efaultDominoDocumentCollectionManager.java | 4 +- .../driver/lsxbe/util/DominoNoSQLUtil.java | 56 +++++++++++++++++++ .../META-INF/MANIFEST.MF | 5 +- .../xsp/jakarta/nosql/NoSQLActivator.java | 30 ++++++++++ .../META-INF/MANIFEST.MF | 1 + .../xsp/jakartaee/JakartaActivator.java | 39 ++++++++----- .../xsp/jakartaee/util/LibraryUtil.java | 13 +++++ 9 files changed, 139 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 49ab1142..a4fb033f 100644 --- a/README.md +++ b/README.md @@ -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: @@ -818,6 +820,8 @@ 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. + ### Server Faces [Jakarta Server Faces](https://jakarta.ee/specifications/faces/) is the Jakarta EE form of JSF, the spec XPages forked off from. @@ -1170,7 +1174,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. diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/META-INF/MANIFEST.MF index a4e641c3..0add2f76 100755 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/META-INF/MANIFEST.MF @@ -33,4 +33,5 @@ Import-Package: com.ibm.commons.util, org.openntf.xsp.jakarta.nosql.mapping.extension;version="2.6.0", org.openntf.xsp.jakarta.nosql.mapping.extension.impl;version="2.8.0" Export-Package: org.openntf.xsp.jakarta.nosql.communication.driver.lsxbe;version="3.1.0", - org.openntf.xsp.jakarta.nosql.communication.driver.lsxbe.impl;version="3.1.0" + org.openntf.xsp.jakarta.nosql.communication.driver.lsxbe.impl;version="3.1.0", + org.openntf.xsp.jakarta.nosql.communication.driver.lsxbe.util diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/impl/DefaultDominoDocumentCollectionManager.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/impl/DefaultDominoDocumentCollectionManager.java index e374c8c4..c2140f6b 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/impl/DefaultDominoDocumentCollectionManager.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/impl/DefaultDominoDocumentCollectionManager.java @@ -830,8 +830,8 @@ private Database getQrpDatabase(Session session, Database database) throws Notes try { String fileName = AbstractEntityConverter.md5(server + filePath) + ".nsf"; //$NON-NLS-1$ - Path tempDir = DominoNoSQLUtil.getTempDirectory(); - Path dest = tempDir.resolve(getClass().getPackage().getName()); + Path dest = DominoNoSQLUtil.getQrpDirectory() + .orElseGet(() -> DominoNoSQLUtil.getTempDirectory().resolve(getClass().getPackageName())); Files.createDirectories(dest); Path dbPath = dest.resolve(fileName); diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/util/DominoNoSQLUtil.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/util/DominoNoSQLUtil.java index ab6c1767..df0eb236 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/util/DominoNoSQLUtil.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/util/DominoNoSQLUtil.java @@ -57,6 +57,20 @@ */ public enum DominoNoSQLUtil { ; + + /** + * Optional setting for a directory to be returned by {@link #getTempDirectory()} instead + * of the system default. + * @since 3.1.0 + */ + private static Path OVERRIDE_TEMP_DIR; + + /** + * Optional setting for a directory to be returned by {@link #getTQrpDirectory()} instead + * of the system default. + * @since 3.1.0 + */ + private static Path OVERRIDE_QRP_DIR; /** * Returns an appropriate temp directory for the system. On Windows, this is @@ -67,6 +81,11 @@ public enum DominoNoSQLUtil { * @return an appropriate temp directory for the system */ public static Path getTempDirectory() { + Path override = OVERRIDE_TEMP_DIR; + if(override != null) { + return override; + } + String osName = AccessController.doPrivileged((PrivilegedAction)() -> System.getProperty("os.name")); //$NON-NLS-1$ if (osName.startsWith("Linux") || osName.startsWith("LINUX")) { //$NON-NLS-1$ //$NON-NLS-2$ return Paths.get("/tmp"); //$NON-NLS-1$ @@ -263,4 +282,41 @@ public static boolean isValid(lotus.domino.Document doc) { return false; } } + + /** + * Sets the directory to be used for temp files, instead of the system default. + * + *

This path must be on the primary local filesystem.

+ * + * @param dir a local-filesystem path to use, or {@code null} to un-set an + * existing value + * @since 3.1.0 + */ + public static void setTempDirectory(Path dir) { + OVERRIDE_TEMP_DIR = dir; + } + + /** + * Sets the directory to be used for QRP databases, instead of the system default. + * + *

This path must be on the primary local filesystem.

+ * + * @param dir a local-filesystem path to use, or {@code null} to un-set an + * existing value + * @since 3.1.0 + */ + public static void setQrpDirectory(Path dir) { + OVERRIDE_QRP_DIR = dir; + } + + /** + * Retrieves the base directory to be used for QRP databases + * + * @return a path to use for QRP databases, or an empty Optional if this + * was not set + * @since 3.1.0 + */ + public static Optional getQrpDirectory() { + return Optional.ofNullable(OVERRIDE_QRP_DIR); + } } diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/META-INF/MANIFEST.MF index ad7606f3..800083ea 100755 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/META-INF/MANIFEST.MF @@ -19,7 +19,10 @@ Require-Bundle: com.ibm.designer.lib.jsf;bundle-version="9.0.0", org.openntf.org.eclipse.jnosql.mapping.semistructured;bundle-version="1.1.1";visibility:=reexport, org.openntf.org.eclipse.jnosql.mapping.document;bundle-version="1.1.0";visibility:=reexport, org.openntf.org.eclipse.jnosql.mapping.reflection;bundle-version="1.1.0" -Import-Package: com.ibm.designer.runtime.domino.adapter, +Import-Package: com.ibm.commons.util, + com.ibm.designer.domino.napi, + com.ibm.designer.runtime.domino.adapter, + com.ibm.domino.napi.c, com.ibm.domino.xsp.module.nsf, com.ibm.xsp.application, com.ibm.xsp.library, diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/NoSQLActivator.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/NoSQLActivator.java index f7665958..e481ddf1 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/NoSQLActivator.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/src/org/openntf/xsp/jakarta/nosql/NoSQLActivator.java @@ -15,10 +15,17 @@ */ package org.openntf.xsp.jakarta.nosql; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import com.ibm.commons.util.StringUtil; +import com.ibm.domino.napi.c.Os; + +import org.openntf.xsp.jakarta.nosql.communication.driver.lsxbe.util.DominoNoSQLUtil; import org.openntf.xsp.jakarta.nosql.weaving.NoSQLWeavingHook; +import org.openntf.xsp.jakartaee.util.LibraryUtil; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; @@ -29,11 +36,34 @@ * @since 2.3.0 */ public class NoSQLActivator implements BundleActivator { + /** + * notes.ini property that can be set to specify a temp directory. + * @since 3.1.0 + */ + public static final String PROP_OVERRIDEQRPDIR = "Jakarta_QRPDir"; //$NON-NLS-1$ + private final List> regs = new ArrayList<>(); @Override public void start(BundleContext context) throws Exception { regs.add(context.registerService(WeavingHook.class.getName(), new NoSQLWeavingHook(), null)); + + if(!LibraryUtil.isTycho()) { + // Check for a notes.ini property overriding the scratch directory + + String iniTempDir = Os.OSGetEnvironmentString(PROP_OVERRIDEQRPDIR); + if(StringUtil.isNotEmpty(iniTempDir)) { + Path tempDir = Paths.get(iniTempDir); + if(!tempDir.isAbsolute()) { + Path dataDir = Paths.get(Os.OSGetDataDirectory()); + tempDir = dataDir.resolve(iniTempDir); + } + DominoNoSQLUtil.setQrpDirectory(tempDir); + } + + // May have been set to a custom value + DominoNoSQLUtil.setTempDirectory(LibraryUtil.getTempDirectory()); + } } @Override diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/META-INF/MANIFEST.MF index c0cc6dae..363ec42d 100755 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/META-INF/MANIFEST.MF @@ -33,6 +33,7 @@ Import-Package: com.ibm.commons.extension, com.ibm.designer.runtime.domino.adapter.servlet, com.ibm.designer.runtime.domino.adapter.util, com.ibm.designer.runtime.domino.bootstrap.adapter, + com.ibm.domino.napi.c, com.ibm.domino.osgi.core.context;resolution:=optional, com.ibm.domino.xsp.adapter.osgi;resolution:=optional, com.ibm.domino.xsp.bridge.http.servlet;resolution:=optional, diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/JakartaActivator.java b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/JakartaActivator.java index 0cb1558f..18127e29 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/JakartaActivator.java +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/JakartaActivator.java @@ -17,12 +17,17 @@ import java.io.IOException; import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; +import com.ibm.commons.util.StringUtil; +import com.ibm.domino.napi.c.Os; + import org.openntf.xsp.jakartaee.util.LibraryUtil; import org.openntf.xsp.jakartaee.weaving.MailWeavingHook; import org.openntf.xsp.jakartaee.weaving.UtilWeavingHook; @@ -41,7 +46,7 @@ public class JakartaActivator implements BundleActivator { * notes.ini property that can be set to specify a temp directory. * @since 3.1.0 */ - public static final String PROP_OVERRIDETEMPDIR = "JakartaTempDir"; //$NON-NLS-1$ + public static final String PROP_OVERRIDETEMPDIR = "Jakarta_TempDir"; //$NON-NLS-1$ private final List> regs = new ArrayList<>(); @@ -50,11 +55,10 @@ public class JakartaActivator implements BundleActivator { public void start(BundleContext context) throws Exception { regs.add(context.registerService(WeavingHook.class.getName(), new UtilWeavingHook(), null)); regs.add(context.registerService(WeavingHook.class.getName(), new MailWeavingHook(), null)); - - AccessController.doPrivileged((PrivilegedExceptionAction)() -> { - // The below tries to load jnotes when run in Tycho Surefire - String application = String.valueOf(System.getProperty("eclipse.application")); //$NON-NLS-1$ - if(!application.contains("org.eclipse.tycho")) { //$NON-NLS-1$ + + // The below tries to load jnotes when run in Tycho Surefire + if(!LibraryUtil.isTycho()) { + AccessController.doPrivileged((PrivilegedExceptionAction)() -> { ClassLoader tccl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(new MailcapAvoidanceClassLoader(tccl)); try { @@ -67,17 +71,26 @@ public void start(BundleContext context) throws Exception { } finally { Thread.currentThread().setContextClassLoader(tccl); } - } - return null; - }); + + // Look for a custom temporary directory path + // https://github.com/OpenNTF/org.openntf.xsp.jakartaee/issues/554 + String iniTempDir = Os.OSGetEnvironmentString(PROP_OVERRIDETEMPDIR); + if(StringUtil.isNotEmpty(iniTempDir)) { + Path tempDir = Paths.get(iniTempDir); + if(!tempDir.isAbsolute()) { + Path dataDir = Paths.get(Os.OSGetDataDirectory()); + tempDir = dataDir.resolve(iniTempDir); + } + LibraryUtil.setTempDirectory(tempDir); + } + return null; + }); + } + // Allow UTF-8-encoded filenames in MimeMultipart // https://github.com/OpenNTF/org.openntf.xsp.jakartaee/issues/501 LibraryUtil.setSystemProperty("mail.mime.allowutf8", "true"); //$NON-NLS-1$ //$NON-NLS-2$ - - // Look for a custom temporary directory path - // https://github.com/OpenNTF/org.openntf.xsp.jakartaee/issues/554 - } @Override diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java index 6d940f48..aadf982e 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/src/org/openntf/xsp/jakartaee/util/LibraryUtil.java @@ -548,4 +548,17 @@ public static void setSystemProperty(String propName, String value) { return null; }); } + + /** + * Attempts to determine whether the running environment is Tycho - i.e. + * during a compile-time test suite. + * + * @return {@code true} if this seems to be running in Tycho; {@code false} + * otherwise + * @since 3.1.0 + */ + public static boolean isTycho() { + String application = String.valueOf(getSystemProperty("eclipse.application")); //$NON-NLS-1$ + return application.contains("org.eclipse.tycho"); //$NON-NLS-1$ + } } From f4fce1e48bc00be0534e1d03f8415d3311316b7b Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 5 Sep 2024 14:30:13 -0400 Subject: [PATCH 22/25] Add parameter for JSP DTD scratch directory (Issue #559) --- README.md | 2 ++ ...efaultDominoDocumentCollectionManager.java | 2 +- .../META-INF/MANIFEST.MF | 1 + .../xsp/jakarta/pages/EarlyInitFactory.java | 31 +++++++++++++++++-- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a4fb033f..d8e52028 100644 --- a/README.md +++ b/README.md @@ -822,6 +822,8 @@ As demonstrated above, this will resolve in-NSF tags via the NSF's classpath and 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. diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/impl/DefaultDominoDocumentCollectionManager.java b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/impl/DefaultDominoDocumentCollectionManager.java index c2140f6b..82436974 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/impl/DefaultDominoDocumentCollectionManager.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/src/org/openntf/xsp/jakarta/nosql/communication/driver/lsxbe/impl/DefaultDominoDocumentCollectionManager.java @@ -271,7 +271,7 @@ public Stream select(SelectQuery query) { if(view != null) { result = entityConverter.convertQRPViewDocuments(database, view, mapping); } else { - DominoQuery dominoQuery = database.createDominoQuery(); + DominoQuery dominoQuery = database.createDominoQuery(); QueryResultsProcessor qrp = qrpDatabase.createQueryResultsProcessor(); try { qrp.addDominoQuery(dominoQuery, dqlQuery, null); diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.pages/META-INF/MANIFEST.MF b/eclipse/bundles/org.openntf.xsp.jakarta.pages/META-INF/MANIFEST.MF index a6340cf1..99557ad3 100755 --- a/eclipse/bundles/org.openntf.xsp.jakarta.pages/META-INF/MANIFEST.MF +++ b/eclipse/bundles/org.openntf.xsp.jakarta.pages/META-INF/MANIFEST.MF @@ -18,6 +18,7 @@ Require-Bundle: jakarta.servlet-api;bundle-version="5.0.0";visibility:=reexport, com.ibm.xsp.designer Import-Package: com.ibm.commons.util, com.ibm.designer.runtime.domino.adapter, + com.ibm.domino.napi, com.ibm.domino.napi.c, com.ibm.domino.xsp.module.nsf, com.ibm.xsp.extlib.util, diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/EarlyInitFactory.java b/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/EarlyInitFactory.java index b8f69c78..92e4c164 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/EarlyInitFactory.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/EarlyInitFactory.java @@ -25,15 +25,19 @@ import java.nio.file.StandardCopyOption; import java.util.Collections; import java.util.Enumeration; +import java.util.logging.Level; +import java.util.logging.Logger; import org.eclipse.core.runtime.FileLocator; import org.openntf.xsp.jakartaee.util.LibraryUtil; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; +import com.ibm.commons.util.StringUtil; import com.ibm.designer.runtime.domino.adapter.HttpService; import com.ibm.designer.runtime.domino.adapter.IServiceFactory; import com.ibm.designer.runtime.domino.adapter.LCDEnvironment; +import com.ibm.domino.napi.NException; import com.ibm.domino.napi.c.Os; import com.ibm.domino.xsp.module.nsf.NSFService; @@ -47,7 +51,13 @@ * @since 2.1.0 */ public class EarlyInitFactory implements IServiceFactory { - public static boolean debug = true; + /** + * notes.ini property that can be set to specify a DTD output directory. + * @since 3.1.0 + */ + public static final String PROP_OVERRIDEDTDDIR = "Jakarta_DTDDir"; //$NON-NLS-1$ + + private static final Logger log = Logger.getLogger(EarlyInitFactory.class.getPackageName()); @Override public HttpService[] getServices(LCDEnvironment env) { @@ -100,6 +110,7 @@ private void deployServletDtds() throws URISyntaxException, IOException { public static Path getDeployedJstlBundle() throws IOException { Path destDir = getServletDtdPath(); + System.out.println("deploying DTDs to " + destDir); Files.createDirectories(destDir); Bundle jstl = LibraryUtil.getBundle("org.glassfish.web.jakarta.servlet.jsp.jstl").get(); //$NON-NLS-1$ @@ -113,9 +124,25 @@ public static Path getDeployedJstlBundle() throws IOException { } public static Path getServletDtdPath() { + try { + String iniDtdDir = Os.OSGetEnvironmentString(PROP_OVERRIDEDTDDIR); + if(StringUtil.isNotEmpty(iniDtdDir)) { + Path dtdDir = Paths.get(iniDtdDir); + if(!dtdDir.isAbsolute()) { + Path dataDir = Paths.get(Os.OSGetDataDirectory()); + dtdDir = dataDir.resolve(iniDtdDir); + } + return dtdDir; + } + } catch(NException e) { + if(log.isLoggable(Level.WARNING)) { + log.log(Level.WARNING, "Encountered exception trying to read notes.ini", e); + } + } + String data = Os.OSGetDataDirectory(); Path dataDir = Paths.get(data); - return dataDir.resolve("jakarta").resolve("dtd"); //$NON-NLS-1$ //$NON-NLS-2$ + return dataDir.resolve("domino").resolve("jakarta").resolve("dtd"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } From b066db6917e765add1926e611e9589716ea8db9d Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 5 Sep 2024 14:36:59 -0400 Subject: [PATCH 23/25] Remove errant sysout --- .../src/org/openntf/xsp/jakarta/pages/EarlyInitFactory.java | 1 - 1 file changed, 1 deletion(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/EarlyInitFactory.java b/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/EarlyInitFactory.java index 92e4c164..7f18a394 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/EarlyInitFactory.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.pages/src/org/openntf/xsp/jakarta/pages/EarlyInitFactory.java @@ -110,7 +110,6 @@ private void deployServletDtds() throws URISyntaxException, IOException { public static Path getDeployedJstlBundle() throws IOException { Path destDir = getServletDtdPath(); - System.out.println("deploying DTDs to " + destDir); Files.createDirectories(destDir); Bundle jstl = LibraryUtil.getBundle("org.glassfish.web.jakarta.servlet.jsp.jstl").get(); //$NON-NLS-1$ From dd999ecf2e0a7108d828464bc354df1c7ece06c3 Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Thu, 5 Sep 2024 14:37:23 -0400 Subject: [PATCH 24/25] Add null/synchronization guards in NSFFacesServlet#destroy (Issue #537) --- .../jakarta/faces/nsf/NSFFacesServlet.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.faces/src/org/openntf/xsp/jakarta/faces/nsf/NSFFacesServlet.java b/eclipse/bundles/org.openntf.xsp.jakarta.faces/src/org/openntf/xsp/jakarta/faces/nsf/NSFFacesServlet.java index 8edca7e9..16ac657a 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.faces/src/org/openntf/xsp/jakarta/faces/nsf/NSFFacesServlet.java +++ b/eclipse/bundles/org.openntf.xsp.jakarta.faces/src/org/openntf/xsp/jakarta/faces/nsf/NSFFacesServlet.java @@ -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) { @@ -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(); } From 387f9270189a8516423a41bd3c93aa962209fc7b Mon Sep 17 00:00:00 2001 From: Jesse Gallagher Date: Fri, 6 Sep 2024 12:45:23 -0400 Subject: [PATCH 25/25] Set version to 3.1.0 --- eclipse/bundles/org.openntf.xsp.jakarta.cdi.extlib/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.cdi/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.concurrency/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.el/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.faces/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.json/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.mvc/pom.xml | 2 +- .../bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.nosql/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.pages/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.persistence/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.rest.factory/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.rest/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.servlet/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.transaction/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakarta.validation/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakartaee.bridge.jasapi/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakartaee.commons/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakartaee.core.library/pom.xml | 2 +- .../org.openntf.xsp.jakartaee.osgiresourcelocator/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.jakartaee.ui.library/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.microprofile.config/pom.xml | 2 +- .../bundles/org.openntf.xsp.microprofile.faulttolerance/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.microprofile.health/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.microprofile.library/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.microprofile.metrics/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.microprofile.openapi/pom.xml | 2 +- eclipse/bundles/org.openntf.xsp.microprofile.restclient/pom.xml | 2 +- eclipse/features/org.openntf.xsp.jakartaee.feature/pom.xml | 2 +- eclipse/features/org.openntf.xsp.jakartaee.ui.feature/pom.xml | 2 +- eclipse/features/org.openntf.xsp.microprofile.feature/pom.xml | 2 +- eclipse/nsfs/nsf-jakartaee-bundle-example/pom.xml | 2 +- eclipse/nsfs/nsf-jakartaee-bundlebase-example/pom.xml | 2 +- eclipse/nsfs/nsf-jakartaee-example/pom.xml | 2 +- eclipse/nsfs/nsf-jakartaee-jpa-example/pom.xml | 2 +- eclipse/nsfs/nsf-jakartaee-jsonbconfig-example/pom.xml | 2 +- eclipse/nsfs/nsf-jakartaee-primefaces-example/pom.xml | 2 +- eclipse/nsfs/nsf-jakartaee-primefaces-showcase/pom.xml | 2 +- eclipse/pom.xml | 2 +- .../releng/org.openntf.xsp.jakartaee.source.updatesite/pom.xml | 2 +- eclipse/releng/org.openntf.xsp.jakartaee.updatesite/pom.xml | 2 +- eclipse/releng/xsp-jakartaee-dist/pom.xml | 2 +- eclipse/tests/it-xsp-jakartaee/pom.xml | 2 +- eclipse/tests/org.openntf.xsp.jakarta.example.webapp/pom.xml | 2 +- eclipse/tests/org.openntf.xsp.jakarta.json.test/pom.xml | 2 +- eclipse/tests/org.openntf.xsp.jakarta.validation.test/pom.xml | 2 +- eclipse/tests/org.openntf.xsp.jakartaee.test/pom.xml | 2 +- eclipse/tests/org.openntf.xsp.test.beanbundle/pom.xml | 2 +- eclipse/tests/org.openntf.xsp.test.jasapi/pom.xml | 2 +- eclipse/tests/org.openntf.xsp.test.postinstall/pom.xml | 2 +- 51 files changed, 51 insertions(+), 51 deletions(-) diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.cdi.extlib/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.cdi.extlib/pom.xml index dad9c59d..41818066 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.cdi.extlib/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.cdi.extlib/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.cdi.extlib diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.cdi/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.cdi/pom.xml index 3f46e079..55a3c365 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.cdi/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.cdi/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.cdi diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.concurrency/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.concurrency/pom.xml index da889c47..cb4d2b57 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.concurrency/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.concurrency/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.concurrency diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.el/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.el/pom.xml index efdac232..b39a554c 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.el/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.el/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.el diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.faces/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.faces/pom.xml index 967e8ecf..c2dd58d3 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.faces/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.faces/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.faces diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.json/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.json/pom.xml index fe5c8c73..4cf03b58 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.json/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.json/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.json diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.mvc/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.mvc/pom.xml index c37b004f..f5fdc2fc 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.mvc/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.mvc/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.mvc diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/pom.xml index 3494cc92..acfd46a9 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver.lsxbe/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.nosql.driver.lsxbe diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/pom.xml index 729a83f7..3a8e12e2 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql.driver/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.nosql.driver diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/pom.xml index 5b154ebd..6dc14914 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.nosql/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.nosql/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.nosql diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.pages/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.pages/pom.xml index 2c660551..e11a3e7a 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.pages/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.pages/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.pages diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.persistence/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.persistence/pom.xml index 8cebb4d3..cf7a219e 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.persistence/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.persistence/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.persistence diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.rest.factory/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.rest.factory/pom.xml index 038c9394..2ead7417 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.rest.factory/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.rest.factory/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.rest.factory diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.rest/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.rest/pom.xml index 5eb3c43f..cfcdee65 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.rest/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.rest/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.rest diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.servlet/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.servlet/pom.xml index f70a67a0..3a7de320 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.servlet/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.servlet/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.servlet diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.transaction/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.transaction/pom.xml index 5c305d59..5f5708b1 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.transaction/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.transaction/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.transaction diff --git a/eclipse/bundles/org.openntf.xsp.jakarta.validation/pom.xml b/eclipse/bundles/org.openntf.xsp.jakarta.validation/pom.xml index 59182cd3..9eadbea0 100644 --- a/eclipse/bundles/org.openntf.xsp.jakarta.validation/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakarta.validation/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../.. org.openntf.xsp.jakarta.validation diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.bridge.jasapi/pom.xml b/eclipse/bundles/org.openntf.xsp.jakartaee.bridge.jasapi/pom.xml index 6bfc5e82..89b5716f 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.bridge.jasapi/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.bridge.jasapi/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../.. org.openntf.xsp.jakartaee.bridge.jasapi diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/pom.xml b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/pom.xml index a4538221..85add548 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.commons/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.commons/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakartaee.commons diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.core.library/pom.xml b/eclipse/bundles/org.openntf.xsp.jakartaee.core.library/pom.xml index 7ce9a0c3..c0df65a7 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.core.library/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.core.library/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakartaee.core.library diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/pom.xml b/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/pom.xml index a4fa3a39..5b6c912b 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.osgiresourcelocator/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakartaee.osgiresourcelocator diff --git a/eclipse/bundles/org.openntf.xsp.jakartaee.ui.library/pom.xml b/eclipse/bundles/org.openntf.xsp.jakartaee.ui.library/pom.xml index b9050fad..01a49cc3 100644 --- a/eclipse/bundles/org.openntf.xsp.jakartaee.ui.library/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.jakartaee.ui.library/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakartaee.ui.library diff --git a/eclipse/bundles/org.openntf.xsp.microprofile.config/pom.xml b/eclipse/bundles/org.openntf.xsp.microprofile.config/pom.xml index 76ea45ff..211ee089 100644 --- a/eclipse/bundles/org.openntf.xsp.microprofile.config/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.microprofile.config/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.microprofile.config diff --git a/eclipse/bundles/org.openntf.xsp.microprofile.faulttolerance/pom.xml b/eclipse/bundles/org.openntf.xsp.microprofile.faulttolerance/pom.xml index 51875091..30848538 100644 --- a/eclipse/bundles/org.openntf.xsp.microprofile.faulttolerance/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.microprofile.faulttolerance/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.microprofile.faulttolerance diff --git a/eclipse/bundles/org.openntf.xsp.microprofile.health/pom.xml b/eclipse/bundles/org.openntf.xsp.microprofile.health/pom.xml index bf8607b2..04cc80bb 100644 --- a/eclipse/bundles/org.openntf.xsp.microprofile.health/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.microprofile.health/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.microprofile.health diff --git a/eclipse/bundles/org.openntf.xsp.microprofile.library/pom.xml b/eclipse/bundles/org.openntf.xsp.microprofile.library/pom.xml index d958ab9f..600a2a85 100644 --- a/eclipse/bundles/org.openntf.xsp.microprofile.library/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.microprofile.library/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.microprofile.library diff --git a/eclipse/bundles/org.openntf.xsp.microprofile.metrics/pom.xml b/eclipse/bundles/org.openntf.xsp.microprofile.metrics/pom.xml index f8790726..2efea883 100644 --- a/eclipse/bundles/org.openntf.xsp.microprofile.metrics/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.microprofile.metrics/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.microprofile.metrics diff --git a/eclipse/bundles/org.openntf.xsp.microprofile.openapi/pom.xml b/eclipse/bundles/org.openntf.xsp.microprofile.openapi/pom.xml index e35bca2c..0b1958bb 100644 --- a/eclipse/bundles/org.openntf.xsp.microprofile.openapi/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.microprofile.openapi/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.microprofile.openapi diff --git a/eclipse/bundles/org.openntf.xsp.microprofile.restclient/pom.xml b/eclipse/bundles/org.openntf.xsp.microprofile.restclient/pom.xml index 7ee323d9..4276df5a 100644 --- a/eclipse/bundles/org.openntf.xsp.microprofile.restclient/pom.xml +++ b/eclipse/bundles/org.openntf.xsp.microprofile.restclient/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.microprofile.restclient diff --git a/eclipse/features/org.openntf.xsp.jakartaee.feature/pom.xml b/eclipse/features/org.openntf.xsp.jakartaee.feature/pom.xml index 73de2113..0117271f 100644 --- a/eclipse/features/org.openntf.xsp.jakartaee.feature/pom.xml +++ b/eclipse/features/org.openntf.xsp.jakartaee.feature/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakartaee.feature diff --git a/eclipse/features/org.openntf.xsp.jakartaee.ui.feature/pom.xml b/eclipse/features/org.openntf.xsp.jakartaee.ui.feature/pom.xml index 0406639a..0080bb32 100644 --- a/eclipse/features/org.openntf.xsp.jakartaee.ui.feature/pom.xml +++ b/eclipse/features/org.openntf.xsp.jakartaee.ui.feature/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakartaee.ui.feature diff --git a/eclipse/features/org.openntf.xsp.microprofile.feature/pom.xml b/eclipse/features/org.openntf.xsp.microprofile.feature/pom.xml index 318bc051..a063017f 100644 --- a/eclipse/features/org.openntf.xsp.microprofile.feature/pom.xml +++ b/eclipse/features/org.openntf.xsp.microprofile.feature/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.microprofile.feature diff --git a/eclipse/nsfs/nsf-jakartaee-bundle-example/pom.xml b/eclipse/nsfs/nsf-jakartaee-bundle-example/pom.xml index f6286528..9ba4478b 100644 --- a/eclipse/nsfs/nsf-jakartaee-bundle-example/pom.xml +++ b/eclipse/nsfs/nsf-jakartaee-bundle-example/pom.xml @@ -6,7 +6,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml nsf-jakartaee-bundle-example diff --git a/eclipse/nsfs/nsf-jakartaee-bundlebase-example/pom.xml b/eclipse/nsfs/nsf-jakartaee-bundlebase-example/pom.xml index d0347a40..0cbd9c0a 100644 --- a/eclipse/nsfs/nsf-jakartaee-bundlebase-example/pom.xml +++ b/eclipse/nsfs/nsf-jakartaee-bundlebase-example/pom.xml @@ -6,7 +6,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml nsf-jakartaee-bundlebase-example diff --git a/eclipse/nsfs/nsf-jakartaee-example/pom.xml b/eclipse/nsfs/nsf-jakartaee-example/pom.xml index fdb90ec9..0aba939d 100644 --- a/eclipse/nsfs/nsf-jakartaee-example/pom.xml +++ b/eclipse/nsfs/nsf-jakartaee-example/pom.xml @@ -6,7 +6,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml nsf-jakartaee-example diff --git a/eclipse/nsfs/nsf-jakartaee-jpa-example/pom.xml b/eclipse/nsfs/nsf-jakartaee-jpa-example/pom.xml index b35dc1f8..021b29f0 100644 --- a/eclipse/nsfs/nsf-jakartaee-jpa-example/pom.xml +++ b/eclipse/nsfs/nsf-jakartaee-jpa-example/pom.xml @@ -6,7 +6,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml nsf-jakartaee-jpa-example diff --git a/eclipse/nsfs/nsf-jakartaee-jsonbconfig-example/pom.xml b/eclipse/nsfs/nsf-jakartaee-jsonbconfig-example/pom.xml index faee7052..8aba563a 100644 --- a/eclipse/nsfs/nsf-jakartaee-jsonbconfig-example/pom.xml +++ b/eclipse/nsfs/nsf-jakartaee-jsonbconfig-example/pom.xml @@ -6,7 +6,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml nsf-jakartaee-jsonbconfig-example diff --git a/eclipse/nsfs/nsf-jakartaee-primefaces-example/pom.xml b/eclipse/nsfs/nsf-jakartaee-primefaces-example/pom.xml index fffa32f0..41547cf4 100644 --- a/eclipse/nsfs/nsf-jakartaee-primefaces-example/pom.xml +++ b/eclipse/nsfs/nsf-jakartaee-primefaces-example/pom.xml @@ -6,7 +6,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml nsf-jakartaee-primefaces-example diff --git a/eclipse/nsfs/nsf-jakartaee-primefaces-showcase/pom.xml b/eclipse/nsfs/nsf-jakartaee-primefaces-showcase/pom.xml index 6b067376..d662b988 100644 --- a/eclipse/nsfs/nsf-jakartaee-primefaces-showcase/pom.xml +++ b/eclipse/nsfs/nsf-jakartaee-primefaces-showcase/pom.xml @@ -6,7 +6,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml nsf-jakartaee-primefaces-showcase diff --git a/eclipse/pom.xml b/eclipse/pom.xml index 83465d59..5f9ae5fc 100644 --- a/eclipse/pom.xml +++ b/eclipse/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 pom XPages Jakarta EE Support diff --git a/eclipse/releng/org.openntf.xsp.jakartaee.source.updatesite/pom.xml b/eclipse/releng/org.openntf.xsp.jakartaee.source.updatesite/pom.xml index 84e9fca6..f3670f2e 100644 --- a/eclipse/releng/org.openntf.xsp.jakartaee.source.updatesite/pom.xml +++ b/eclipse/releng/org.openntf.xsp.jakartaee.source.updatesite/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakartaee.source.updatesite diff --git a/eclipse/releng/org.openntf.xsp.jakartaee.updatesite/pom.xml b/eclipse/releng/org.openntf.xsp.jakartaee.updatesite/pom.xml index 1e426170..9cc118cb 100644 --- a/eclipse/releng/org.openntf.xsp.jakartaee.updatesite/pom.xml +++ b/eclipse/releng/org.openntf.xsp.jakartaee.updatesite/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakartaee.updatesite diff --git a/eclipse/releng/xsp-jakartaee-dist/pom.xml b/eclipse/releng/xsp-jakartaee-dist/pom.xml index e30e000e..2c205015 100644 --- a/eclipse/releng/xsp-jakartaee-dist/pom.xml +++ b/eclipse/releng/xsp-jakartaee-dist/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml xsp-jakartaee-dist diff --git a/eclipse/tests/it-xsp-jakartaee/pom.xml b/eclipse/tests/it-xsp-jakartaee/pom.xml index 008a8d59..dc597a19 100644 --- a/eclipse/tests/it-xsp-jakartaee/pom.xml +++ b/eclipse/tests/it-xsp-jakartaee/pom.xml @@ -5,7 +5,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml it-xsp-jakartaee diff --git a/eclipse/tests/org.openntf.xsp.jakarta.example.webapp/pom.xml b/eclipse/tests/org.openntf.xsp.jakarta.example.webapp/pom.xml index d4cfe4c7..079d7d53 100644 --- a/eclipse/tests/org.openntf.xsp.jakarta.example.webapp/pom.xml +++ b/eclipse/tests/org.openntf.xsp.jakarta.example.webapp/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.example.webapp diff --git a/eclipse/tests/org.openntf.xsp.jakarta.json.test/pom.xml b/eclipse/tests/org.openntf.xsp.jakarta.json.test/pom.xml index 6af8dd52..cee8a1b6 100644 --- a/eclipse/tests/org.openntf.xsp.jakarta.json.test/pom.xml +++ b/eclipse/tests/org.openntf.xsp.jakarta.json.test/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.json.test diff --git a/eclipse/tests/org.openntf.xsp.jakarta.validation.test/pom.xml b/eclipse/tests/org.openntf.xsp.jakarta.validation.test/pom.xml index f4fae255..1192eb96 100644 --- a/eclipse/tests/org.openntf.xsp.jakarta.validation.test/pom.xml +++ b/eclipse/tests/org.openntf.xsp.jakarta.validation.test/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakarta.validation.test diff --git a/eclipse/tests/org.openntf.xsp.jakartaee.test/pom.xml b/eclipse/tests/org.openntf.xsp.jakartaee.test/pom.xml index a7c59da6..77feed30 100644 --- a/eclipse/tests/org.openntf.xsp.jakartaee.test/pom.xml +++ b/eclipse/tests/org.openntf.xsp.jakartaee.test/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.jakartaee.test diff --git a/eclipse/tests/org.openntf.xsp.test.beanbundle/pom.xml b/eclipse/tests/org.openntf.xsp.test.beanbundle/pom.xml index caa20201..8fc25083 100644 --- a/eclipse/tests/org.openntf.xsp.test.beanbundle/pom.xml +++ b/eclipse/tests/org.openntf.xsp.test.beanbundle/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.test.beanbundle diff --git a/eclipse/tests/org.openntf.xsp.test.jasapi/pom.xml b/eclipse/tests/org.openntf.xsp.test.jasapi/pom.xml index 0c71ea16..d53e8b6d 100644 --- a/eclipse/tests/org.openntf.xsp.test.jasapi/pom.xml +++ b/eclipse/tests/org.openntf.xsp.test.jasapi/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.test.jasapi diff --git a/eclipse/tests/org.openntf.xsp.test.postinstall/pom.xml b/eclipse/tests/org.openntf.xsp.test.postinstall/pom.xml index 3356c362..300d8254 100644 --- a/eclipse/tests/org.openntf.xsp.test.postinstall/pom.xml +++ b/eclipse/tests/org.openntf.xsp.test.postinstall/pom.xml @@ -4,7 +4,7 @@ org.openntf.xsp xsp-jakartaee - 3.1.0-SNAPSHOT + 3.1.0 ../../pom.xml org.openntf.xsp.test.postinstall