I'm working with JsonElements and its addProperty method(s). A JsonElement has 4 overloaded addProperty methods which I'd like to compress down into one to make it easier to add properties. This is what I've written up to start, and I'm realizing that the tricky part is going to be figuring out if a string is a Number.
Any thoughts on how to improve this method?
public JsonElementBuilder addProperty(final String property, final Object value)
{
if (parent instanceof JsonObject) {
if (value instanceof Boolean) {
((JsonObject) parent).addProperty(property, (Boolean)value);
} else if (value instanceof Character) {
((JsonObject) parent).addProperty(property, (Character)value);
} else if (value instanceof Number) {
((JsonObject) parent).addProperty(property, (Number)value);
} else if (value instanceof String) {
if (isInteger((String)value))
{
((JsonObject) parent).addProperty(property, (Number)value);
} else {
((JsonObject) parent).addProperty(property, (String)value);
}
}
}
private boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
}
return true;
}
This is a typical scenario where subtype polymorphism helps. Do the following
interface I {
void do();
}
class A implements I { void do() { doA() } ... }
class B implements I { void do() { doB() } ... }
class C implements I { void do() { doC() } ... }
Then you can simply call do() on this.
If you are not free to change A, B, and C, you could apply the visitor pattern to achieve the same.
Can yo explain why you want to do that? Overloaded methods, like you call them, is called Polymorphism, and it´s just a great Java feature that precisely allows you to avoid that kind of code into your methods.
You can make a single call for all the different classes, and Java does the selection of the correct method consuming less resources than your if ... else code...
Thanks to polymorphism -and btw also thanks to inheritance- you can do this:
//Many different types...
boolean boolProp = true;
char charProp = 'a';
int intProp = 12;
double dblProp = 1.50;
String strProp = "Polymorphism rocks!";
//One method name for all types...
jsonElement.addProperty("prop1", boolProp);
jsonElement.addProperty("prop2", charProp);
jsonElement.addProperty("prop3", intProp);
jsonElement.addProperty("prop4", dblProp);
jsonElement.addProperty("prop5", strProp);
So... why the hell do you want to write yourself a method that does something that Java can do itself without any effort and much more efficiently?
Related
I haven't had a lot of practice with patterns and application architecture. In a nutshell, I have to find certain attributes which object features. Some code will better describe task:
IAttribute {
IAttribute analyze(IFunction func);
}
//up to 10 different attributes
ArgumentsAttribute implements Attribute {
Map<String, ArgType> args = new HashMap<>();
IAttribute analyze(IFunction func) {
for (Argument arg : func.getArgs()) {
args.put(arg.getName(), arg.getType());
}
if (!args.isEmpty()) return this;
return null;
}
}
ReturnAttribute implements Attribute {
IAttribute analyze(IFunction func) {
if (func.hasReturn) return this;
return null;
}
}
AttributeAnalyzer {
List<Attributes> analyzeAttributes(IFunction func) {
List<IAttribute> attributes = new ArrayList<IAttribute>();
attributes.add(new ArgumentAttribute());
attributes.add(new ReturnAttribute());
...
for (IAttribute attr : attributes) {
attr = attr.analyze(func);
if (null == attr) attributes.remove(attr);
}
return attributes;
}
}
However, this implementation seems to be a little strange. I don't like the fact that Attribute is sort of holder, but it has to implement method to find itself. In my opinion, the best practice would be an opportunity to overload static methods, but obviously its not possible. In this way, we would separate holder from analyzing logic without adding new abstractions(maybe I am not right).
IAttribute {
static IAttribute analyze();
}
ConcreteAttribute1 {
int x = 0;
static IAttribute analyze() {
...
if (x != 0) return new ConcreteAttribute1();
return null;
}
}
ConcreteAttribute2 {
String s = "";
static IAttribute analyze() {
...
if (!s.equals("")) return new ConcreteAttribute2();
return null;
}
}
AttributeAnalyzer {
List<Attributes> analyzeAttributes() {
List<IAttribute> attributes = new ArrayList<IAttribute>();
attributes.add(ConcreteAttribute1.analyze());
attributes.add(ConcreteAttribute2.analyze());
...
for (IAttribute attr : attributes) {
if (null == attr) attributes.remove(attr);
}
return attributes;
}
}
In addition, I have to filter spoiled Attributes. So, are there any ways of refactoring to make this code looks better?
If you have a distinct analyze function for each concrete attribute, with little or no overlap, then your initial code sample may not be all that bad. However, I would then change the signature of the method to boolean analyze().
If there is more overlap in the way attributes are analyzed then you might consider a single method boolean analyze(IAttribute) inside your AttributeAnalyzer class (or in a dedicated class).
Okay so I have a batch of methods returning boolean values of true/false.
private void saveChangesOnEditButtonActionPerformed(java.awt.event.ActionEvent evt) {
updateMainTabsAccess();
updateUserPaymentTabPermissions();
updateUserRegistrationTabPermissions();
updateUserStudentsTabPermissions();
updateUserFacultyTabPermissions();
updateUserHomePermissions(); //saves any update made on existing user settings/permissions
updateUserInformation(); // sasve any update made on existing user information such as username
}
I would like to know if it's possible for me to check each of the methods' return value through a for-each loop.
I'm thinking of creating a private boolean isUpdateSuccessful() method.
Say like,
private boolean isUpdateSuccessful(){
Boolean a = updateMainTabsAccess();
Boolean b = updateUserPaymentTabPermissions();
//........so on....
Boolean result = (a && b &&...)
return result;
}
Problem is, I don't know if it's possible to put them in an arraylist or component array like
ArrayList<Boolean> listOfMethods = new ArrayList<Boolean>(method1,method2..);
So that I can then check each through a for-each loop
for(Boolean b:listOfMethods){
Boolean successful=true;
successful = (successful && b)
}
My questions are:
1.) How do I extract the return values of these methods and use the methods to initialize the Arraylist.
2.) Using for-each loop, is there any possibility of what I'm trying to do? I none, then what do you suggest I do?
I'd appreciate any answer or suggestion. I simply want to check if every method was successful. I thought of using ?1:0:
Thanks in advance.
If I am you, I would do this. Just a sample code:
private void saveChangesOnEditButtonActionPerformed(java.awt.event.ActionEvent evt) {
if (updateMainTabsAccess()) {
if (updateUserPaymentTabPermissions()) {
if (updateUserRegistrationTabPermissions()) {
...
} else {
// error on update registration
}
} else {
// error on update payment
}
}
With the above style:
You don't execute other methods when the before one fails.
Can have detailed error messages for each error.
You need not to main a collection and iteration.
Why not use a Stream to check the results:
Stream.<Boolean>of(updateMainTabsAccess(),
updateUserPaymentTabPermissions(),
updateUserRegistrationTabPermissions(),
updateUserStudentsTabPermissions(),
updateUserFacultyTabPermissions(),
updateUserHomePermissions(),
updateUserInformation()).allMatch(b -> b);
this way you get rid of short circuit evaluation and also don't need to create method references for each method.
method references
List<Supplier<Boolean>> methods = Arrays.asList(this::updateMainTabsAccess,
this::updateUserPaymentTabPermissions,
...
);
for (Supplier<Boolean> supplier : methods) {
boolean methodResult = supplier.get();
...
}
This can hardly be considered an improvement though...
this will find all method in side your class which is return Boolean after automatically invoke method one by one and store response to successful variable
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
public class Test {
public static void main(String[] args) {
Test test = new Test();
Class c = test.getClass();
boolean successful = true;
for (Method method : c.getDeclaredMethods()) {
if (method.getReturnType().toString().equals("boolean")) {
try {
String mname = method.getName();
Object o = method.invoke(test, null);
System.out.format("%s() returned %b%n", mname, (Boolean) o);
successful = successful && (Boolean) o;
} catch (Exception e) {
e.printStackTrace();
}
}
}
System.out.println("final answer : " + successful);
}
public boolean a() {
return true;
}
public boolean b() {
return false;
}
public boolean c() {
return false;
}
}
Hope its help to you.
If you want every method to be executed and check if every method scucceded you could simply write
boolean success = updateMainTabsAccess() &
updateUserPaymentTabPermissions() &
updateUserRegistrationTabPermissions() &
updateUserStudentsTabPermissions() &
updateUserFacultyTabPermissions() &
updateUserHomePermissions() &
updateUserInformation();
You have already received some answers.
Fabian's is a good one if you are using java 8.
But to answer directly your points
1.) How do I extract the return values of these methods and use the methods to initialize the Arraylist.
ArrayList<Boolean> resultsList = new ArrayList<Boolean>();
resultsList.add(updateMainTabsAccess());
...
2.) Using for-each loop, is there any possibility of what I'm trying to do? I none, then what do you suggest I do?
boolean res = true;
for (Boolean singleResult : resultsList) {
res = res && singleResult;
}
Here is the old style way to acheive your goal when Lambdas weren't introduced by Java 8.
public class TestMethodsListCall {
public abstract class Checker {
public abstract boolean check();
}
public static void main(String[] args) {
new TestMethodsListCall();
}
public TestMethodsListCall() {
final TestMethodsListCall that = this;
List<Checker> checkers = Arrays.asList( //
new Checker() { public boolean check() { return that.methodA(); } }, //
new Checker() { public boolean check() { return that.methodB(); } } //
// , ...
);
boolean res = true;
for (Checker c : checkers) {
res = res & c.check();
if (!res) {
// Break, display some message or all together
}
}
}
public boolean methodA() {
return true;
}
public boolean methodB() {
return false;
}
}
I'm needing to get a unique method identifier to use as a key on a HashMap.
I'm trying to do something using stacktrace and reflection and user the method signature. But the problem is I didn´t find a way to retrive the complete method signature (to avoid methods overload).
Edited
I would like that somethink like this works:
public class Class1 {
HashMap<String, Object> hm;
public Class1() {
hm = new HashMap<String, Object>();
}
public Object method() {
if (!containsKey()) {
Object value;
...
put(value);
}
return get();
}
public Object method(String arg1) {
if (!containsKey()) {
Object value;
...
put(value);
}
return get();
}
public Boolean containsKey() {
if (hm.containsKey(Util.getUniqueID(2)) {
return true;
} else {
return false;
}
}
public void put(Object value) {
hm.put(Util.getUniqueID(2), value);
}
public Object get() {
String key = Util.getUniqueID(2);
if (hm.containsKey(key) {
return hm.get(key);
} else {
return null;
}
}
}
class Util {
public static String getUniqueID(Integer depth) {
StackTraceElement element = Thread.currentThread().getStackTrace()[depth];
return element.getClassName() + ":" + element.getMethodName();
}
}
But the problem is the two methods, with this strategy, will have the same ID.
How can I work around?
You can append + ":" + element.getLineNumber() but you'd still have to worry about the case where two overloaded methods are put on one long line.
Looking at the StackTraceElement methods, it doesn't seem possible to get a unique method identifier this way. Besides, the code is not very readable in my opinion.
I'd suggest you try to be more explicit and do
if (hm.containsKey("getValue(int)") {
...
}
or something similar.
(I was astonished not to be able to find this question already on stackoverflow, which I can only put down to poor googling on my part, by all means point out the duplicate...)
Here is a toy class that returns the reverse of what you put into it. Currently it works on integers, but would require only very minor changes to work for String.
public class Mirror {
int value;
public int get() {
return reverse(value);
}
private int reverse(int value2) {
String valueString = value + "";
String newString = reverse(valueString);
return Integer.parseInt(newString);
}
private String reverse(String valueString) {
String newString = "";
for (char c : valueString.toCharArray()) {
newString = c + newString;
}
return newString;
}
public void set(int value) {
this.value = value;
}
}
What I'd like to do is make the class generic, but only for, say, two or three possible types. So what I want to write is:
public class Mirror<X, where X is one of Integer, String, or MagicValue {
X value
public X get(){
[...]
What's the correct syntax? My Google-fu is failing me... :(
EDIT: it appears there isn't a correct syntax and it can't appear to be done, so my main question is: why? this seems like the sort of thing that people might want to do before they made the class truly generic...
EDIT EDIT: Managed to work out the why with some labmates today, so added the relevant why answer below.
Unfortunately java does not provide such functionality directly. However I can suggest you the following work around:
Create parametrized class Mirror with private constructor and 3 static factory methods that create instance of Mirror with specific parameter:
public class Mirror<T> {
private T value
private Mirror(T value) {
this.value = value;
}
public static Mirror<Integer> integerMirror(Integer value) {
return new Mirror(value);
}
public static Mirror<String> stringMirror(String value) {
return new Mirror(value);
}
public static Mirror<MagicValue> magicMirror(MagicValue value) {
return new Mirror(value);
}
}
EDIT
Obviously you can (and probably should) separate the class Mirror from its creating, e.g. put the factory methods to separate class MirrorFactory. In this case the constructor should become package protected.
If you want to support large yet limited number of classes you can implement only one generic factory method
public static <T> Mirror<T> createMirror(T value) {
checkTypeSupported(value);
return new Mirror(value);
}
Method checkTypeSupported(value); may use some kind of metadatat (e.g. properties, JSON etc file) to get supported types. In this case however you will not enjoy the compile time validation.
Other solution is to require that all supported types extend certain base class or implement interface:
public class Mirror<T extends MyInterface> {}
But this solution seems does not match your requirements since you need Integer, String and MagicValue.
Various ways to do what you need...Here is another option. No getter or setter.
One instance of Mirror for each type to be handled. One reverse() method.
Tweak as necessary. Add error checking/handling.
public class Mirror<T> {
public T reverse(final T value) {
T result = null;
while (true) {
if (value instanceof String) {
System.out.println("Do for String");
result = value;
break;
}
if (value instanceof Integer) {
System.out.println("Do for Integer");
result = value;
break;
}
if (value instanceof JFrame) {
System.out.println("Do for JFrame");
result = value;
break;
}
throw new RuntimeException("ProgramCheck: Missing handler for type " + value.getClass().getSimpleName());
}
return result;
}
Tester:
final Mirror<String> testerString = new Mirror<>();
testerString.reverse("string");
final Mirror<Integer> testerInteger = new Mirror<>();
testerInteger.reverse(41);
testerInteger.reverse(42);
testerInteger.reverse(43);
final Mirror<JFrame> testerJFrame = new Mirror<>();
testerJFrame.reverse(new JFrame());
Results:
Do for String
Do for Integer
Do for Integer
Do for Integer
Do for JFrame
An alternative would be to just accept the fact that you have no control over the type hierarchy of String/Integer and create an interface to give a common type for the classes you do have control over
public int reverse(int value) {
return Integer.valueOf(new StringBuilder(value + "").reverse()
.toString());
}
public String reverse(String value) {
return new StringBuilder(value + "").reverse().toString();
}
public <T extends Reversible> T reverse(T value) {
value.reverse();
return value;
}
public interface Reversible {
public void reverse();
}
And if you only want one instance of the Mirror class...use a generic method.
public class Mirror {
public <T> T reverse(final T value) {
T result = null;
while (true) {
if (value instanceof String) {
System.out.println("Do for String");
result = value;
break;
}
if (value instanceof Integer) {
System.out.println("Do for Integer");
result = value;
break;
}
if (value instanceof JFrame) {
System.out.println("Do for JFrame");
result = value;
break;
}
throw new RuntimeException("ProgramCheck: Missing handler for type " + value.getClass().getSimpleName());
}
return result;
}
tester:
final Mirror tester = new Mirror();
String s = tester.reverse("string");
Integer i41 = tester.reverse(41);
Integer i42 = tester.reverse(42);
Integer i43 = tester.reverse(43);
JFrame j = tester.reverse(new JFrame());
results:
Do for String
Do for Integer
Do for Integer
Do for Integer
Do for JFrame
You can't bound a generic parameter to range of values. You could however restrict it programatically:
public abstract class AbstractMirror<T> {
T value;
protected AbstractMirror(Class<T> clazz) {
if (clazz != Integer.class && clazz != String.class && clazz != MagicValue.class)
throw new IllegalArgumentException();
}
public abstract T get();
protected abstract T reverse(T value);
}
You can use so-called "witness" types to make the compiler do what you want.
public interface Reversible< T > {
public static final class IntReversible implements Reversible< Integer > {}
public static final class StringReversible implements Reversible< String > {}
public static final class MagicReversible implements Reversible< MagicValue > {}
}
public abstract class Mirror< T, R extends Reversible< T > > {
// ...
}
public class IntMirror extends Mirror< Integer, IntReversible > {
// ...
}
However, the reason your example doesn't make any sense is because you gain virtually nothing from using a generic in this context. What possible algorithm will reverse an integer or a string or a MagicValue without resorting to awful run-time type-checking and casting? The code will be all three reverse algorithms, wrapped with a hideous if-ladder.
So here is the why (worked it out at work)
Generics are always from a subclass, although it looks like
Public class Thing<T> {}
will allow any type in there, really what it's saying is that it will allow any subtype of Object. I.e.
Public class Thing<T extends Object> {}
This is effectively working as inheritance, and indeed, the Oracle Website shows us this happening when the syntactic sugar is removed:
In the following example, the generic Node class uses a bounded type
parameter:
public class Node<T extends Comparable<T>> {
private T data;
private Node<T> next;
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
public T getData() { return data; }
// ...
}
The Java compiler replaces the bounded type parameter T with the first
bound class, Comparable:
public class Node {
private Comparable data;
private Node next;
public Node(Comparable data, Node next) {
this.data = data;
this.next = next;
}
public Comparable getData() { return data; }
// ...
}
...and so the answer turns out that the reason you can't limit the types in this way is because it effectively turns into multiple Inheritance, which is nasty, and which I'm happy to avoid....
I am using the Oval validation framework to validate fields that HTML fields cannot hold malicious javascript code. For the malicious code detection, I am using an external framework that returns me a list of errors that I would like to use as error messages on the field. The problem I am running into is that I can only setMessage in the check implementation, while I would rather do something like setMessages(List). So while I am currently just joining the errors with a comma, I would rather pass them back up as a list.
Annotation
#Target({ ElementType.METHOD, ElementType.FIELD})
#Retention( RetentionPolicy.RUNTIME)
#Constraint(checkWith = HtmlFieldValidator.class)
public #interface HtmlField {
String message() default "HTML could not be validated";
}
Check
public class HtmlFieldValidator extends AbstractAnnotationCheck<HtmlDefaultValue> {
public boolean isSatisfied( Object o, Object o1, OValContext oValContext, Validator validator ) throws OValException {
if (o1 == null) {
return true;
} else {
CleanResults cleanResults = UIowaAntiSamy.cleanHtml((String) o1);
if (cleanResults.getErrorMessages().size() > 0) {
String errors = StringUtils.join(cleanResults.getErrorMessages(), ", ");
this.setMessage(errors);
return false;
} else {
return true;
}
}
}
}
Model class
class Foo {
#HtmlField
public String bar;
}
Controller code
Validator validator = new Validator(); // use the OVal validator
Foo foo = new Foo();
foo.bar = "<script>hack()</script>";
List<ConstraintViolation> violations = validator.validate(bo);
if (violations.size() > 0) {
// inform the user that I cannot accept the string because
// it contains invalid html, using error messages from OVal
}
If setMessage(String message) is a method created by a superclass, you can override it and once it receives the data, simply split the string into a list and call a second function in which you would actually place your code. On a side note, I would also recommend changing the separating string to something more unique as the error message itself could include a comma.
Your question doesn't really make much sense though. If you are "passing them back up" to a method implemented in a superclass, then this voids the entire point of your question as the superclass will be handling the data.
I am going to assume the setError methods is a simple setter that sets a String variable to store an error message that you plan to access after checking the data. Since you want to have the data in your preferred type, just create a new array of strings in your class and ignore the superclass. You can even use both if you so desire.
public class HtmlFieldValidator extends AbstractAnnotationCheck<HtmlDefaultValue> {
public String[] errorMessages = null;
public void setErrorMessages(String[] s) {
this.errorMessages = s;
}
public boolean isSatisfied( Object o, Object o1, OValContext oValContext, Validator validator ) throws OValException {
if (o1 == null) {
return true;
} else {
CleanResults cleanResults = UIowaAntiSamy.cleanHtml((String) o1);
if (cleanResults.getErrorMessages().size() > 0) {
//String errors = StringUtils.join(cleanResults.getErrorMessages(), ", ");
//this.setMessage(errors);
this.setErrorMessages(cleanResults.getErrorMessages());
return false;
} else {
return true;
}
}
}
}
Elsewhere:
HtmlFieldValidator<DefaultValue> hfv = new HtmlFieldValidator<DefaultValue>();
boolean satisfied = hfv.isSatisfied(params);
if (!satisfied) {
String[] errorMessages = hfv.errorMessages;
//instead of using their error message
satisfy(errorMessages);//or whatever you want to do
}
EDIT:
After you updated your code I see what you mean. While I think this is sort of overdoing it and it would be much easier to just convert the string into an array later, you might be able to do it by creating a new class that extends Validator its setMessage method. In the method, you would call super.setMethod as well as splitting and storing the string as an array in its class.
class ValidatorWithArray extends Validator {
public String[] errors;
public final static String SPLIT_REGEX = ";&spLit;";// Something unique so you wont accidentally have it in the error
public void setMessage(String error) {
super.setMessage(error);
this.errors = String.split(error, SPLIT_REGEX);
}
}
In HtmlFieldValidator:
public boolean isSatisfied( Object o, Object o1, OValContext oValContext, Validator validator ) throws OValException {
if (o1 == null) {
return true;
} else {
CleanResults cleanResults = UIowaAntiSamy.cleanHtml((String) o1);
if (cleanResults.getErrorMessages().size() > 0) {
String errors = StringUtils.join(cleanResults.getErrorMessages(), ValidatorWithArray.SPLIT_REGEX);
this.setMessage(errors);
return false;
} else {
return true;
}
}
}
And now just use ValidatorWithArray instead of Validator
The situation in which I want to achieve this was different from yours, however what I found was best in my case was to create an annotation for each error (rather than having one that would return multiple errors). I guess it depends on how many errors you are likely to be producing in my case it was only two or three.
This method makes also makes your code really easy to reuse as you can just add the annotations wherenever you need them and combine them at will.