Skip to content

Commit

Permalink
Merge branch 'main' into upgrade-to-hibernate-6.4
Browse files Browse the repository at this point in the history
  • Loading branch information
Cies authored and Cies committed May 22, 2024
2 parents 821ced0 + 987b018 commit 62f0ca5
Show file tree
Hide file tree
Showing 14 changed files with 111 additions and 66 deletions.
39 changes: 22 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,33 @@ To run tests only on Javanet:

## How to release

To make a release, you need to
1. have a write permission to `io.github.replay-framework` group in Maven central repository.
2. have these lines in `~/.gradle/gradle.properties`:
> signing.keyId=2#####8
> signing.password=***********************
> signing.secretKeyRingFile=/Users/andrei/.gnupg/secring.gpg
> sonatypeUsername=*******
> sonatypePassword=********************
Steps to release version 2.4.0 (for example)
To make a release, you need to:
1. Have a write permission to `io.github.replay-framework` group in Maven central repository.
2. Have these lines in `~/.gradle/gradle.properties`:

```
signing.keyId=2#####8
signing.password=***********************
signing.secretKeyRingFile=/path/to/.gnupg/secring.gpg
sonatypeUsername=*******
sonatypePassword=********************
```

A guide for setting up GPG for can be found on [the Sonatype website](https://central.sonatype.org/publish/requirements/gpg).

Steps to release version 2.4.0 (for example):
1. Fill the CHANGELOG.md
2. Replace previous version by "2.4.0" in build.gradle
3. commit & push (CHANGELOG.md + build.gradle + maybe something else)
4. run ./release.sh 2.4.0 // This uploads the `*.jar` files to https://oss.sonatype.org
3. Commit & push (CHANGELOG.md + build.gradle + maybe something else)
4. Run ./release.sh 2.4.0 // This uploads the `*.jar` files to https://oss.sonatype.org
5. Login to https://oss.sonatype.org/#stagingRepositories
5.1. Click "Close", wait until "release" button gets enabled (~1-2 minutes)
5.2. Click "Release" (no need to fill description)
5.3. After ~5 minutes, the new jar will be available in Central Maven repo
* Click "Close", wait until "release" button gets enabled (~1-2 minutes)
* Click "Release" (no need to fill description)
* After ~5 minutes, the new jar will be available in Central Maven repo
6. Open https://github.com/replay-framework/replay/milestones -> 2.4.0 -> "Edit milestone" -> "Close milestone"
7. Open https://github.com/replay-framework/replay/releases -> "Draft a new release"
7.1. fill the release details (copy-paste from CHANGELOG.md)
7.2. click "Publish release"
* Fill the release details (copy-paste from CHANGELOG.md)
* Click "Publish release"
8. Replace version in build.gradle by "2.5.0-SNAPSHOT" and commit
9. Create a new release on github: https://github.com/replay-framework/replay/releases
10. Close milestone 2.4.0 and create a new milestone 2.5.0: https://github.com/replay-framework/replay/milestones
Expand Down
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ defaultTasks 'clean', 'check', 'publishToMavenLocal'

ext {
commonsLangVersion = '3.14.0'
netty4Version = '4.1.108.Final'
commonsTextVersion = '1.11.0'
slf4jVersion = '2.0.12'
netty4Version = '4.1.109.Final'
commonsTextVersion = '1.12.0'
slf4jVersion = '2.0.13'
assertjVersion = '3.25.3'
mockitoVersion = '5.11.0'
mockitoVersion = '5.12.0'
pdfTestVersion = '1.8.1'
groovyVersion = '3.0.21'
httpclientVersion = '4.5.14'
Expand All @@ -22,7 +22,7 @@ subprojects {
apply plugin: 'java'
apply plugin: 'java-library'

[compileJava, compileTestJava]*.options.collect {options ->
[compileJava, compileTestJava]*.options.collect { options ->
options.encoding = 'UTF-8'
options.compilerArgs << '-parameters'
options.debug = true
Expand Down
10 changes: 5 additions & 5 deletions framework/build.gradle
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
dependencies {
api('com.google.code.findbugs:jsr305:3.0.2')
implementation('io.github.classgraph:classgraph:4.8.168')
implementation('io.github.classgraph:classgraph:4.8.172')
api('com.zaxxer:HikariCP:5.1.0')
api('com.google.code.gson:gson:2.10.1')
// Cannot upgrade to org.asynchttpclient:async-http-client as that requires Netty4 and we use Netty3
implementation('com.ning:async-http-client:1.9.40') {
exclude group: 'io.netty'
}
api('com.google.guava:guava:33.1.0-jre') {transitive = false}
api('com.google.guava:guava:33.2.0-jre') {transitive = false}
api('commons-beanutils:commons-beanutils:1.9.4') {transitive = false}
api('commons-codec:commons-codec:1.16.1') {transitive = false}
api('commons-codec:commons-codec:1.17.0') {transitive = false}
api('org.apache.commons:commons-email:1.6.0') {transitive = false}
api('commons-fileupload:commons-fileupload:1.5.0.redhat-00001')
api('commons-io:commons-io:2.15.1')
api('commons-io:commons-io:2.16.1')
implementation("org.apache.commons:commons-lang3:$commonsLangVersion")
implementation "org.apache.commons:commons-text:$commonsTextVersion"
implementation 'com.github.f4b6a3:ulid-creator:5.2.3'
api('commons-logging:commons-logging:1.3.0')
api('commons-logging:commons-logging:1.3.2')
api('javax.mail:mail:1.4.7')
api('javax.inject:javax.inject:1')
api('jakarta.inject:jakarta.inject-api:2.0.1')
Expand Down
37 changes: 18 additions & 19 deletions framework/src/play/data/binding/ParamNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@
import play.utils.Utils;

import java.util.*;
import java.util.regex.Pattern;

public class ParamNode {
private final String name;
private final Map<String, ParamNode> _children = new HashMap<>(8);
private String[] values = null;
private String originalKey;

// splits a string on one-ore-more instances of .[]
// this works so that all the following strings (param naming syntax)
// is resolved into the same structural hierarchy:
// Regex to split the key of an x-www-form-urlencoded key-value pair on one-ore-more instances of ".[]".
// Using this all the following strings (Play's naming syntax for keys) resolved into the same structural hierarchy:
// a.b.c=12
// a[b].c=12
// a[b][c]=12
// a.b[c]=12
private static final String keyPartDelimiterRegexpString = "[\\.\\[\\]]+";
private static final Pattern keyPartDelimiterRegex = Pattern.compile("[.\\[\\]]+");

public ParamNode(String name) {
this.name = name;
Expand All @@ -36,15 +36,15 @@ public String getFirstValue(Class<?> type) {
return null;
}

if (values.length>1 && String.class.equals(type)) {
// special handling for string - when multiple values, concatenate them with comma..
if (values.length > 1 && String.class.equals(type)) {
// Special handling for strings: when multiple values are provided, concatenate them into one
return Utils.join(values, ", ");
} else {
return values[0];
}
}

public void addChild( ParamNode child) {
public void addChild(ParamNode child) {
_children.put(child.name, child);
}

Expand All @@ -53,7 +53,7 @@ public ParamNode getChild(String name) {
}

public ParamNode getChild(String name, boolean returnEmptyChildIfNotFound) {
ParamNode child = getChild( name.split(keyPartDelimiterRegexpString));
ParamNode child = getChild(keyPartDelimiterRegex.split(name));
if (child == null && returnEmptyChildIfNotFound) {
child = new ParamNode(name);
}
Expand All @@ -72,7 +72,7 @@ public RemovedNode(ParamNode removedFrom, ParamNode removedNode) {

/**
* Removes a child from this node, but stores what is removed to list.
* The we can later call which will add it back again.
* Then we can later call which will add it back again.
* This is a "hack" related to #1195 which makes it possible to reuse the RootParamsNode-structure
* if you want to perform the bind-operation multiple times.
*
Expand All @@ -82,24 +82,24 @@ public RemovedNode(ParamNode removedFrom, ParamNode removedNode) {
*/
public boolean removeChild(String name, List<RemovedNode> removedNodesList) {
ParamNode removedNode = _children.remove(name);
if ( removedNode != null) {
removedNodesList.add( new RemovedNode(this, removedNode));
if (removedNode != null) {
removedNodesList.add(new RemovedNode(this, removedNode));
return true;
} else {
return false;
}
}

public static void restoreRemovedChildren( List<RemovedNode> removedNodesList ) {
for ( RemovedNode rn : removedNodesList) {
for (RemovedNode rn : removedNodesList) {
rn.removedFrom._children.put( rn.removedNode.name, rn.removedNode);
}
}

private ParamNode getChild(String[] nestedNames) {
ParamNode currentChildNode = this;
for (int i=0; i<nestedNames.length; i++) {
currentChildNode = currentChildNode._children.get(nestedNames[i]);
for (String nestedName : nestedNames) {
currentChildNode = currentChildNode._children.get(nestedName);
if (currentChildNode == null) {
return null;
}
Expand Down Expand Up @@ -128,7 +128,7 @@ public String getOriginalKey() {
}

public static RootParamNode convert(Map<String, String[]> params) {
RootParamNode root = new RootParamNode( params);
RootParamNode root = new RootParamNode(params);

for (Map.Entry<String, String[]> e : params.entrySet()) {
String key = e.getKey();
Expand All @@ -139,8 +139,8 @@ public static RootParamNode convert(Map<String, String[]> params) {

ParamNode currentParent = root;

for ( String name : key.split(keyPartDelimiterRegexpString)) {
ParamNode paramNode = currentParent.getChild( name );
for (String name : keyPartDelimiterRegex.split(key)) {
ParamNode paramNode = currentParent.getChild(name);
if (paramNode ==null) {
// first time we see this node - create it and add it to parent
paramNode = new ParamNode(name);
Expand All @@ -150,8 +150,7 @@ public static RootParamNode convert(Map<String, String[]> params) {
}

// currentParent is now the last node where we should place the values
currentParent.setValue( values, key);

currentParent.setValue(values, key);
}
return root;
}
Expand Down
2 changes: 1 addition & 1 deletion framework/src/play/plugins/PluginCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ private PluginDescriptor toPluginDescriptor(ClasspathResource pluginsFile, Strin
return new PluginDescriptor(lineParts[1].trim(), parseInt(lineParts[0]), pluginsFile.url());
}

private void loadPlugins(SortedSet<PluginDescriptor> pluginsToLoad) {
public void loadPlugins(SortedSet<PluginDescriptor> pluginsToLoad) {
for (PluginDescriptor info : pluginsToLoad) {
logger.trace("Loading plugin {}", info.name);
PlayPlugin plugin = Injector.getBeanOfType(info.name);
Expand Down
29 changes: 18 additions & 11 deletions framework/test/play/data/binding/BinderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,14 @@ public void verify_unbinding_and_binding_of_simple_Bean() {
data1.a = "aAaA";
data1.b = 13;



Map<String, Object> r = new HashMap<>();
Data1.myStatic = 1;

Unbinder.unBind(r, data1, "data1", noAnnotations);
// make sure we only have info about the properties we want..
// make sure we only have info about the properties we want
assertThat(r.keySet()).containsOnly("data1.a", "data1.b");

Map<String, String[]> r2 = fromUnbindMap2BindMap( r);
Map<String, String[]> r2 = fromUnbindMap2BindMap(r);

Data1.myStatic = 2;
RootParamNode root = ParamNode.convert(r2);
Expand All @@ -72,6 +70,17 @@ public void verify_unbinding_and_binding_of_simple_Bean() {
assertThat(Data1.myStatic).isEqualTo(2);
}

@Test
public void verify_equality_of_structural_hierarchy() {

Map<String, String[]> abc12 = Map.of("a.b.c", new String[] {"12"});
RootParamNode root = ParamNode.convert(abc12);
assertThat(root.getChild("a.b.c").getValues()).isEqualTo(new String[] {"12"});
assertThat(root.getChild("a[b].c").getValues()).isEqualTo(new String[] {"12"});
assertThat(root.getChild("a[b][c]").getValues()).isEqualTo(new String[] {"12"});
assertThat(root.getChild("a.b[c]").getValues()).isEqualTo(new String[] {"12"});
}


@Test
public void verify_unbinding_and_binding_of_nestedBeans() {
Expand All @@ -94,8 +103,6 @@ public void verify_unbinding_and_binding_of_nestedBeans() {
data2.data.add(data1_1);
data2.data.add(data1_2);



Map<String, Object> r = new HashMap<>();
Unbinder.unBind(r, data2, "data2", noAnnotations);
Map<String, String[]> r2 = fromUnbindMap2BindMap(r);
Expand Down Expand Up @@ -234,8 +241,8 @@ public void test_enum_set_binding() {

RootParamNode rootParamNode = ParamNode.convert(params);

Data5 binded = (Data5) Binder.bind(request, session, rootParamNode, "data", Data5.class, Data5.class, noAnnotations);
assertThat(binded.testEnumSet).isEqualTo(data.testEnumSet);
Data5 bound = (Data5) Binder.bind(request, session, rootParamNode, "data", Data5.class, Data5.class, noAnnotations);
assertThat(bound.testEnumSet).isEqualTo(data.testEnumSet);
}

@Test
Expand All @@ -245,8 +252,8 @@ public void test_binding_class_with_private_constructor() {

RootParamNode rootParamNode = ParamNode.convert(params);

Data6 binded = (Data6) Binder.bind(request, session, rootParamNode, "user", Data6.class, Data6.class, noAnnotations);
assertThat(binded.name).isEqualTo("john");
Data6 bound = (Data6) Binder.bind(request, session, rootParamNode, "user", Data6.class, Data6.class, noAnnotations);
assertThat(bound.name).isEqualTo("john");
}

/**
Expand All @@ -265,7 +272,7 @@ private Map<String, String[]> fromUnbindMap2BindMap(Map<String, Object> r) {
} else if (v instanceof String[]) {
r2.put(key, (String[])v);
} else if (v instanceof Collection) {
Object[] array = ((Collection) v).toArray();
Object[] array = ((Collection<?>) v).toArray();
r2.put(key, Arrays.copyOf(array, array.length, String[].class));
} else {
throw new RuntimeException("error");
Expand Down
6 changes: 6 additions & 0 deletions framework/test/play/plugins/PluginCollectionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import play.libs.WS;

import java.util.List;
import java.util.TreeSet;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
Expand Down Expand Up @@ -136,6 +137,11 @@ public void onApplicationStop_runsPluginsInReverseOrder() {
inOrder.verify(plugin2).onApplicationStop();
inOrder.verify(plugin1).onApplicationStop();
}

@Test
public void loadPlugins_shouldAllowDirectInvocation() {
new PluginCollection().loadPlugins(new TreeSet<>());
}
}

class TestPlugin extends PlayPlugin {{index = 1;}}
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
2 changes: 1 addition & 1 deletion liquibase/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ dependencies {
implementation project(':framework')
testImplementation project(':framework').sourceSets.test.compileClasspath

implementation('org.liquibase:liquibase-core:4.26.0') {transitive = false}
implementation('org.liquibase:liquibase-core:4.27.0') {transitive = false}
}

apply from: rootProject.file('gradle/deploy.gradle')
2 changes: 1 addition & 1 deletion pdf/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ configurations {
}

ext {
FLYING_SOURCER_VERSION = '9.7.1'
FLYING_SOURCER_VERSION = '9.7.2'
YAHP_VERSION = 1.3
}

Expand Down
30 changes: 29 additions & 1 deletion replay-tests/criminals/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# criminals
# Criminals

This is an example of a [RePlay](https://github.com/replay-framework/replay) project.

It may be used to understand the differences between a project based on [Play1](https://github.com/playframework/play1) and a project based on RePlay.

It also serves as a means to test RePlay.


## Running

Since all all projects in the `replay-test` folder are parameterized over the server backends (e.g.: `netty3`, `netty4` or `javanet`) you need to
uncomment the `implementation` line in `replay-tests/replay-tests.gradle`:

```java
dependencies {
// To run the app locally:
// implementation project(':netty3')

// ...
}
```

You need to add the `-parameters` flag to the `javac` configuration in:
`Settings` > `Build, Execution, Deployment` > `Compiler` > `Java Compiler` > `Additional command line parameters`.
Then rebuild your project with: `Build` > `Rebuild Project`.

After that you can run the project from IntelliJ with the pre-configured `Criminals` Run Configuration.

To log in the password should be identical the email address provided in the login page.
You are then asked to provide an OTP, the OTP is found output of the application
after submitting your username and password.

Loading

0 comments on commit 62f0ca5

Please sign in to comment.