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

Feature that allows you to use SpEL in @NamePattern of entity #1061

Open
wants to merge 1 commit into
base: release_6_10
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.haulmont.cuba.namepattern;

import com.haulmont.cuba.testmodel.namepattern.MethodNamePatternEntity;
import com.haulmont.cuba.testmodel.namepattern.SpelNamePatternEntity;
import com.haulmont.cuba.testmodel.namepattern.SimpleNamePatternEntity;
import com.haulmont.cuba.testsupport.TestContainer;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

/**
* @author Rushan Zagidullin
* @since 17.07.2018
*/
public class NamePatternTest {

@ClassRule
public static TestContainer container = TestContainer.Common.INSTANCE;

SimpleNamePatternEntity simpleNamePatternEntity1;
SimpleNamePatternEntity simpleNamePatternEntity2;
MethodNamePatternEntity methodNamePatternEntity1;
MethodNamePatternEntity methodNamePatternEntity2;
SpelNamePatternEntity spelNamePatternEntity1;
SpelNamePatternEntity spelNamePatternEntity2;

@SuppressWarnings("IncorrectCreateEntity")
@Before
public void setUp() {
simpleNamePatternEntity1 = new SimpleNamePatternEntity();
simpleNamePatternEntity1.setName("name1");

simpleNamePatternEntity2 = new SimpleNamePatternEntity();
simpleNamePatternEntity2.setName(null);

methodNamePatternEntity1 = new MethodNamePatternEntity();
methodNamePatternEntity1.setName("name1");

methodNamePatternEntity2 = new MethodNamePatternEntity();
methodNamePatternEntity2.setName(null);

spelNamePatternEntity1 = new SpelNamePatternEntity();
spelNamePatternEntity1.setName("name1");
spelNamePatternEntity1.setNumber(5);
spelNamePatternEntity1.setNumber2(null);

spelNamePatternEntity2 = new SpelNamePatternEntity();
spelNamePatternEntity2.setName("name2");
spelNamePatternEntity2.setNumber(null);
spelNamePatternEntity2.setNumber2(null);
}

@Test
public void testSimpleNamePatternEntity1() {
assertEquals("name1", simpleNamePatternEntity1.getInstanceName());
}

@Test
public void testSimpleNamePatternEntity2() {
assertEquals("", simpleNamePatternEntity2.getInstanceName());
}

@Test
public void testMethodNamePatternEntity1() {
assertEquals("name1", methodNamePatternEntity1.getInstanceName());
}

@Test
public void testMethodNamePatternEntity2() {
assertNull(methodNamePatternEntity2.getInstanceName());
}

@Test
public void testComplexNamePatternEntity1() {
assertEquals("Hello, my name is name1. Sum of numbers = 5", spelNamePatternEntity1.getInstanceName());
}

@Test
public void testComplexNamePatternEntity2() {
assertEquals("Hello, my name is name2. Sum of numbers = 0", spelNamePatternEntity2.getInstanceName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.haulmont.cuba.namepattern;

import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
* @author Rushan Zagidullin
* @since 17.07.2018
*/
@Component("cuba_NamePatternTestBean")
public class NamePatternTestBean {
public int sum(Integer... values) {
return Optional.ofNullable(values)
.map(ints -> Arrays.stream(ints)
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.sum())
.orElse(0);
}

public String concat(String... values) {
return Optional.ofNullable(values)
.map(strings -> Arrays.stream(strings)
.collect(Collectors.joining()))
.orElse("");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.haulmont.cuba.testmodel.namepattern;

import com.haulmont.chile.core.annotations.NamePattern;
import com.haulmont.cuba.core.entity.StandardEntity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

/**
* @author Rushan Zagidullin
* @since 17.07.2018
*/
@NamePattern("#formatName|name")
@Table(name = "TEST_METHOD_NAME_PATTERN_ENTITY")
@Entity(name = "test$MethodNamePatternEntity")
public class MethodNamePatternEntity extends StandardEntity {
private static final long serialVersionUID = -833743669993760614L;

@Column(name = "NAME")
protected String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public String formatName() {
return getName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.haulmont.cuba.testmodel.namepattern;

import com.haulmont.chile.core.annotations.NamePattern;
import com.haulmont.cuba.core.entity.StandardEntity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

/**
* @author Rushan Zagidullin
* @since 17.07.2018
*/
@NamePattern("%s|name")
@Table(name = "TEST_SIMPLE_NAME_PATTERN_ENTITY")
@Entity(name = "test$SimpleNamePatternEntity")
public class SimpleNamePatternEntity extends StandardEntity {
private static final long serialVersionUID = -833743669993760614L;

@Column(name = "NAME")
protected String name;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.haulmont.cuba.testmodel.namepattern;

import com.haulmont.chile.core.annotations.NamePattern;
import com.haulmont.cuba.core.entity.StandardEntity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;

/**
* @author Rushan Zagidullin
* @since 17.07.2018
*/
@NamePattern("#{@cuba_NamePatternTestBean.concat('Hello, my name is ', name, '. Sum of numbers = ', @cuba_NamePatternTestBean.sum(number, number2))}|name")
@Table(name = "TEST_SPEL_NAME_PATTERN_ENTITY")
@Entity(name = "test$SpelNamePatternEntity")
public class SpelNamePatternEntity extends StandardEntity {
private static final long serialVersionUID = -833743669993760614L;

@Column(name = "NAME")
protected String name;

@Column(name = "NUMBER")
protected Integer number;

@Column(name = "NUMBER_2")
protected Integer number2;

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public Integer getNumber() {
return number;
}

public void setNumber(Integer number) {
this.number = number;
}

public Integer getNumber2() {
return number2;
}

public void setNumber2(Integer number2) {
this.number2 = number2;
}
}
4 changes: 4 additions & 0 deletions modules/core/test/cuba-test-persistence.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,9 @@
<class>com.haulmont.cuba.testmodel.jpa_cascade.JpaCascadeItem</class>

<class>com.haulmont.cuba.testmodel.not_persistent.CustomerWithNonPersistentRef</class>

<class>com.haulmont.cuba.testmodel.namepattern.MethodNamePatternEntity</class>
<class>com.haulmont.cuba.testmodel.namepattern.SimpleNamePatternEntity</class>
<class>com.haulmont.cuba.testmodel.namepattern.SpelNamePatternEntity</class>
</persistence-unit>
</persistence>
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,16 @@
import com.haulmont.cuba.core.global.DevelopmentException;
import com.haulmont.cuba.core.global.Messages;
import com.haulmont.cuba.core.global.MetadataTools;
import com.haulmont.cuba.core.sys.AppContext;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -226,6 +234,9 @@ public static String getInstanceName(Instance instance) {
throw new RuntimeException("Error getting instance name", e);
}
}
if (rec.isSpEL) {
return evaluateSpEL(instance, rec.format);
}

// lazy initialized messages, used only for enum values
Messages messages = null;
Expand All @@ -252,6 +263,15 @@ public static String getInstanceName(Instance instance) {
}
}

public static String evaluateSpEL(Instance instance, String format) {
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext evaluationContext = new StandardEvaluationContext(instance);
BeanResolver beanResolver = new BeanFactoryResolver(AppContext.getApplicationContext());
evaluationContext.setBeanResolver(beanResolver);
Expression expression = parser.parseExpression(format, new TemplateParserContext());
return expression.getValue(evaluationContext, String.class);
}

/**
* Parse a name pattern defined by {@link NamePattern} annotation.
* @param metaClass entity meta-class
Expand All @@ -272,10 +292,13 @@ public static NamePatternRec parseNamePattern(MetaClass metaClass) {

String format = StringUtils.substring(pattern, 0, pos);
String trimmedFormat = format.trim();
String methodName = trimmedFormat.startsWith("#") ? trimmedFormat.substring(1) : null;
boolean isSpEL = trimmedFormat.startsWith("#{");
String methodName = trimmedFormat.startsWith("#") && !isSpEL ?
trimmedFormat.substring(1) :
null;
String fieldsStr = StringUtils.substring(pattern, pos + 1);
String[] fields = INSTANCE_NAME_SPLIT_PATTERN.split(fieldsStr);
return new NamePatternRec(format, methodName, fields);
return new NamePatternRec(format, methodName, fields, isSpEL);
}

public static class NamePatternRec {
Expand All @@ -291,11 +314,16 @@ public static class NamePatternRec {
* Array of property names
*/
public final String[] fields;
/**
* Is name pattern described as SpEL
*/
public final boolean isSpEL;

public NamePatternRec(String format, String methodName, String[] fields) {
public NamePatternRec(String format, String methodName, String[] fields, boolean isSpEL) {
this.fields = fields;
this.format = format;
this.methodName = methodName;
this.isSpEL = isSpEL;
}
}

Expand Down