spring replace class ExpressionEvaluationUtils - spring

I have the following code and I migrated my project from spring 3 to spring 4.
But ExpressionEvaluationUtils is obsolete actually.
Do you have any idea to replace it ?
/**
* Set quote escaping for this tag, as boolean value. Default is "true".
*/
public void setQuoteEscape(String quoteEscape) throws JspException {
this.quoteEscape = ExpressionEvaluationUtils.evaluateBoolean("quoteEscape", quoteEscape, pageContext);
}
/**
* Set breakLine escaping for this tag, as boolean value. Default is "true".
*/
public void setBackslashEscape(String backslashEscape) throws JspException {
this.backslashEscape = ExpressionEvaluationUtils.evaluateBoolean("backslashEscape", backslashEscape, pageContext);
}
Do you have any idea to replace it?

Related

Why does Mockito return null when I specify an Optional of my type

I have a method on a controller to get a list of all the punishment types for a chat room (Kick, Ban, Warn and Mute). On the first test when I mock the data it works as expected and the test passes.
However, on my second test I provided. I defined what should be returned as an Optional<Punishment> with the attribute of punishmentName set as "mute". I am very confused why this is giving me null. When I run the Spring application outside of testing, the route works fine. For some reason the mock never wants to return the value I specified but only null. Specifically, this is being caught in the test on the line .andExpect(jsonPath("$.punishmentName", Matchers.equalTo("mute"))); as the fields value is null giving the following error:
java.lang.AssertionError: No value at JSON path "$.punishmentName"
For clarity, I have also provided the controller methods and service methods.
Punishment Controller Test:
#WebMvcTest(PunishmentController.class)
#RunWith(SpringRunner.class)
public class PunishmentControllerTest {
#Autowired
private MockMvc mvc;
#MockBean
private PunishmentService punishmentService;
#MockBean
private PunishmentValidator punishmentValidator;
#Test
public void getAllPunishmentTypesReturnsAListOfPunishmentTypes() throws Exception {
List<Punishment> punishments = new ArrayList<>();
punishments.add(new Punishment("mute"));
punishments.add(new Punishment("kick"));
punishments.add(new Punishment("ban"));
punishments.add(new Punishment("warn"));
Mockito.when(punishmentService.getAllPunishmentTypes()).thenReturn(punishments);
mvc.perform(get("/api/punishments"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.hasSize(4)))
.andExpect(jsonPath("$[0].punishmentName", Matchers.equalTo("mute")))
.andExpect(jsonPath("$[1].punishmentName", Matchers.equalTo("kick")))
.andExpect(jsonPath("$[2].punishmentName", Matchers.equalTo("ban")))
.andExpect(jsonPath("$[3].punishmentName", Matchers.equalTo("warn")));
}
#Test
public void getPunishmentTypeReturnsMuteWhenMuteIsSpecified() throws Exception {
Optional<Punishment> mute = Optional.of(new Punishment("mute"));
Mockito.when(punishmentService.getPunishmentType("mute")).thenReturn(mute);
mvc.perform(get("/api/punishments/mute"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.punishmentName", Matchers.equalTo("mute")));
}
Controller methods:
/**
* GET request for all punishment types.
* #return List<Punishment> - When Punishments are found in the database they are returned in a List object.
* Otherwise, an empty list is returned if no records are found or an error occurs.
*/
#GetMapping
public List<Punishment> getAllPunishments() {
return punishmentService.getAllPunishmentTypes();
}
/**
* GET request for one punishment type.
* #param punishmentType String - The type of punishment.
* #return Optional<Punishment> - The rule that gets returned or an empty optional if no rule is found.
*/
#GetMapping(path = "{punishmentType}")
public Optional<Punishment> getPunishment(#PathVariable("punishmentType") String punishmentType) {
boolean isPunishmentTypeValid = punishmentValidator.validatePunishmentName(punishmentType);
if (isPunishmentTypeValid) {
return punishmentService.getPunishmentType(punishmentType);
} else {
return Optional.empty();
}
}
}
Service methods:
/**
* Gets all the punishment types
* #return List<Punishment> - The rules in the community
*/
public List<Punishment> getAllPunishmentTypes() {
return punishmentRepository.findAll();
}
/**
* Gets a specific punishment type.
* #param punishmentType String - The type of punishment.
* #return The punishment retrieved.
*/
public Optional<Punishment> getPunishmentType(String punishmentType) {
return punishmentRepository.findById(punishmentType);
}
I believe it is because you forget to mock the method PunishmentValidator#validatePunishmentName("mute") to return true such that the method that you stub on PunishmentService is never invoked because by default if you do not stub a method , it will return false (see this).
Also it is a known behaviour that #MockBean is configured as lenient stubbing which will not reported error (i.e. throw UnnecessaryStubbingException) if you stub a method but it actually does not get executed.
So change the following should fix your problem :
#Test
public void getPunishmentTypeReturnsMuteWhenMuteIsSpecified() throws Exception {
Optional<Punishment> mute = Optional.of(new Punishment("mute"));
Mockito.when(punishmentService.getPunishmentType("mute")).thenReturn(mute);
Mockito.when(punishmentValidator.validatePunishmentName("mute")).thenReturn(true);
mvc.perform(get("/api/punishments/mute"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.punishmentName", Matchers.equalTo("mute")));
}

Check permission; always a request against database?

I have a question regarding Apache Shiro.
I´m using permission and role concept.
I have on the left side a menu with many links to my other pages (create an employee, show employee list etc.).
For each menu item I have also security for it to hide it or not (depends on the permission), like:
<pm:menu widgetVar="me"
rendered="#{checkPermissionController.checkPermission(['myprofile:show', 'myprofile:edit'])}">
To check if the user is permitted or not, I have those two functions in my bean:
/**
* Check permission for login User
*
* #return
* #throws IOException
* #throws PermissionGroupNotFoundException
*/
public boolean checkPermission(String permissionName) throws IOException {
if (loginBean.getCurrentUserShiro().isPermitted(permissionName)) {
return true;
}
return false;
}
/**
* If one of the permission is true
*
* #param strings
* #return
*/
public boolean checkPermission(List<String> list) {
int i = list.size();
if (i != 0) {
for (String s : list) {
if (loginBean.getCurrentUserShiro().isPermitted(s)) {
return true;
}
}
}
return false;
}
My question is now more against performance.
Is Apache Shiro execute for each menu entry a request against the database if the user is permitted or not?
Or does Shiro fetch at login time all permission for a user and "hold" it in the "Shiro User" object?
If yes: how can I improve it?
Edit:
Here my LoginBean:
#SessionScoped
#Named
public class LoginBean implements Serializable {
private Subject currentUserShiro;
public String submit() {
LOGGER.info("START submit");
try {
currentUserShiro = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
....
}
////////////////////
// Getter + Setter
////////////////////
public String getUsername() {
return username;
}
public Subject getCurrentUserShiro() {
return currentUserShiro;
}
currentUserShiro.login(token);
I'd recommend using Shiro's filters to handle the actual login logic for you.
https://shiro.apache.org/web.html
Otherwise, you could end up with the Subject not tied to your Session. It looks like your application might be forcing a log in any time getCurrentUserShiro is called. You should let the framework handle this for you.
It's not a JSF, but you can see a basic JSP example here (the Shrio config logic will be the same):
https://github.com/apache/shiro/tree/master/samples/servlet-plugin
You would likely just replace the login page: https://github.com/apache/shiro/blob/master/samples/servlet-plugin/src/main/webapp/login.jsp with your custom page

Thymeleaf - check if a template exists

I am searching a way to check if a template exists before returning it in a view with Thymeleaf and Spring.
In my controller i was trying to do something like this:
String finalTemplate = template.getPrefix() + "/" + templateName;
try {
return finalTemplate;
} catch(TemplateInputException e) {
logger.debug("Sono qua");
return templateName;
}
but the exception is not catch...
The way you are handling exception here will not work for template exceptions.
Check below threads regarding this in issues section github.
https://github.com/thymeleaf/thymeleaf-spring/issues/94
https://github.com/thymeleaf/thymeleaf-spring/issues/81
StringTemplateResource from the comment above seems to return true in every case for thymeleaf 3.0. Here is a method to do this for classpath included templates:
public static String baseDir = "templates";
/**
* Check if a template exists in subfolder templates.
*
* #param templateName relative name of template below the basedir.
* #return true if exists, otherwise false
*/
public static boolean templateExists(final String templateName)
{
final ClassLoaderTemplateResource iTemplateResource =
new ClassLoaderTemplateResource(baseDir + "/" + templateName, "UTF8");
return iTemplateResource.exists();
}
Testcase:
#Test
public void testNonExisting()
{
assertFalse(templateExists("foo"));
}
#Test
public void testExisting()
{
assertTrue(templateExists("foo.txt"));
}
Assuming a classpath resource templates/foo.txt exists.

ConfigurationFactory from log4j2 not executed in Spring boot application

I am trying to load a configuration file (.yaml) to configure log4j2 in a SpringBoot application. Using documentation provided by log4j2 team I am trying to execute a ConfigurationFactory. But nothing is executed. I have to do it when applications starts because there are some properties not defined until this point.
This is the code I have:
#Plugin(name = "LoggingConfigurationFactory", category = "ConfigurationFactory")
#Order(10)
public class LoggingConfigurationFactory extends ConfigurationFactory {
/**
* Valid file extensions for XML files.
*/
protected static final String[] SUFFIXES = new String[] {".yaml", "*"};
/**
* Return the Configuration.
* #param source The InputSource.
* #return The Configuration.
*/
#Override
public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source) {
return new NuarYamlConfiguration(loggerContext, source);
}
/**
* Returns the file suffixes for XML files.
* #return An array of File extensions.
*/
public String[] getSupportedTypes() {
return SUFFIXES;
}
}
If anyone knows how to do it, I would appreciate it
Thanks in advance
Peter

Externalized message.properties file is not picking up in Tomcat

According to my requirement, I need to externalize the message.properties file (Keep outside from war file) and in same time it should be automatically re loadable on update.
So I achieved both by following code and its working fine with Jetty Server. But in when I use Tomcat Server that externalized property file is not picking up by the system, instead its uses only the file inside the war.
public final class Messages
{
public static final String BUNDLE_NAME = "com.sample.project.core.ui.resources.messages";
// private static ResourceBundle resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME);
private static ResourceBundle resourceBundle;
private static final Logger LOGGER = Logger.getLogger(Messages.class);
private static ReloadableResourceBundleMessageSource messageSource;
static
{
try
{
FileInputStream fis =
new FileInputStream(System.getProperty("resources.messages.file.path"));
resourceBundle = new PropertyResourceBundle(fis);
}
catch (FileNotFoundException e)
{
LOGGER.error("messages.properties file not found: " + e);
resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME);
}
catch (Exception e)
{
LOGGER.error("messages.properties file reading failed: " + e);
resourceBundle = ResourceBundle.getBundle(BUNDLE_NAME);
}
}
private Messages()
{
}
/**
* <p>
* setter methos to ReloadableResourceBundleMessageSource object.
* </p>
*
*
* #param inMessageSource
* set reloadable resources bundle
**/
public static void setMessageSource(final ReloadableResourceBundleMessageSource inMessageSource)
{
Messages.messageSource = inMessageSource;
Messages.messageSource.setBasename(System.getProperty("resources.messages.file.path"));
}
/**
* <p>
* Resolve a message by a key and argument replacements.
* </p>
*
* #see MessageFormat#format(String, Object...)
* #param key
* the message to look up
* #param arguments
* optional message arguments
* #return the resolved message
**/
public static String getMessage(final String key, final Object... arguments)
{
try
{
if (messageSource != null)
{
return messageSource.getMessage(key, arguments, Locale.getDefault());
}
else
{
if (arguments != null)
return MessageFormat.format(resourceBundle.getString(key), arguments);
return resourceBundle.getString(key);
}
}
catch (NoSuchMessageException e)
{
LOGGER.error("Message key not found: " + key);
return '!' + key + '!';
}
catch (MissingResourceException e)
{
LOGGER.error("Message key not found: " + key);
return '!' + key + '!';
}
}
}
(Here file path I'm passing as a VM argument using "resources.messages.file.path" key)
First I thought it was a problem with accessing the file system and tried many ways. Then I heard about catalina.policy file and I added some lines like this..
grant codeBase "file:${catalina.base}/webapps/sample.war/-" {
permission java.security.AllPermission;
permission java.io.FilePermission "file:${catalina.base}${file.separator}webapps${file.separator}messages.properties", "read, write";
permission java.util.PropertyPermission "resources.messages.file.path", "read";
}
But non of them gave me luck. I'm desperate. Any idea what this issue is? Please help me. Thank you in advance. (Tested on Tomcat6)
Finally I found where I screwed up.
This setter method of messageSource should not be static and I removed static access of messageSource
messageSource = inMessageSource;
messageSource.setBasename(System.getProperty("resources.messages.file.path"));
Now code is working fine. And no need of that permission entry in catalina.policy file. Thanks to everyone who helped me.

Resources