I was looking for some sample example code that could help me write full-fledged code for adding a method in another class using ASTRewrite.
P.S: It is not a problem of adding lines in a method that is already created. Instead, I wish to create a new method which doesn't exist in user's class and which has the capability of accepting parameters and has some code inside it.
If, generally, you are able to make changes using ASTRewrite then probably all you need is to obtain a ListRewrite for the body declarations of the declaring class, s.t. like:
astRewrite.getListRewrite(type, type.getBodyDeclarationsProperty())
the resulting ListRewrite has various insertX methods to suite your needs.
The method can be created beforehand using the factory methods from AST (i.e., for this you don't need to bother the rewriter for this).
Related
I am wondering if is it possible to add method to class without having to rewrite whole class again using Java Poet?
Thanks
JavaPoet emits source code, nothing else. It can't consume the source code of an existing class.
You could emit a method with it and insert it into the body of a class some other way, but that's as good as it gets.
One reason would be to get a specific order that methods are to be called.
I would guess that pattern language would be used for this. This can be done in JavaScript but what is the solution in Java, can it be done?
if you want that the user calls a specific sequence of methods, put this workflow into a method and make this method the only accessible point of entry for the user.
otherwise there is no need in java to define a specific order of methods in a source file.
This is just a sketch right now, have not tested yet!
put all the method names in a String[]
create a for loop to traverse the array
Then substitute the methodname for the array member in the code in the next clue:
How do I invoke a Java method when given the method name as a string?
What I am trying to do: I want to have a pre-compiled java byte-code file, and be able to place a "mark" in some places. Later I want to analyze this file using ASM and replace mark with some code. So, how can I implement this? Currently I am trying to do it, by inserting invocations of empty static method, but I still feeling like I am doing something wrong. Is there a better way to do this?
P.S. If more general, I want to have some precompiled class template, for example:
public class Main {
public static void Main(String... args){
System.out.println("Program starts!");
//I want to insert code here
System.out.println("Bye!");
}}
There is no Java statement without a predefined meaning, well, maybe with the exception of the empty statement ; which doesn’t create code that you can find in the byte code. There are annotations, but these can only be used to mark another code fragment, not to create a stand-alone statement within your code.
So you have to choose a statement to assign it the meaning of being a mark in your template code and your solution of using an invocation of a dedicated empty method is a perfect candidate for such a mark. Since it’s new meaning does not rely on the kind of statement but on the target method which resides in a class whose name is distinguishable from all other classes, there is no conflict between your mark and other statements.
But you should consider that the framing class code is rather trivial compared to the code you will generate when implementing a compiler for any non trivial language. In most cases, the logic of patching the generated code into an existing code will exceed the complexity of just generating a complete class file.
If you really have large pieces of unchanging code you should consider placing them into their own classes and generate classes using or extending them. This simplifies the code generation and avoids code duplication (the same reason why these techniques are used in manually written code).
I'm investigating ways to ensure a java class only calls a limited set of allowed methods from other classes. The usecase I have receives the class via the standard java serialization.
The approach I want to try is to simply list the methods it calls and only run the code if it passes a short whire list.
The question I have : how do I list the methods used in that class?
This is not a perfect solution but you coud use this if you can't find something better. You can use javap, if you're in Linux, run in the command line (or run a proccess using Runtime.exec()): javap -verbose /path/to/my/classfile.class | grep invoke and you'll have the binary signatures that the class "calls" from other classes. Yes, I know, it's not what you wanted but you could use it as a last resource.
If you need a more "javaish" solution, you could have a look at a java library called "asm": http://asm.ow2.org/
You could pass a dynamic proxy object to the caller, which inside checks the methods against your white list and throws exception when the call is not allowed.
Dynamic proxies basically allows you to insert piece of code between the caller's method invocation and the actual invocation of the called method.
I'd really think through though to if you really need this. Dynamic proxies are useful but they can also be very confusing and annoying to debug.
I am reading an Excel file using java, I have written some methods for my business logic and i want to implement using properties File.
What i want to Do is :
I am having 10 Columns and 10 methods, i need to declare this methods in Properties file use from that file.
Suppose for column A i want only 2 methods then i can use only those 2 methods, For next column B suppose 10 methods and So on.
Can i Do this or is there any other way to implement this.
Please Suggest me if there is any other way to implement this. Thanks in Advance.
To prevent misunterstandings: properties files are just text files, so you need to use Java code in order to process them. They'll only provide a String->String (key->value) mapping, thus you need to parse and interpret the strings yourself.
That being said, here's a suggestion on what you might (want to) do:
Since your question isn't that clear I'll make a couple of assumptions:
Your properties file contains something like:
column1=method1,method7
column2=method1,method2,method3
etc.
The methods are all declared in one class using a common signature
When parsing your excel file you might want to apply the methods to the columns based on the properties file.
So, here are some hints on what you could do:
Parse the properties file and create a list of method names per column
When working on a cell/column get the method names for the respective column
Use YourClass.class.getMethod(methodName, parameterTypes) to get the Method instances.
Call Method#invoke(...) to invoke the method.
Edit:
As an alternative to having all methods in one class you could also use the fully qualified class name, e.g. yourpackage.YourClass#method1, split at # to get the class name and the method, then use Class.forName(fqcn) to get the class and finally call getMethod(...) on that.
If the signature differs, you might have to use a more complicated notation and parse the parameter classes as well.
There be parsers ready to use for this, but I don't know any. However, some apache commons projects like El and Configuration might prove useful for this task.
It's not at all clear what you are trying to do, but in any case you definitely cannot "call" any Java methods from a .properties file (or call from Java to a method contained in a .properties file). A .properties file is not executable, nor is it treated by any standard Java utility as executable/interpretable code. In essence, all it contains is data, and data cannot call or be called.
What you could do however is roll your own framework for doing this, either by using reflection to map the textual method calls in your input file to actual method calls against one or more Java objects, or more simply (but less flexibly/extensibly) by storing a predetermined set of codes which you map directly to method calls using a switch/if-else block, or perhaps by storing your desired code as JavaScript and using an existing Java-based JavaScript interpreter to execute the code.