Know what class instantiated a class - java

Basically, I'm creating an API. I have multiple endpoints, implemented as controllers. If an endpoint is called, it instantiates a parserclass, adds some options (like permitted parameters etc).
But now: If the parser fails, I want it to present a nice error, containing a link to the docs of the endpoint that actually failed.
I use b4j, which works on top of Java, so any relevant Java code should be easy to convert. In b4j, any endpoint is resembled by a class.
E.g.
I have a 'getPOIByCity' endpoint.
If a user calls this method, a city parameter is required. If he/she omits the parameter, I want the user to be greeted with an error containing:
1 required parameter missing: city
See the documentation: http://www.link.to/doc/getPOIByCity
My first thought was to do some kind of stack tracing to know which class instantiated the parses class, but I cannot believe that is the way to do this.
C# has the slightly more elegant 'Caller information' attributes.
Any insights in how to do this?

As another-dave already mentioned, it would make a lot more sense to delegate the exception to the calling class (the controller) and show the error from there.
But just to give an answer to your problem, you can use
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
String parentClass = stackTraceElements[2].getClassName();
Class cl = Class.forName(parentClass);
to achieve what you want.

Related

Need to access method/data from calling java methods

My challenge. I have a class that is being accessed by third-party code, and I want to audit what's calling it. To do this I need to access the object or at least the data of the calling objects. Class name from the stack trace isn't far enough.
The real example:
I've extended the BaseStandardCredentials class from Jenkins. I want to audit the public Secret getPassword() method. But to audit, I need the job details. Anyone using the more normal methods is audited elsewhere. But there are a few plugins/shared pipeline code which pull all credentials from the system, effectively hiding the job involved, and just cherry-pick the credential they need (http_request is the main culprit but there are others)
My basic thought is to audit the getPassword() function as that's exactly who/what is getting the data. I can see in the stack trace the calling methods but that's no good if I can't get the job name/number from one of the execution objects.
Any way to do this? Or any way to at least tag the object in a way it shows up in a stack trace?

Java - Creating a class to dynamically determine if user has access to the calling method

I have tried doing a search for this but I fear I may not be wording what I want to do very well.
Currently, we have about a hundred action classes in our application with each determining if a user has access to it. I would like to make a class that can figure out the calling method, what permissions are required for it, and if the user has those permissions. Unfortunately, I don't really know how to even get started with this as each class may have slightly different requirements.
I'm happy to add more explanation if needed but as I said, I'm not sure I'm wording what I'm trying to do very well so if anyone has a better way of putting it that gets me some google results or a link to a related question here that's already been answered, I know I'd appreciate it.
current permissions checks look like below. This is a simple implementation, there are usually multiple profile checks in one if block.
If (scc.getUser().getCurrentProfile().getSystemAdmin() != 1) {
logIllegalAccess(log);
break;
}
IMHO the most elegant solution would make use of annotation processing. The idea is that you would annotate action classes with a custom annotation, something like:
#RequiredPermission(Permissions.SYSADM)
class ActionA {
public ActionA newInstance() {
return new ActionA_Gen(new ActionA());
}
private ActionA() {...}
...
}
Action classes would have to have a newInstance() method to be used to create instances instead of calling new. The method would create an instance of a class by the same name with _Gen extension. This class would have one method for each method in the original action class, which would perform a permission check and call the corresponding method in the original class instance that was passed to its constructor.
The _Gen class would be generated by an annotation processor.
Note that by using reflection it might be possible to move the newInstance() method in a common superclass.

Enforce method call to avoid throwing exception

I have a library and to create an instance, I use the connectWith() method to send database model:
Wallet wallet = new WalletPoket();
wallet.connectWith(
DAOFactory.getDAOFactory(DAOFactory.MYSQL)
);
Followed by these methods:
int privateCardId = wallet.addCard(1, "Economy 1");
boolean wasDeleted = wallet.deleteCard(privateCardId);
...
Calling the previous methods will result in a NullPointerException if the connectWith() method is not called prior.
Is it possible to force the user to call the connectWith() method or present the user with a warning if they do not?
Would it be acceptable to call the method from the constructor?
Wallet wallet = new WalletPoket(
DAOFactory.getDAOFactory(DAOFactory.MYSQL)
);
What would be the best alternative?
You have a few options.
Force the user to pass the option as an argument to the constructor.
Throw an exception with a message stating that connectWidth must be called if it was not called.
If there is a good default thing to connect with, then connect with that in the constructor.
This is where things get a bit verbose, since it means:
You have to check state before you do anything, and
You have to guard against developers doing silly things.
One thing you can do is check the state of your connection (ensuring that it's not null), then throwing an IllegalStateException explaining why it blew up:
if(null == daoFactory) {
throw new IllegalStateException("You are attempting to invoke this without a DAO Factory defined.");
}
...but you'd have to add this check to every method that you had in your program.
A preferred approach in my mind would be to add this to the constructor of the object, since that clearly captures the need to have this dependency before the entity is constructed. So effectively, I agree with your second approach.
The last thing you could do is do some fancy annotation processing to force a specific compiler warning or error should this dependency go missing, but it's likely a lot more straightforward to add it in as a constructor dependency instead.
If the addCard and deleteCard method calls are crucial to the Object's functionality (i.e almost always called), then add it as a constructor.
Otherwise, you can simply throw a detailed IllegalStateException when they're called in the wrong order. You should also document the library methods accordingly explaining what's needed for them to function properly.
The (library) class Wallet should have provided a constructor that takes the database endpoint. Since it is not available, you could provide a utility wrapper that accounts for it. That way, your utility wrapper can mandate the endpoint and make sure that it is available beforehand.
Another thing you can explore is dependency injection, i.e. whenever a client needs a Wallet, it does #Inject Wallet wallet. This, admittedly, has added complexity, but it renders the code that is more easily testable. (See javax.inject, or dagger).
I think, you should implement proxy design pattern to solve the problem.
When the client creates a Wallet, they should get the proxy of the Wallet instance.When client invokes the service API say addCard then Real Wallet object instance comes into picture(lazy loading) and does the dao instantiation which is a singleton instance.

How to search a class which can handle specific data in Java?

I have multiple classes in my current project like HTMLRequest, SPDYRequest, BHIVERequest. I get data from a network stream and I want to find out, which of the classes can handle this data. For this I read the header of the Stream packet (All protocols are in the same form, so I can read until I get empty line (\r\n) ) and then pass this header to a static function in the request classes which returns a boolean which tells whether it is a header for this kind of request or not. Now I want to be able to load specific Protocols at runtime (from plug-ins). What is the best way to be able to check whether I have a Protocol for a header or not.
My thoughts were:
An extra class Protocol as a singleton, which then is registered in a RequestFactory, that then has to find out which Protocol can create a request for this kind of header and calls Protocol.assemble()
A static List of Class<? extends Request> so I can call the static methods through reflection or by Class.newInstance()
I don't like both that ideas, so what is the right way to dynamically do this stuff in Java?
If it were me, I'd do something similar, but not identical, to option 1:
Read all plugins at startup, storing their headers and a reference to either their class name or an instance (if they're stateless) in a HashMap in a RequestFactory or similarly named utility. You'd also store references to the built-in system protocols in this map.
When a request comes in, make a call to RequestFactory.getProtocol(String header) to grab a reference to the protocol that should be used.
Note that if you go this route, you don't need a method in each protocol class that lets you query whether a header is appropriate for it; the factory handles that for you.
Edit
...I just noticed the "at runtime" part of your question, which makes the "at startup" part of my solution a little out of place. New plugins could still be registered into the factory's internal map as they're recognized/loaded; that shouldn't affect the usefulness of this design as a whole.

How to introduce a special case in the API design?

I'm developing API for a library which will be used by a customer.
The library should provide single interface to access several remote resources. So, I should create API and several its implementations (correspondent to the number of remote resources).
I met the next problem: all resources except one has API for logging in. So, I can create method
void authenticate (String login, String password) throws AuthenticationException;
But I can't pass authentication to that one resource with this method.
To pass authentication on that resource I need to perform some actions and receive URL for authentication, then I should give this URL to the caller, caller program use some magic to pass authentication, and after that it should give me back "the flow".
So now I need 2 more methods to achieve necessary result:
String getAuthenticationURL () throws AuthenticationException;
void postAuthentication () throws AuthenticationException;
If I add these methods to the API then I'll have to create their empty implementations (or implementations which throws RuntimeException) in all API implementations for 'normal' resources.
If I do not add them to the API but add them only to one concrete implementation then I'll break the whole idea of unified API.
The approach with these 2 methods is only one of at least several possible solutions. So, any advices and suggestions are welcome.
You could have an abstract base class with two concrete child classes--each child containing a different authentication mechanism.
The other (probably better) method, however, might be to create an abstract "Authentication" object with two APIs (two concrete implementations). One would have your authenticate method, the other would have your get/post.
The advantage here is that your authenticate class contains all the functionality specific to authentication.. might even have some of the code in the class that is an abstract parent of your two authentication objects.
You can still keep your authenticate method if you like, it's implementation would simply be delegated to the authenticate object.
Note that this also gives your user a more "Minimal" api whereas extending your original interface gives you an entire second copy & paste class to consider.
Also, consider passing the correctly constructed authentication object to the constructor of your original class. Makes for a nice, clean system.
Whenever I break a piece of functionality into it's own class like this I always gain some great refactoring possibilities.
I love Bill K solution, but you could also have your authentication classes work like some kind of factory, providing you with a logged in resource when the authentication is done.
This way the first step for the user would be to chose the right authentication method, authenticate and get it's resource ready for use.

Categories

Resources