Captalizing Strings Automatically before Persist - java

I have the following situation: my application needs to save all the strings typed by the user capitalized on the database, no matter how the user types it, the application needs to capitalize everything before saving it.
I know I could just call the toUpperCase() method on every string before saving it, or call it on every setter method, but I really don't want to do that, I'm looking for a more automatic way to do it without having to change too much code on the application.
I'm using JSF, JPA2, Eclipselink and EJB3.
Does anyone have any suggestion?

You can use lifecycle event listeners for this. There are several ways to implement it:
1: default listeners:
public class StringCapListener {
#PrePersist
#PreUpdate
public void capitalize(Object o) {
// capitalize string attributes
}
...
For the capitalizing you will either need to use reflection (extracting all string fields and changing their value) or let your entities implement an interface.
If you are using the listener only on several entities, prefer using the #EntityListeners annotation on the entity classes. In order to use the listeners on all entities, use default listeners. Unfortunately, you can only define them in XML:
<entity-mappings ...>
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="com.example.StringCapListener">
2: inherited listener method
Let your entities derive from a BaseEntity of sorts. This base class can implement a listener method that is triggered on persist & update.
#PrePersist
#PreUpdate
public void capitalize(BaseEntity o) {
// capitalize string attributes
}
You will need to employ the same reflection magic to get and change all string attributes.

I'm thinking of an interface
public interface Processor<TResult, TInput> {
public TResult process(TInput input);
}
public class StringProcessor implements Processor<String, String> {
public String process(String input) {
return input.toUpperCase();
}
}
Then you'd call the interface on every string before persisting it
//...
public void persistString(String input) {
input = processor.process(input);
// Persistence logic
}

Related

Is it safe to use String as a return type of a bean in spring?

#Configuration
public class Product {
#Bean("xyz")
public String getMethod() {
return "abc";
}
}
#Component
public class Test {
String b;
Test(String xyz) {
this.b = xyz;
}
}
Is this any harm with this approach? I am trying to make change in the existing code where I am replacing the #Value with the getter as the method parameter. As I don't want to change the structure of the existing code I am trying to inject the method as bean as a replacement to #Value.
I suggest you to keep the #Value annotation instead of the whole #Bean configurations.
Why?
What if the getMethod()'s returned value needs to be changed very often? Everytime when you're changing something in the Product class, during build time it needs to be recompiled. What happens if the project is getting bigger and you're using this approach? It leads to longer build time and the more important thing is that this solution is not intuitive and it's hard to keep it clean. Don't think about complex solutions only to make the code look fancy. When you need to inject String values, the easiest approach is to create properties files (which won't get recompiled) and use the #Value annotation.
Now, if you want to add new methods without changing the structure of the existing code there are some patterns which you can apply like decorator pattern.
The main idea is simple: you're creating a decorator class which has an object of the type you need.
The easiest example (which you'll find everywhere on the internet) is the classic Shape example:
public interface Shape {
String someMethod();
}
#Component
public class CustomShape implements Shape { //implement the method here }
And here is the decorator:
public interface ShapeDecorator {
String someMethodExtended();
void someExtraMethod();
}
#Component
public class CustomShapeDecorator implements ShapeDecorator{
#Autowired
// #Qualifier - optional (only if you have more Shape implementations)
private Shape shape;
// now you can either:
// 1. provide new methods
#Override
public void someExtraMethod(){
System.out.println("Hello world!");
}
// 2. or you can EXTEND the Shape's "someMethod()" implementation
#Override
public String someMethodExtended(){
String oldString = this.shape.someMethod();
return oldString + " EXTENDED";
}
}

Where is the right place for annotation processing?

I write simple application. I don't want to use any frameworks. Please suggest me right place to hold annotation processing.
I have a few lines in main method:
String myString = (#NonNull String)list;
And I created #interface:
#Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public #interface NonNull {
}
Which step should I take next? Can I work with annotations without using reflection? Could you expose for me samples of such annotation processing code?
There is no way (AFAIK) to work with annotations without reflection.
If you don't want to use any framework, first step is to write kind of proxy class handling the method requests. It is an example of method processing with annotation use over method:
public class MyProxy {
private <T> T getProxy(T t) {
return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), new Class<?>[]{MyClass.class}, new MyInvocationHandler(t));
}
}
And then implement InvocationHandler:
public class MyInvocationHandler implements InvocationHandler {
private Object obj;
MyInvocationHandler (Object obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
boolean isNotNull = method.isAnnotationPresent(NotNull.class);
if (isNotNull) {
/* process annotated method. Or go through proxy object fields etc.. */
}
}
}
I hope it will help you.
You didn't say what kind of annotation processing you want to do.
Do you want to add a run-time check that will cause your code to crash if list is ever null at run time? For this, reflection will work.
Do you want to add a compile-time check that will reject your code if it cannot prove that list is never null at run time? For this, an annotation processor such as the Checker Framework will work.
Your question does not explain why you don't want to use a framework. Doing so will save you from re-implementing a lot of functionality that others have already created.

How to use Spring MVC #JsonView when returning an object hierarchy from a Rest Controller

I'm building an application which uses Spring MVC 4.10 with jackson 2.3.2.
I have a Project class which has children Proposal objects and a Customer object. These Proposal objects are complex and I want to return a summarized JSON view of them. A similar situation happens with the Customer object. I'm trying to implement this with #JsonView annotations.
I wanted to ask if extending the views of the member object classes in the container object class view is the way to do this or, if not, if there is a cleaner way to implement this that I am unaware of.
Context
Before today, I was under the false impression that you could annotate your controller with multiple views and that the resulting JSON representation would be filtered accordingly.
#JsonView({Project.Extended.class, Proposal.Summary.class, Customer.Summary.class})
#Transactional
#RequestMapping(value="/project", method=RequestMethod.GET)
public #ResponseBody List<Project> findAll() {
return projectDAO.findAll();
}
Where each class had its own JsonView annotations and interfaces
e.g.:
public class Customer {
...
public interface Summary {}
public interface Normal extends Summary {}
public interface Extended extends Normal {}
}
Nevertheless, it is only the first view in the array that gets taken into account. According to https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring
Only one class or interface can be specified with the #JsonView
annotation, but you can use inheritance to represent JSON View
hierarchies (if a field is part of a JSON View, it will be also part
of parent view). For example, this handler method will serialize
fields annotated with #JsonView(View.Summary.class) and
#JsonView(View.SummaryWithRecipients.class):
and the official documentation in http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-jsonview
To use it with an #ResponseBody controller method or controller
methods that return ResponseEntity, simply add the #JsonView
annotation with a class argument specifying the view class or
interface to be used:
So, I ended up extending the views of the members in the view of the container object, like this
#Entity
public class Project {
...
public static interface Extended extends Normal, Proposal.Extended {}
public static interface Normal extends Summary, Customer.Normal {}
public static interface Summary {}
}
and changed my controller to this
#JsonView(Project.Extended.class)
#Transactional
#RequestMapping(value="/project", method=RequestMethod.GET)
public #ResponseBody List<Project> findAll() {
return projectDAO.findAll();
}
This seems to do the trick, but I couldn't find documentation or discussion about this situation. Is this the intended use of JsonViews or is it kind of hackish?
Thank you in advance
-Patricio Marrone
I believe you have configured your views as necessary. The root of the issue is not Spring's #JsonView, but rather Jackson's implementation of views. As stated in Jackson's view documentation:
Only single active view per serialization; but due to inheritance of Views, can combine Views via aggregation.
So, it appears that Spring is simply passing on and adhering to the limitation set in place by Jackson 2.
I use Jersey+Jackson but issued just the same problem.
That's a trick that I'm doing for my application to let me require for several JSON Views during serialization. I bet it is also possible with Spring MVC instead of Jersey, but not 100% sure. It also does not seem to have performance issues. Maybe it is a bit complicated for your case, but if you have large object with big amount of possible views, maybe it's better than doing a lot of inheritance.
So I use the Jackson Filter approach to require several views in serialization. However, I haven't found the way to overcome the issue of putting #JsonFilter("name") above the classes to map, which does not make it so clean. But I mask it in custom annotation at least:
#Retention(RetentionPolicy.RUNTIME)
#JacksonAnnotationsInside
#JsonFilter(JSONUtils.JACKSON_MULTIPLE_VIEWS_FILTER_NAME)
public #interface JsonMultipleViews {}
The filter itself looks like this:
public class JsonMultipleViewsFilter extends SimpleBeanPropertyFilter {
private Collection<Class<?>> wantedViews;
public JsonMultipleViewsFilter(Collection<Class<?>> wantedViews) {
this.wantedViews = wantedViews;
}
#Override
public void serializeAsField( Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer ) throws Exception {
if( include( writer ) ) {
JsonView jsonViewAnnotation = writer.getAnnotation(JsonView.class);
// serialize the field only if there is no #JsonView annotation or, if there is one, check that at least one
// of view classes above the field fits one of required classes. if yes, serialize the field, if no - skip the field
if( jsonViewAnnotation == null || containsJsonViews(jsonViewAnnotation.value()) ) {
writer.serializeAsField( pojo, jgen, provider );
}
}
else if( !jgen.canOmitFields() ) {
// since 2.3
writer.serializeAsOmittedField( pojo, jgen, provider );
}
}
private boolean containsJsonViews(Class<?>[] viewsOfProperty) {
for (Class<?> viewOfProperty : viewsOfProperty) {
for (Class<?> wantedView : wantedViews) {
// check also subclasses of required view class
if (viewOfProperty.isAssignableFrom(wantedView)) {
return true;
}
}
}
return false;
}
#Override
protected boolean include( BeanPropertyWriter writer ) {
return true;
}
#Override
protected boolean include( PropertyWriter writer ) {
return true;
}
}
I can use this filter like this:
public static String toJson( Object object, Collection<Class<?>> jsonViewClasses) throws JsonProcessingException {
// if no json view class is provided, just map without view approach
if (jsonViewClasses.isEmpty()) {
return mapper.writeValueAsString(object);
}
// if only one json view class is provided, use out of the box jackson mechanism for handling json views
if (jsonViewClasses.size() == 1) {
return mapper.writerWithView(jsonViewClasses.iterator().next()).writeValueAsString(object);
}
// if more than one json view class is provided, uses custom filter to serialize with multiple views
JsonMultipleViewsFilter jsonMultipleViewsFilter = new JsonMultipleViewsFilter(jsonViewClasses);
return mapper.writer(new SimpleFilterProvider() // use filter approach when serializing
.setDefaultFilter(jsonMultipleViewsFilter) // set it as default filter in case of error in writing filter name
.addFilter(JACKSON_MULTIPLE_VIEWS_FILTER_NAME, jsonMultipleViewsFilter) // set custom filter for multiple views with name
.setFailOnUnknownId(false)) // if filter is unknown, don't fail, use default one
.writeValueAsString(object);
}
After that, Jersey allows us to add Jersey Filters on the point of running the application (it goes through each endpoint in each Controller in start of application and we can easily bind the Jersey filters at this moment if there is is multiple value in #JsonView annotation above the endpoint).
In Jersey filter for #JsonView annotation with multiple value above endpoint, once it's bint on startup to correct endpoints depending on annotations, we can easily override the response entity with calling that utils method
toJson(previousResponeObjectReturned, viewClassesFromAnnoation);
No reason to provide the code of Jersey Filter here since you're using Spring MVC. I just hope that it's easy to do it the same way in Spring MVC.
The Domain Object would look like this:
#JsonMultipleViews
public class Example
{
private int id;
private String name;
#JsonView(JsonViews.Extended.class)
private String extendedInfo;
#JsonView(JsonViews.Meta.class)
private Date updateDate;
public static class JsonViews {
public interface Min {}
public interface Extended extends Min {}
public interface Meta extends Min {}
//...
public interface All extends Extended, Meta {} // interfaces are needed for multiple inheritence of views
}
}
We can ommit putting Min.class in my case on those fields that are always required not depending on view. We just put Min in required views and it will serialize all fields without #JsonView annotation.
View All.class is required for me since if we have, for example, a specific set of views for each domain class (like in my case) and then we need to map a complex model consisting of several domain objects that both use views approach - some view for object one, but all views for object two, it's easier to put it above endpoint like this:
#JsonView({ObjectOneViews.SomeView.class, ObjectTwoViews.All.class})
because if we ommit ObjectTwoViews.All.class here and require for only ObjectOneViews.SomeView.class, those fields that are marked with annotation in Object Two will not be serialized.

How to validate Tapestry's form fields with values that come from database?

I have a question regarding field validation with values present in the database.
I've been following http://jumpstart.doublenegative.com.au/jumpstart/examples/input/contributingvalidators as a guide, and it's been pretty straightforward for the most parts. However, I've hit a wall of some sort.
I'm trying to make my own validator:
public class UniqueValueProperty extends AbstractValidator<String, String> {
// my validation stuff here
}
This is how I'm trying to contribute it:
public void contributeFieldValidatorSource(MappedConfiguration<String, Validator> configuration) {
configuration.add(UniqueValueProperty.VALIDATION_NAME, new UniqueValueProperty());
}
So, to sum up:
I understand I need to provide a javascript code for client side validation, but I'm not sure how to actually access the DAO and do the check?
Edit:
Validator has a method you override, which does this:
Hook used by components to allow the validator to contribute
additional attributes or (more often) client-side JavaScript
#Override
public void render(Field field, String constraintValue,
MessageFormatter formatter, MarkupWriter writer, FormSupport formSupport) {
formSupport.addValidation(field, VALIDATION_NAME, buildMessage(formatter, field, constraintValue), null);
If I understood it correctly, I can add some javascript code for client-side validation, right? Well, what I'd like to do in that part (dunno if it's possible) is to actually check for some things in my DB using the DAO, or even to pass more (dynamic) paremeters to validator, such as a list of values it should not trigger validation fail on.
Thanks :D
Edit:
Lance, are you suggesting I could do this:
Tapestry.Validator.uniqueValueProperty = function(field, message, constraint) {
field.addValidator(function(value) {
if ((value != null) && (value.trim().length > 0)) {
if (dao.valueExistsInColumn(value, constraint)) {
throw message;
}
}
});
};
where dao variable is injected in my validator object, contributed via addInstance method?
Use configuration.addInstance(name, class) instead of configuration.add(name, instance). Then tapestry will instantiate your validator and inject any dependencies (eg DAOs).
EDIT
eg:
public class MyValidator extends AbstractValidator {
#Inject private Dao dao;
public void render(Field field, String constraintValue, MessageFormatter formatter, MarkupWriter writer, FormSupport formSupport) {
// this is the serverside representation of the field which will be rendered to HTML
Element fieldElement = writer.getElement();
List<String> values= dao.getSomeList(constraintValue);
String valuesAsString = values.toString();
// add an attribute to the DOM, this can be referenced in javascript later
fieldElement.attribute("data-values", valuesAsString);
formSupport.addValidation(...);
}
}
The field will now have a "data-some-list" in the HTML/DOM which your javascript validator can now access. If using jquery, it has built in support for "data-" attributes. eg:
var valuesAsString = $(#someField").data("values");
Or
var valuesAsString = $(#someField").attr("data-values");

Setting a bean value (column) automatically before persisting in Hibernate?

Is there a nice and elegant way to set a bean value (column) before Hibernate persists an entity? Basically I have a field called "modification_date". It's on a bunch of entities. Whenever one of these entities is updated/modified, I'd basically like that field set automatically.
I could write the code in the service layer to set the date every time the object is saved/updated manually...
I also have a Dao Layer. Every Dao extends from a support class that contains a save() method. I could just use reflection and set the value inside of this method. I could check to see if that class has a field with the name "modicationDate", and if it does, set it to new Date().
Is there a better way than this? Or is using my generic save() method the best approach? This is something I'd like to be robust and not have to worry about it ever again. I will be happy knowing that by simply making a "modificationDate" property that this will be taken care of for me automatically from this point on. Using the save() method seems like the best place, but if there's a better way, I'd like to become aware of it.
Checkout event listeners:
#Entity
#EntityListeners(class=LastUpdateListener.class)
public class Cat {
#Id private Integer id;
private String name;
private Calendar dateOfBirth;
#Transient private int age;
private Date lastUpdate;
#PostLoad
public void calculateAge() {
...
}
}
public class LastUpdateListener {
/**
* automatic property set before any database persistence
*/
#PreUpdate
#PrePersist
public void setLastUpdate(Cat o) {
o.setLastUpdate( new Date() );
}
}

Categories

Resources