Is it possible to access other class method without passing method parameter - java

I have scenario where i want to access another class method which is returning something.
The method in another class is expecting parameter
Example:
public class Class1()
{
public Response postResponse(String getURL,DataTable dataTable)
{
/*..
my post request code here
..*/
return postData;
}
}
public class Class2()
{
public void readPostResponse()
{
/*..
here i want to access Class1.postResponse method and I don't want to pass the
parameter..
..*/
}
}
Please let me know how to achieve this.

You have three choices:
pass parameters. This is preferred way. Because parameters of method contains some info that can be used in method
mock or stub your parameters if it is possible. It looks like you are using Selenium, but Selenium starts a real browser
pass null parameters.It is not really preferred way because your method can work incorrectly without necessary data

I started to write this before #StepUp posted his answer. I am going to cover the way I think it should be done based on what I understood by "I don't want to pass the parameter"
It sounds you want to create a default case. This example is arbitrary since your code is not really specific. In general terms, when talking about functions, a default case for a function is a method with the same name, with no parameter list. For example,
public class Class1
{
/**
* Default case
*/
public Response postResponse()
{
// Some code here
}
/**
* Specific case (the ellipsis means some parameter list)
*/
public Response postResponse(...)
{
// Some code here
}
}
In your case, you may want to create a default step definition that you can invoke independently in a specific scenario, or you may want to call it from the same scenario with or without parameters specified in your data table. You can still take the same approach. I want to mention that having a default case, doesn't mean that you absolutely need to pass null parameters. 99% of the time, this is a bad idea. All you need to do is to pass some default values.
public class Class1
{
/**
* Default case
*/
public Response postResponse()
{
String url = "..."; // maybe a base URL here?
Object col1 = ...;
Object col2 = ...;
handlePostResponse(url, col1, col2);
// Do other stuff?
return response;
}
/**
* Specific case
*/
public Response postResponse(String url, DataTable dataTable)
{
// Iterate through data table and call handlePostResponse for each row
return response;
}
// This method wraps how to handle post response. The ellipsis might be the elements of the data table
private void handlePostResponse(String url, Object col1, Object col2)
{
// Do something
}
}
Now that you have this, you can call your method in Class 2 that needs to invoke the default case in Class 1.
public class Class2
{
public void readPostResponse()
{
Class1 clazz1 = new Class1();
Response resp = clazz1.postResponse(); // calling no parameters (default) case (you may not need to get the response object (ignore it altogether)
// Do more stuff?
}
}
Remember that every time you pass null to a function or return null from a function, you may have to do some sort of input or output validation to ensure the object about to be used to invoke other methods is not null. Not doing so will result in Null Pointer Exceptions.
One last note: I am using Object merely for illustration. In your case, it will be whatever type of object each column represent. Most likely, it will be String, but it could also be a number wrapper (i.e. Integer) or some custom data type you might've created for your scenario(s).

Related

Interface that extracts a boolean or String

So I have a data class that is somewhat laid out as:
class MyData {
String str1,str2,str3;
Boolean bool1,bool2;
}
The attributes are to be populated based upon a String input, something like:
public void populate(String s) {
if(s.contains("somevalue") myData.setStr1("xxx");
if(s.constains("something else") myData.setBool1(true);
else myData.setBool1(false);
}
This is, of course, a pretty horrible way to do things as s.contains are actually some pretty hairy conditions, so instead I defined an interface:
public interface DataFinderInterface {
public String findStringData(final String input);
public Boolean findBooleanData(final String input);
}
Therefore the populate method could be rewritten as:
public void populate(String s) {
myData.setStr1(str1Finder.findStringData(s));
myData.setBool1(bool1Finder.findBooleanData(s);
}
The implementations of this interface either define a findStringData or a findBooleanData, which is quite unsatisfying. The populate method needs to know if we are expecting to use the findStringData method or the findBooleanData method.
Is there a better way to do this? Am I being overly picky, because the populate method needs to know what instance of DataFinderInterface to assign to what field anyway?
A single findData method returning a String should be sufficient: the code that processes Booleans can put a call to Boolean.getBoolean() on top of it:
public interface DataFinderInterface {
public String findData(final String input);
}
...
myData.setBool1(Boolean.getBoolean(bool1Finder.findData(s));
The problem with the above (or ONE of the problems) is that you are always calling setStr1 AND setBool1 and I assume you will be calling all of the others as well.
If you MUST use something like the above pattern you might want to consider having MyData hold AtomicRefernce<String> and AtomicReference<Boolean>. Then have getSettableString and getSettableBoolean methods that returns the appropriate reference or null if no match.
If it is only the interface method signature you are worried about this could be solved using generics. However it does seem a little weird to initialize an object from a string that way. Perhaps if you add more details about what problem you are trying to solve, there might be a better solution.
public interface DataFinder<T> {
public T findData(final String input);
}
DataFinder<String> str1Finder = new ... // a class implementing DataFinder<String>
DataFinder<Boolean> bool1Finder = new ... // a class implementing DataFinder<Boolean>
public void populate(String s) {
myData.setStr1(str1Finder.findData(s));
myData.setBool1(bool1Finder.findData(s);
}
Consider using regular expressions to extract the data you need from the input string. I would leave the MyData class as a simple data container and build a separate class for populating it - for example, a MyDataBuilder. This class could use string matching in order to extract the fields and populate them on the object.

Dynamically Return a Class of a Type Determined During a Method Call via Class.forName()

I know that I can dynamically determine the return type of a method by passing in a class and then declaring that class as the return type, as in the following example:
public static <returnType> returnClass dynamicConstructor (Class<returnType> returnClass){
//Dynamically construct an object using a zero parameter constructor
return (returnClass) object;
}
The code that would be called would be:
DynamicConstructor.construct(constructedClass);
This code is nice because when you're calling the method in code, it's simple and encapsulated. However, I would like to take it one step further and make the parameter a string containing the full class name, then have the method determine the type of the object via Class.forName(className). The trouble with this is that I can't figure out how to return the type as determined later on. Using method overloading, the code I have is:
public static ?????? dynamicConstructor (String className){
try {
return dynamicConstructor(Class.forName(className));
} catch (ClassNotFoundException e) {
System.out.println("Could not find class at path " + classPath);
e.printStackTrace();
return null;
}
}
The problem is that I have no idea what to put in the part labeled ??????. I want to be able to somehow reference the class determined by Class.forName(className). Is this possible?
It's certainly possible to create an instance of the class from the class name (as long as you have a zero-arg constructor), but if the only place the class name is stored is in a String, then there's no way to determine the type to return. So your method signature would be
public static Object dynamicConstructor(String)
which is probably not very useful or what you want.
So the short answer is, no, this is not possible.

Java - set an object variable via setter method, but I dont want the ability to change it again

I have Spring Web Services project, where I have access to the logged in username.
The processes then takes place via several classes, but what I want to do is, set the username in a User class/bean when I first receive it in the first class.
i.e. the following:
My first web services class:
// Set the Spring Security Name of the user
user.setSpringSecurityUsername(request.getUserId());
String springSecurityUsername = user.getSpringSecurityUsername();
My User class
private String springSecurityUsername = "";
private final String windowsUsername = System.getProperty("user.name");
public String getSpringSecurityUsername() {
return springSecurityUsername;
}
public void setSpringSecurityUsername(String springSecurityUsername) {
this.springSecurityUsername = springSecurityUsername;
}
public String getWindowsUsername() {
return windowsUsername;
}
I want to be able create a new instance of the User bean and set the SpringSecurityUsername. I then wish to pass the user object to the other processing classes, but I don't what them to have access to the setter method in the user (e.g. don't want other classes to be able to use the .setSpringSecurityUsername.
I only want to be able to set it the once.
Can anyone help with this?
I only want to be able to set it the once.
It sounds like you should be passing it to the constructor then. You've referred to the class as a bean in some cases - does it have to be a strict JavaBean with a parameterless constructor? Or should everything still work for you if you just add a constructor?
The benefit of putting it into the constructor over ignoring/throwing on a second setSpringUsername call is that you simply can't express the incorrect code. It's always better to make something impossible than to have to tell people not to do it :)
(It also means you can make it a final field, too.)
It sounds like the initializing value should just be a constructor parameter and there should be no setter method at all. In the case it's also valid to never call the setter, include both a constructor without the argument and one with the argument.
Initialize it internally with some value, then in your setter check to see if it still has that value. If it does, allow it to be set. If it doesn't it has already been set - simply do nothing in that case.
You can't prevent the method from being called, but you can check whether it got called previously:
boolean usernameSet = false;
public synchronized void setSpringSecurityUsername(String springSecurityUsername) {
if (!usernameSet) {
this.springSecurityUsername = springSecurityUsername;
usernameSet = true;
}
}
This is actually a requirement of the builder pattern. You have each setter return "this" and when you want to finalize it you call a method like "finish" to disable all the setters. Goes like this:
new MyClass()
.setAge(20)
.setWeight(200)
.setHeight(6.0)
.finish();
Not a bad pattern at all, kind of gives you named parameters for java without losing the advantages of a immutability.
I would say go for setting it in constructor and no setter methods.
public User(String userName){
this.springSecurityUsername = userName;
}
Here's some code that will allow it to be set once:
private Object v;
public void setV(Object o) {
if (v == null)
v = o;
}
Or if null is a possible value zfor the first set, do this:
private Object notSer = new Object();
private Object v = notSer;
public void setV(Object o) {
if (v == notSer)
v = o;
}

Constant specific method using Enums OR Refection ? Need to invoke methods based on string

I have DTOs (Data Transfer Objects) sent to the DAO (Data Access Object).
DTO has an identifier string.
Based on this string (or rather the DTO), I want to invoke specific methods in the DAO.
These methods make database calls.
I have found two options to do this:
1. Constant specific method implementation using Enum
2. Invoke the method based on reflection ( in which case the DTO will carry the name of the method that needs to be invoked.)
I want to know which is a better option. Are there any other alternatives ? Is it okay to have database calls within the Enum.
The programming language used is Java.
I would not put database calls within your Enum. Instead, provide a method on your DAO that accepts the DTO, and then let that method call other methods within the DAO based on the string on the DTO. You could use a switch statement on the Enum, and make this very efficient. (Alternatively, put this implementation in a separate "adapter" class, since it could be argued that this code doesn't strictly belong in the DAO, either.)
I would also avoid reflection, mainly due to additional complexities - including in debugging and troubleshooting, as well as potential security concerns. (What if the String contained a method name that you didn't want called?)
You can create a map that maps the strings to method calls:
class YourDAO {
private interface Action {
public void perform();
}
private Map<String, Action> actions;
public YourDAO() {
actions.add("String1", new Action() {
public void perform() {
daoMethod1();
}
}
actions.add("String2", new Action() {
public void perform() {
daoMethod2();
}
}
}
public void daoMethod1() {
...
}
public void daoMethod2() {
...
}
public void doSomethingWithDTO(YourDTO dto) {
actions.get(dto.getIdentifier()).perform();
}
}
You can even adapt this idea to perform specific actions on different DTO types if you
change the key type of the map to Class<?> and instead of dto.getIdentifier() use dto.getClass().

how to reduce the code of constructor overloading

In my one class I have many constructors like this..
public MyData(int position,String songName,String duration, boolean e) {
//initialization of above variable like int, string,string and boolean
}
public MyData(String songName, String artistName, String duration,String downloadPath, String songSize, String albumName,String url,String trackId, boolean e)
{
//initialization of above variable like String,String,String,String,String,String,String,String and boolean
}
and some more like above.
Now the calling time, I'm calling that constructor only that I require data. but I don't think my flow is good so I need some help to reduce my code as well as creation of good flow.
If anybody have a good flow to achieve this, then please share.
Thanks in advance.
Assuming you're effectively applying defaults, usually the best approach is to have one "full" constructor and make the others call it. For example:
public Foo(String name)
{
// Default the description to null
this(name, null);
}
public Foo(String name, String description)
{
this.name = name;
this.description = description;
}
You still end up with quite a lot of cruft in terms of overloaded constructors, but at least each of those "extra" constructors contains no actual code - just a call to another constructor. If possible, chain the constructors together so that the default for any particular value is only specified in one place - or use a constant. That way you get consistency.
Another option is to use a "parameter object" following the builder pattern - create another class whose sole purpose is to hold the data for the constructor parameters. This should be mutable, with setters for all of the different values. Often it's useful to make the setters return the builder, so you can use:
FooParameters parameters = new FooParameters()
.setName("some name")
.setDescription("some description");
// Either a constructor call at the end, or give FooParameters
// a build() or create() method
Foo foo = new Foo(parameters);
This is particularly useful if the main type you're constructing is an immutable type - it means you can apply conditional logic in the calling code to set some parameters but not others. The Java framework itself uses this approach in ProcessBuilder, although personally I'm not keen on the way it overloads method names to either return a value or set a value based on whether you provide an argument :(
Note the comment above the constructor call in the final snippet - if your helper class is only ever helpful for creating objects of a single type, you can give it an extra method (build, create, start, whatever is most appropriate) to take the place of the constructor call. This allows you to build the whole final object in a fluent way.
One option in the Java implementation of the builder pattern is to use a nested type, e.g.
Foo foo = new Foo.Builder().setName(...).setDescription(...).build();
That avoids polluting your package with another class which is only useful for building instances of Foo.
You may want to have another object that is responsible for creating the object through the builder pattern. For example, you could define an object like this:
public class SongBuilder {
private String artistName;
private String songTitle;
/* ... everything else ... */
public SongBuilder setArtistName(String name) {
this.artistName = name;
return this;
}
public SongBuilder setSongTitle(String title) {
this.songTitle = title;
return this;
}
/* ... everything else ... */
public Song create() {
return new Song(artistName, songTitle, /* ... everything else ... */);
}
}
You could then define a single constructor for Song that takes in all the data. To make a Song, you could then write
Song s = new SongBuilder().setSongTitle("Still Alive").setArtistName("GLaDOS").create();
The advantage of this approach is that you can set a reasonable default for all the parameters, then just call the appropriate set functions for parameters that you actually use. It also allows you to add new parameters easily without having to go back and rewrite important code.
Alternatively, as Jon Skeet points out, you can have multiple constructors that all call one another. The advantage of the builder pattern over this approach is that if you have n different parameters, there are 2n combinations of constructors you'd need to write, whereas you only need one builder.
Hope this helps!

Categories