Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TAP5-2749: Incorrect behavior of getIfExists in EntityApplicationStatePersistenceStrategy #36

Merged
merged 5 commits into from
Apr 23, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,16 @@ public <T> T getIfExists(Class<T> ssoClass)

Object sso = session.getAttribute(key);

return sso != null ? (T)sso : null;
return transformPersistedValue(sso);
}
return null;
}

protected <T> T transformPersistedValue(Object value)
{
return (T) value;
}

protected <T> String buildKey(Class<T> ssoClass)
{
return PREFIX + ssoClass.getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ public EntityApplicationStatePersistenceStrategy(Request request, Session hibern
delegate = new EntityPersistentFieldStrategy(hibernateSession, null);
}

@Override
protected <T> T transformPersistedValue(Object value)
{
return value instanceof SessionRestorable ? (T) delegate.convertPersistedToApplicationValue(value) : (T) value;
}

@Override
@SuppressWarnings("unchecked")
public <T> T get(Class<T> ssoClass, ApplicationStateCreator<T> creator)
Expand All @@ -44,7 +50,7 @@ public <T> T get(Class<T> ssoClass, ApplicationStateCreator<T> creator)

if (persistedValue instanceof SessionRestorable)
{
Object restored = delegate.convertPersistedToApplicationValue(persistedValue);
Object restored = transformPersistedValue(persistedValue);

// Maybe throw an exception instead?
if (restored == null)
Expand Down
7 changes: 7 additions & 0 deletions tapestry-jpa/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,11 @@ task runTestApp6(type:JavaExec) {
args "-d", "src/test/app6", "-p", "8080"
classpath += project.sourceSets.test.runtimeClasspath
}

task runTestApp7(type:JavaExec) {
description 'Start app7 integration test app, useful when debugging failing integration tests'
main = 'org.apache.tapestry5.test.JettyRunner'
args "-d", "src/test/app7", "-p", "8080"
classpath += project.sourceSets.test.runtimeClasspath
}

Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public EntityApplicationStatePersistenceStrategy(final Request request,
this.entityManagerManager = entityManagerManager;
}

@Override
protected <T> T transformPersistedValue(Object value)
{
return value instanceof PersistedEntity ? (T) ((PersistedEntity) value).restore(entityManagerManager) : (T) value;
}

@Override
public <T> T get(final Class<T> ssoClass, final ApplicationStateCreator<T> creator)
{
Expand All @@ -41,7 +47,7 @@ public <T> T get(final Class<T> ssoClass, final ApplicationStateCreator<T> creat
{
final PersistedEntity persisted = (PersistedEntity) persistedValue;

final Object restored = persisted.restore(entityManagerManager);
final Object restored = transformPersistedValue(persisted);

// shall we maybe throw an exception instead?
if (restored == null)
Expand Down
15 changes: 15 additions & 0 deletions tapestry-jpa/src/test/app7/Index.tml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<head>
<title>Start Page</title>
</head>
<body>
<div>
<t:if test="loggedIn">
<span>Logged as ${username}</span>
</t:if>
<t:if test="notLogged">
<t:actionlink t:id="signIn">Sign in</t:actionlink>
</t:if>
</div>
</body>
</html>
18 changes: 18 additions & 0 deletions tapestry-jpa/src/test/app7/Login.tml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<body>
<div>
<t:form t:id="login">
<h2>Please sign in</h2>
<div>
<t:textfield t:id="username" placeholder="Username"/>
</div>
<div>
<t:passwordfield t:id="password" placeholder="Password"/>
</div>
<div>
<t:submit t:id="register" />
</div>
</t:form>
</div>
</body>
</html>
35 changes: 35 additions & 0 deletions tapestry-jpa/src/test/app7/WEB-INF/web.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2023 The Apache Software Foundation

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.
-->

<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Test Tapestry Project</display-name>
<context-param>
<param-name>tapestry.app-package</param-name>
<param-value>org.example.app7</param-value>
</context-param>
<filter>
<filter-name>app</filter-name>
<filter-class>org.apache.tapestry5.TapestryFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>app</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
6 changes: 6 additions & 0 deletions tapestry-jpa/src/test/conf/testng.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,10 @@
</packages>
</test>

<test name="Tapestry JPA Integration Test with EntityApplicationStatePersistenceStrategy" enabled="true">
<parameter name="tapestry.web-app-folder" value="src/test/app7" />
<packages>
<package name="org.apache.tapestry5.jpa.integration.app7" />
</packages>
</test>
</suite>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2023 The Apache Software Foundation
//
// 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 org.apache.tapestry5.jpa.integration.app7;

import org.apache.tapestry5.test.SeleniumTestCase;
import org.apache.tapestry5.test.TapestryTestConfiguration;
import org.testng.annotations.Test;

@TapestryTestConfiguration(webAppFolder = "src/test/app7")
public class SessionApplicationStatePersistenceStrategyTest extends SeleniumTestCase
{

@Test
public void check()
{
open("/");
clickAndWait("link=Sign in");
String username = "test-user";
typeKeys("//input[@id='username']", username);
typeKeys("//input[@id='password']", "test-password");
clickAndWait("//input[@id='register']");
assertTextPresent("Logged as " + username);
}
}
20 changes: 20 additions & 0 deletions tapestry-jpa/src/test/java/org/example/app7/AppConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2023 The Apache Software Foundation
//
// 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 org.example.app7;

public class AppConstants
{
public static final String TEST_PERSISTENCE_UNIT = "TestUnit";
}
48 changes: 48 additions & 0 deletions tapestry-jpa/src/test/java/org/example/app7/entities/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2023 The Apache Software Foundation
//
// 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 org.example.app7.entities;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class User
{
@Id
private String username;

private String password;

public String getPassword()
{
return password;
}

public void setPassword(String password)
{
this.password = password;
}

public String getUsername()
{
return username;
}

public void setUsername(String username)
{
this.username = username;
}

}
50 changes: 50 additions & 0 deletions tapestry-jpa/src/test/java/org/example/app7/pages/Index.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2023 The Apache Software Foundation
//
// 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 org.example.app7.pages;

import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.ApplicationStateManager;
import org.example.app7.entities.User;

public class Index
{
@Inject
private ApplicationStateManager applicationStateManager;

@InjectPage
private Login login;

public String getUsername()
{
User user = applicationStateManager.getIfExists(User.class);
return user != null ? user.getUsername() : null;
}

public boolean isLoggedIn()
{
return applicationStateManager.exists(User.class);
}

public boolean isNotLogged()
{
return !isLoggedIn();
}

Object onActionFromSignIn()
{
return login;
}
}
57 changes: 57 additions & 0 deletions tapestry-jpa/src/test/java/org/example/app7/pages/Login.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2023 The Apache Software Foundation
//
// 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 org.example.app7.pages;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.example.app6.AppConstants;
import org.example.app7.entities.User;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.ApplicationStateManager;

public class Login
{
@Property
private String username;

@Property
private String password;

@Inject
@PersistenceContext(unitName = AppConstants.TEST_PERSISTENCE_UNIT)
private EntityManager entityManager;

@Inject
private ApplicationStateManager applicationStateManager;

@InjectPage
private Index index;

Object onSuccessFromLogin()
{
entityManager.getTransaction().begin();
User user = new User();
user.setUsername(username);
user.setPassword(password);
entityManager.persist(user);
entityManager.getTransaction().commit();

applicationStateManager.set(User.class, user);
return index;
}
}