Comments (17)
First comments that come to my mind. The ultimate goal of PODAM is to fill a POJO state. The strict adherence to JavaBean standards (although we've relaxed it quite a bit already by filling Immutable classes and, where possible, attributes without a setter) allows us to set only attributes. Even in the case above ultimately you want to fill Holder's attributes, only through outer setter methods. Now, one way that we could achieve that would be to invoke all setters in a POJO regardless. But here I think there might lie the problem. What would happen if someone wrote a setter that is not actually a setter and has some nasty side effects? Consider the following case:
public class Pojo {
private String string1;
private String string2;
public setString1(String string) {...}
public setString2(String string) {...}
public setInitialStatus(Bombshell bomb) {
bomb.ignite(); //This could have any sort of side effect
}
}
If we were to relax the Javabean rules, Podam would first set string1 and string2 and then ignite a bomb. One could ask: "Why would anyone write code like that?" and the answer is probably no one but that kind of proves my point. Podam is a framework and as such it doesn't have to know whether users write good or bad code. It needs to always work regardless of sensible or meaningless code. The adherence to Javabean standards is a contract between Podam and its users so that it can always fulfil its mission, which is to set a POJO's internal state.
How would you suggest Podam deals with the above situation?
from podam.
That's one of the two things that came to mind PODAM
will have to deal with from its perspective.
- What if the setter wasn't a
Java Bean
style setter? Like what if accepted 2 or more parameters and returned something? I mean, although that's bad code, it's still writable, soPODAM
will have to deal with it. I thinkPODAM
deals with such cases well already - it ensures the setter signature matches that of the traditional setter before invoking, so there's no problem with this. - What if the setter had invariants, especially dangerous ones at that throwing exceptions/errors if the parameter wasn't what the setter was expecting it to be (guess
@PodamExclude
or theDataProviderStrategy
would help here) or bad code (like your bombshell example)? The one solution I can think of (if there wasn't an explicit matching instance field, of course) is extending@PodamExclude
to methods so that the user can specify the annotation on setter they wantPODAM
to not mess with. My point is, such a not-so-sensible code could as well be written in aJava Bean
with an explicitly standard instance field, soPODAM
must already be running that risk and expecting user's intervention in such cases thru the@PodamExclude
annotation or theDataProviderStrategy
on the field that they wantPodam
to handle the way they expect it to.
But then if PODAM
had to deviate too much from its principle of keeping it simple and expecting types to strictly adhere to the Java Bean
standards, I guess it should be fine to not relax this.
from podam.
Maybe what we could do is to provide Podam with an additional list of
methods to invoke. We're already doing something similar by allowing users
to define, for example, a list of fields to exclude. So similarly we could
have an extendedMethods collection containing a list of additional methods
to execute and stick that to the Classinfo class.
Daniil what do you think?
On Saturday, April 11, 2015, mystarrocks [email protected] wrote:
That's one of the two things that came to mind PODAM will have to deal
with from its perspective.
What if the setter wasn't a Java Bean style setter? Like what if
accepted 2 or more parameters and returned something? I mean, although
that's bad code, it's still writable, so PODAM will have to deal with
it. I think PODAM deals with such cases well already - it ensures the
setter signature matches that of the traditional setter before invoking, so
there's no problem with this.What if the setter had invariants, especially dangerous ones at that
throwing exceptions/errors if the parameter wasn't what the setter was
expecting it to be (guess @PodamExclude or the DataProviderStrategy
would help here) or bad code (like your bombshell example)? The one
solution I can think of (if there wasn't an explicit matching instance
field, of course) is extending @PodamExclude to methods so that the
user can specify the annotation on setter they want PODAM to not mess
with. My point is, such a not-so-sensible code could as well be written in
a Java Bean with an explicitly standard instance field, so PODAM must
already be running that risk and expecting user's intervention in such
cases thru the @PodamExclude annotation or the DataProviderStrategy on
the field that they want Podam to handle the way they expect it to.But then if PODAM had to deviate too much from its principle of keeping
it simple and expecting types to strictly adhere to the Java Bean
standards, I guess it should be fine to not relax this.—
Reply to this email directly or view it on GitHub
#86 (comment).
from podam.
I will speak about Podam 5.2.1-SNAPSHOT version. In 5.2.0 this is also possible, but code will be slightly different.
So what is between you and the success is AbstractClassInfoStrategy.approve()
method, part of ClassInfoStrategy
, which implements POJO introspection
public boolean approve(ClassAttribute attribute) {
return (attribute.getAttribute() != null);
}
It skips all setters, which has no field, because Java contains lots of classes with setters, which breaks PODAM production.
So what you need to do is to use custom ClassInfoStrategy
. For example, like this:
private static ClassInfoStrategy classInfoStrategy
= new AbstractClassInfoStrategy() {
@Override
public boolean approve(ClassAttribute attribute) {
/* EJB attributes: field and setter */
if (attribute.getAttribute() != null) {
return true;
}
/* Exclusion for SpecialPojo class */
for (Method setter : attribute.getSetters()) {
if (SpecialPojo.class.equals(setter.getDeclaringClass())) {
return true;
}
}
return false;
}
};
Use this strategy with Podam factory
PodamFactory podam = new PodamFactoryImpl().setClassStrategy(classInfoStrategy);
And then attributes get filled:
SpecialPojo pojo = podam.manufacturePojo(SpecialPojo.class);
Assert.assertNotNull("Construction failed", pojo);
Assert.assertNotNull("Attr should not be empty", pojo.getMyString());
I hope this helps.
from podam.
Daniil, I think what we need is an extraMethods concept where users can add the extra methods they want to execute. These might not only be setters but any method really. I’ve created a local branch issue-86 and I’m trying to implement this concept there.
Regards,
On 12 Apr 2015, at 14:18, Daniil Ivanov [email protected] wrote:
I will speak about Podam 5.2.1-SNAPSHOT version. In 5.2.0 this is also possible, but code will be slightly different.
So what is between you and the success is AbstractClassInfoStrategy.approve() method, part of ClassInfoStrategy, which implements POJO introspection
public boolean approve(ClassAttribute attribute) {
return (attribute.getAttribute() != null);
}
It skips all setters, which has no field, because Java contains lots of classes with setters, which breaks PODAM production.So what you need to do is to use custom ClassInfoStrategy. For example, like this:
private static ClassInfoStrategy classInfoStrategy
= new AbstractClassInfoStrategy() {@Override public boolean approve(ClassAttribute attribute) { /* EJB attributes: field and setter */ if (attribute.getAttribute() != null) { return true; } /* Exclusion for NonEJBPojo class */ for (Method setter : attribute.getSetters()) { if (NonEJBPojo.class.equals(setter.getDeclaringClass())) { return true; } } return false; }
};
Use this strategy with Podam factoryPodamFactory podam = new PodamFactoryImpl().setClassStrategy(classInfoStrategy);
And then attributes get filled:SpecialPojo pojo = podam.manufacturePojo(SpecialPojo.class); Assert.assertNotNull("Construction failed", pojo); Assert.assertNotNull("Attr should not be empty", pojo.getMyString());
I hope this helps.
—
Reply to this email directly or view it on GitHub #86 (comment).
from podam.
Well, PODAM already can do it for such simple case. But I see your proposal extremely valuable for another type of beans, those, which have post construction initialization, for example, like this:
package uk.co.jemos.podam.test.dto;
import java.net.MalformedURLException;
import java.net.URL;
import javax.annotation.PostConstruct;
/**
* POJO , with post construction initialization
*/
public class PostConstructPojo {
private URL url;
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@PostConstruct
public void init() throws MalformedURLException {
url = new URL(value);
}
@Override
public String toString() {
return url.toString();
}
}
from podam.
True, my example was maybe too simple to demonstrate the exact need and PODAM
is definitely capable of handling such cases already. My point was to be able to specify ad-hoc methods to be executed that might affect the state in a desired yet subtle way, not necessarily just the setters like Marco pointed out.
from podam.
This has now been implemented in 5.3.1-SNAPSHOT, however Daniil is going to improve my initial commit. Once completed, we’ll be releasing 5.3.1.RELEASE and it’ll be available on Maven central.
Regards,
On 12 Apr 2015, at 18:28, mystarrocks [email protected] wrote:
True, my example was maybe too simple to demonstrate the exact need and PODAM is definitely capable of handling such cases already. My point was to be able to specify ad-hoc methods to be executed that might affect the state in a desired yet subtle way, not necessarily just the setters like Marco pointed out.
—
Reply to this email directly or view it on GitHub #86 (comment).
from podam.
Cheers guys, that was quick!
from podam.
Fixed in 5.3.0-SNAPSHOT. Will be released in 5.3.0.RELEASE
from podam.
Something like this
daivanov@e9ab2c5
PoDaM user will need to have only these two lines in her/his code:
classInfoStrategy.addExtraMethod(ExtraMethodsPojo.class, "setMyString", String.class);
classInfoStrategy.addExtraMethod(ExtraMethodsPojo.class, "setMyLong", Long.class);
from podam.
Perfect! Could you please update also the website docs?
On Tuesday, April 14, 2015, Daniil Ivanov [email protected] wrote:
Something like this
daivanov/joinmo@e9ab2c5
daivanov@e9ab2c5PoDaM user will need to have only these two lines in her/his code:
classInfoStrategy.addExtraMethod(ExtraMethodsPojo.class, "setMyString", String.class);
classInfoStrategy.addExtraMethod(ExtraMethodsPojo.class, "setMyLong", Long.class);—
Reply to this email directly or view it on GitHub
#86 (comment).
from podam.
Sure!
from podam.
Does this solution accept more than one argument?
On Tuesday, April 14, 2015, Daniil Ivanov [email protected] wrote:
Something like this
daivanov/joinmo@e9ab2c5
daivanov@e9ab2c5PoDaM user will need to have only these two lines in her/his code:
classInfoStrategy.addExtraMethod(ExtraMethodsPojo.class, "setMyString", String.class);
classInfoStrategy.addExtraMethod(ExtraMethodsPojo.class, "setMyLong", Long.class);—
Reply to this email directly or view it on GitHub
#86 (comment).
from podam.
It's variable length arguments list. What worries me, now ExtraMethodExecutorData encapsulates only java.reflect.Method and nothing else. It's good for extension, but from lean development point of view this is waste.
from podam.
We can remove it and use simply Method?
On Tuesday, April 14, 2015, Daniil Ivanov [email protected] wrote:
It's variable length arguments list. What worries me, now
ExtraMethodExecutorData encapsulates only java.reflect.Method and nothing
else. It's good for extension, but from lean development point of view this
is waste.—
Reply to this email directly or view it on GitHub
#86 (comment).
from podam.
Now it's released. I noticed one more thing: extra methods are places into HashSet, thus, their execution order is not guaranteed. I believe some users might find it useful as List, when they can be sure in which order extra methods will be invoked.
from podam.
Related Issues (20)
- fails to generate collection for kotlin pojo with default parameters HOT 6
- Optional<List<String>> generated as Optional<List<Object>> HOT 2
- can't set value if property is a single letter with number HOT 1
- Can't generate object when same generic placeholder is used for multiple fields
- attributeMetadata.getAttributeName() is not returning the field name on Inmutable Objects HOT 2
- Podam might produce value out of the range, if only @Min or @Max is present on byte,short,int,long field HOT 1
- CharSequence are not instanciated by default PodamFactory HOT 3
- Add support for @Email with BeanValidationStrategy HOT 5
- manufacturePojoWithFullData issue with Instant HOT 4
- private and protected fields HOT 3
- attributeClassStrategies are not implemented completly HOT 1
- jakarta.validation.constraints.Email annotation not working with Strategy HOT 7
- Fields annotated with @Email generated as null HOT 3
- Replace dependencies for javax with jakarta HOT 3
- String is generated twice HOT 1
- Global Data Provider Strategy not working, neither custom TypeManufacturers (seems to be the same issue) HOT 5
- Complete PodamAnnotation Target value to allow lombok full usage HOT 6
- Compilation with bzlmod HOT 4
- Add support for @FutureOrPresent, @PastOrPresent constraint annotations and java.time.* classes as target attributes HOT 5
- Value with @Lengh annotation being left to null HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from podam.