Iterating through method parameters - java

It's a simple and maybe trivial question: in Java how can I iterate through the parameters passed to the method where I'm working?
I need it to trim() all of them that are strings.
EDIT
To be more precise an example of use can be this (written in a pseudo-code reflecting how I wish it to work):
public void methodName(String arg1, int arg2, int arg3, String arg4, double arg5)
for(Object obj : getThisMethod().getParameters() )
System.out.println(obj.getName() + " = " + obj.toString())
The point is that getThisMethod().getParameters(). What must I write in that place?

If your function uses Varargs this is pretty straightforward:
private void yourFunction(String... parameters) {
for (String parameter : parameters) {
// Do something with parameter
}
}

Individual parameters aren't iterable; you'd need a collection for that.
You'll just have to get a shovel if they're individual Strings.
If you have so many String parameters that this is oppressive, perhaps your method needs to be re-thought. Either all those parameters should be encapsulated into an object, because they're related, or that method is trying to do too much. It speaks to a lack of cohesion to me.

The task you are trying solve is only possible using AOP (Aspect Oriented Programming) frameworks.
AOP frameworks allow you to add some code to the method without changing it. In reality they create Proxy classes that wrap around your original classes and execute required lines of code before each method you bind them too.
However, AOP is an overkill for some simple tasks as it usually requires some complex configurations and usually integration with DI frameworks.
Here's some list of AOP frameworks if you are still interested: http://java-source.net/open-source/aspect-oriented-frameworks.
Edit:
Actually, I think that you are doing your task the wrong way in first place. If your method is a part of Business Layer - it should not allow non-trimmed parameters and throw some kind of Exception in that case. If your method is part of some Presentation Layer - it should be cleaning the parameters manually, usually near the part where it reads the parameters from the user.
For example, if you are reading that parameters from some Swing form, then you should trim them before passing to your Constructor. For example:
Your current code:
int someId = Integer.valueOf(idField.getText());
String someName = nameField.getText();
String someArg = argField.getText();
new Constructor(someId, someName, someArg)
How it should be handled:
int someId = Integer.valueOf(idField.getText());
String someName = nameField.getText().trim();
String someArg = argField.getText().trim();
new Constructor(someId, someName, someArg)

For you can change your method to be the following you can iterate over them.
public void method(String... args)

If your question is how to recognise a String from an Object, you can do that:
if (myObject instanceof String) {
// My param is a string!
}

Related

Designing Services with different types of parameters java

I am working on designing a common Service interface for atleast 5 concrete implementations. Now all these services require different types of inputs. I thought of creating a Param class to hold parameters, so that interface could remain common. but then, for some implementations, some of the fields will be unused. I also thought of using Map to hold my params, but that is also not good(casts and if-elses everywhere). Also, I thought of doing was to create a class with Static methods Service.responseAsPerFirstImplementation(p1, t1, i1) and such. But, this way is not good coding. Please suggest how I should design between Modular design, flexibility vs variability of parameters?
EDIT:
Is below the good way of doing it?
public class Client {
public static void main(String[] args) {
System.out.println(Services.response(new UserParam(1, new Date())));
System.out.println(Services.response(new PatternParam("core")));
}
}
I think the core of the question is if your parameters come from some "generic", unstructured sourcelike HTTP request parameters or command line arguments or some structured source - I would put a Swing form there as you know in advance which UI elements you have.
In case of "generic" parameters you have to convert these parameters into something your services can process. You can do this manually or with some library/framework. For instance, you can use annotations to describe how your HTTP request and its parameters map to your controllers/services/methods:
#RestController
#RequestMapping("/trainRun")
public class TrainRunController {
#RequestMapping(value = "/{year}/{month}/{day}/{trainNumber}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public TrainRun getTrainRun(#PathVariable Integer year, #PathVariable Integer month, #PathVariable Integer day,
#PathVariable String trainNumber) { ... }
}
Similarly with command-line parameters - you can use somethings like args4j to map CLI parameters into Java object first and then call your services appropriately.
Hope this helps.

Mockito control output returned based off input

I have issue where when I use Java parallelStream instead of stream my tests fail. This happens because I am returning Mock objects in a strict order rather than controlling Mock objects returned based on input.
The following is my current code used to return mocks objects:
when(myOperation.getSomething(any(String.class)))
.thenAnswer(AdditionalAnswers.returnsElementsOf(aListOfThings)));
How can I concisely control the return value based off the argument I am passing to "getSomething"?
You can do something like that:
when(myOperation.getSomething(any(String.class))).thenAnswer(new Answer<SomeThing>() {
#Override
public SomeThing answer(final InvocationOnMock invocation) throws Throwable {
// HERE ====> use invocation.getArguments()
return new SomeThing();
}
});
Here the answer return a SomeThing instance, you will need to adjust to your needs
Some reading:
Java 8 custom answer support
doAnswer documentation
InvocationOnMock javadoc
Instead of using an Answer, you can just iterate across your values and set up specific stubs for each one. Unlike with an Answer, you have to be able to predict all values for which you're stubbed, but for your particular case here it sounds like that might not be a problem.
for (int i = 0; i < aListOfThings.size(); i++) {
when(myOperation.getSomething(aListOfKeys.get(i)))
.thenReturn(aListOfThings.get(i));
}

log all the attribute changes of a Class

For debugging purposes I need to keep track of a Class attributes changes.
For example consider the following class:
class Test {
int myInt;
String myString;
...
public void setMyInt(int a) ...
public void setMyString(String s) ...
public printDebugLog();
}
void main() {
Test t = new Test();
t.setMyInt(5);
t.setMyString("Hello");
t.printDebugLog();
}
I want to output to be something like:
myInt => 5
myString => Hello
The easy solution is to create logs instantly. i.e. adding a Log function as follow:
void Log(String s) {
System.out.println(s);
}
and then code the set functions like below:
void setMyString(String s) {
myString = s;
Log("myString => " + s);
}
this requires all the set functions to be written variously and I wonder if there are any better solution for such matter. For example it might be easier (if possible) to create a SetValue function which accepts two variables and set the first attribute to the value of the second object. or something like this.
Any idea?
To do this you should wrap your class with orthogonal code that performs logging.
Since your class does not implement interface you cannot use dynamic proxy, so you have to use one of solutions that use byte code engineering.
The strongest solution I know is AspectJ. But probably you even do not need it. You can use Javassist or CGLIb - the byte code engineering libraries that allow creating proxies that wrap classes, so you can add code that performs logging.
You can use AOP to intercept the setter methods and log when they are called. A quick google should give you a few examples.
If you debug via JPDA,
you can create a Breakpoint
on a field you like to watch.

Conditional generation of method bodies to satisfy large interfaces in Java

The Java OpenGL GL interface contains about 2000 methods, for debugging purposes I would like to wrap an instance and delegate calls to it while doing some logging. The logging code can be pushed to the same method in each case, so the task of writing out the method implementations looks like it could be automated. An example of what I am trying to do:
import javax.media.opengl.GL;
public class GLErrorLogger implements GL {
private final GL backing;
public GLErrorLogger(GL delegateToMe) {
backing = delegateToMe;
}
private void checkErrorCode() {
// Log frame and thread details depending on gl state
}
/**
* Example of a method
*/
#Override
public int glGenLists(int arg0) {
checkErrorCode();
int retVal = backing.glGenLists(arg0);
checkErrorCode();
return retVal;
}
// rest of methods here...
}
In other words copy the method name and parameters (minus their types) into a call on the backing object, surround with calls to the logging method, and if there is a return type then assign the result to a variable of this type and return it at the end of the method.
I looked at creating a one shot eclipse code template to autogenerate the methods, but there wasn't an immediately obvious way to do pattern matching on the return type. Can anyone suggest a way to do this in Eclipse or any of its code generation tools to save me pulling out the regex toolkit?
You might want to use an Aspect to create the necessary bytecode for you instead of producing all the source code. Take a look at the Traceing Aspect example here: Traceing Aspect Example.
As an Alternative, you can create a Java Dynamic Proxy, if you do not want to use AspectJ as Thrid party Library. Please refer to Dynamic Proxy Tutorial
Use JDK proxies as suggested, or: use a Mock Framework like EasyMock or Mockito.
GL mock = EasyMock.createMock(GL.class);
EasyMock.expect(mock.someMethod()).andReturn(someValue);
// or, if you need to do more computing:
EasyMock.expect(mock.someOtherMethod()).andAnswer(new IAnswer<String>() {
public String answer() throws Throwable {
return "some value you calculate here";
}
});
EasyMock.replay(mock);
now you can use the mock Object for all methods you configured.
See the EasyMock readme for more info.

Good practice to validate immutable values objects

Suppose a MailConfiguration class specifying settings for sending mails :
public class MailConfiguration {
private AddressesPart addressesPart;
private String subject;
private FilesAttachments filesAttachments;
private String bodyPart;
public MailConfiguration(AddressesPart addressesPart, String subject, FilesAttachments filesAttachements,
String bodyPart) {
Validate.notNull(addressesPart, "addressesPart must not be null");
Validate.notNull(subject, "subject must not be null");
Validate.notNull(filesAttachments, "filesAttachments must not be null");
Validate.notNull(bodyPart, "bodyPart must not be null");
this.addressesPart = addressesPart;
this.subject = subject;
this.filesAttachements = filesAttachements;
this.bodyPart = bodyPart;
}
// ... some useful getters ......
}
So, I'm using two values objects : AddressesPart and FilesAttachment.
Theses two values objects have similar structures so I'm only going to expose here AddressesPart :
public class AddressesPart {
private final String senderAddress;
private final Set recipientToMailAddresses;
private final Set recipientCCMailAdresses;
public AddressesPart(String senderAddress, Set recipientToMailAddresses, Set recipientCCMailAdresses) {
validate(senderAddress, recipientToMailAddresses, recipientCCMailAdresses);
this.senderAddress = senderAddress;
this.recipientToMailAddresses = recipientToMailAddresses;
this.recipientCCMailAdresses = recipientCCMailAdresses;
}
private void validate(String senderAddress, Set recipientToMailAddresses, Set recipientCCMailAdresses) {
AddressValidator addressValidator = new AddressValidator();
addressValidator.validate(senderAddress);
addressValidator.validate(recipientToMailAddresses);
addressValidator.validate(recipientCCMailAdresses);
}
public String getSenderAddress() {
return senderAddress;
}
public Set getRecipientToMailAddresses() {
return recipientToMailAddresses;
}
public Set getRecipientCCMailAdresses() {
return recipientCCMailAdresses;
}
}
And the associated validator : AddressValidator
public class AddressValidator {
private static final String EMAIL_PATTERN
= "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*#[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
public void validate(String address) {
validate(Collections.singleton(address));
}
public void validate(Set addresses) {
Validate.notNull(addresses, "List of mail addresses must not be null");
for (Iterator it = addresses.iterator(); it.hasNext(); ) {
String address = (String) it.next();
Validate.isTrue(address != null && isAddressWellFormed(address), "Invalid Mail address " + address);
}
}
private boolean isAddressWellFormed(String address) {
Pattern emailPattern = Pattern.compile(EMAIL_PATTERN);
Matcher matcher = emailPattern.matcher(address);
return matcher.matches();
}
}
Thus, I have two questions :
1) If for some reasons, later, we want to validate differently an address mail (for instance to include/exclude some aliases matching to existing mailingList), should I expose a kind of IValidator as a constructor parameter ? like the following rather than bringing concrete dependence (like I made):
public AddressValidator(IValidator myValidator) {
this.validator = myValidator;
}
Indeed, this will respect the D principle of SOLID principle : Dependency injection.
However, if we follow this logical, would a majority of Values Objects own an abstract validator or it's just an overkill the most of time (thinking to YAGNI ?) ?
2) I've read in some articles than in respect of DDD, all validations must be present and only present in Aggregate Root, means in this case : MailConfiguration.
Am I right if I consider that immutable objects should never be in an uncohesive state ? Thus, would validation in constructor as I made be preferred in the concerned entity (and so avoiding aggregate to worry about validation of it's "children" ?
There's a basic pattern in DDD that perfectly does the job of checking and assembling objects to create a new one : the Factory.
I've read in some articles than in respect of DDD, all validations
must be present and only present in Aggregate Root
I strongly disagree with that. There can be validation logic in a wide range of places in DDD :
Validation upon creation, performed by a Factory
Enforcement of an aggregate's invariants, usually done in the Aggregate Root
Validation spanning accross several objects can be found in Domain Services.
etc.
Also, I find it funny that you bothered to create an AddressesPart value object -which is a good thing, without considering making EMailAddress a value object in the first place. I think it complicates your code quite a bit because there's no encapsulated notion of what an email address is, so AddressesPart (and any object that will manipulate addresses for that matter) is forced to deal with the AddressValidator to perform validation of its addresses. I think it shouldn't be its responsibility but that of an AddressFactory.
I'm not quite sure if I follow you 100%, but one way to handle ensuring immutable objects are only allowed to be created if they are valid is to use the Essence Pattern.
In a nutshell, the idea is that the parent class contains a static factory that creates immutable instances of itself based on instances of an inner "essence" class. The inner essence is mutable and allows objects to be built up, so you can put the pieces together as you go, and can be validated along the way as well.
The SOLID principals and good DDD is abided by since the parent immutable class is still doing only one thing, but allows others to build it up through it's "essence".
For an example of this, check out the Ldap extension to the Spring Security library.
Some observations first.
Why no generics? J2SE5.0 came out in 2004.
Current version of Java SE has Objects.requiresNonNull as standard. Bit of a mouthful and the capitalisation is wrong. Also returns the passed object so doesn't need a separate line.
this.senderAddress = requiresNonNull(senderAddress);
Your classes are not quite immutable. They are subclassable. Also they don't make a safe copy of their mutable arguments (Sets - shame there aren't immutable collection types in the Java library yet). Note, copy before validation.
this.recipientToMailAddresses = validate(new HashSet<String>(
recipientToMailAddresses
));
The use of ^ and $ in the regex is a little misleading.
If the validation varies, then there's two obvious (sane) choices:
Only do the widest variation in this class. Validate more specifically in the context it is going to be used.
Pass in the validator used and have this as a property. To be useful, client code would have to check and do something reasonable with this information, which is unlikely.
It doesn't make a lot of sense to pass the validator into the constructor and then discard it. That's making the constructor overcomplicated. Put it in a static method, if you must.
The enclosing instance should check that its argument are valid for that particular use, but should not overlap with classes ensuring that they are generally valid. Where would it end?
Although an old question but for anyone stumbling upon the subject matter, please keep it simple with POJOs (Plain Old Java Objects).
As for validations, there is no single truth because for a pure DDD you need to keep the context always in mind.
For example a user with no credit card data can and should be allowed to create an account. But credit card data is needed when checking out on some shopping basket page.
How this is beautifully solved by DDD is by moving the bits and pieces of code to the Entities and Value Objects where it naturally belong.
As a second example, if address should never be empty in the context of a domain level task, then Address value object should force this assertion inside the object instead of using asking a third party library to check if a certain value object is null or not.
Moreover Address as a standalone value object doesn't convey much at its own when compared with ShippingAddress, HomeAddress or CurrentResidentialAddress ... the ubiquitous language, in other words names convey their intent.

Categories

Resources