How can I get Annotation class from TypeDescription - byte-buddy

I'm trying to work with ByteBuddy.
How, with given TypeDescription, can I get annotation class?
So far I found getActualName.
#Override
public boolean matches(final TypeDescription target) {
//System.out.printf("matches(%1$s)\n", target);
//System.out.printf("\tcanonicalName: %1$s\n", target.getCanonicalName());
//System.out.printf("\tcomponentType: %1$s\n", target.getComponentType());
{
final AnnotationList inheritedAnnotations = target.getInheritedAnnotations();
inheritedAnnotations.forEach(v -> {
//System.out.printf("\tinherited annotationDescriptor: %1$s\n", v);
});
}
{
final AnnotationList declaredAnnotations = target.getDeclaredAnnotations();
declaredAnnotations.forEach(v -> {
//System.out.printf("\tdeclared annotationDescriptor: %1$s\n", v);
});
}
{
final FieldList<FieldDescription.InDefinedShape> declaredFields = target.getDeclaredFields();
declaredFields.forEach(declaredFiled -> {
System.out.println("declaredField: " + declaredFiled);
final AnnotationList declaredAnnotations = declaredFiled.getDeclaredAnnotations();
declaredAnnotations.forEach(declaredAnnotation -> {
System.out.println("declaredAnnotation: {}" + declaredAnnotation);
final Set<ElementType> elementTypes = declaredAnnotation.getElementTypes();
System.out.println("\telementTypes: " + elementTypes);
final TypeDescription annotationType = declaredAnnotation.getAnnotationType();
System.out.println("\tannotationType: " + annotationType);
System.out.println("\tannotationType.actualName: " + annotationType.getActualName());
});
});
}
return false;
}
I'm, actually, trying to add some methods on compiled classes by some fields annotated with specific annotation.

An AnnotationList is a list of AnnotationDescription typed object where you can invoke the getAnnotationType method to receive a TypeDescription of their annotation type.

Related

How to return object from retrofit api get call

I am trying to get list of objects from api call with retrofit but i just cant find the way to do so :(
This is the function i built:
private List<Business> businesses getBusinesses()
{
List<Business> businessesList = new ArrayList<>();
Call<List<Business>> call = jsonPlaceHolderApi.getBusinesses();
call.enqueue(new Callback<List<Business>>() {
#Override
public void onResponse(Call<List<Business>> call, Response<List<Business>> response) {
if(!response.isSuccessful())
{
textViewResult.setText("Code: " + response.code());
return;
}
List<Business> businesses = response.body();
for(Business business : businesses)
{
String content = "";
content += "ID: " + business.getId() + "\n";
content += "Name: " + business.getName() + "\n";
content += "On promotion: " + business.isOnPromotion() + "\n\n";
textViewResult.append(content);
}
businessesList = businesses;
}
#Override
public void onFailure(Call<List<Business>> call, Throwable t) {
call.cancel();
textViewResult.setText(t.getMessage());
}
});
}
I am trying to get the businesses response and return it.
can anyone help me?
Feeling frustrated :(
The way your executing the Retrofit call is asynchronous - using call.enqueue. there's nothing wrong with this approach. In fact it's perhaps the best option, since network calls can take a while and you don't want to block unnecessarily.
Unfortunately, this means you cannot return the result from the function. In most scenarios, if you did, the call would likely finish after the return making your return useless.
There are several ways to deal with this, the simplest one is to use callbacks. For example:
interface OnBusinessListReceivedCallback {
void onBusinessListReceived(List<Business> list);
}
private void businesses getBusinesses(OnBusinessListReceivedCallback callback){
Call<List<Business>> call = jsonPlaceHolderApi.getBusinesses();
call.enqueue(new Callback<List<Business>>() {
#Override
public void onResponse(Call<List<Business>> call, Response<List<Business>> response) {
if(!response.isSuccessful()){
textViewResult.setText("Code: " + response.code());
return;
}
callback.onBusinessListReceived(response.body());
}
#Override
public void onFailure(Call<List<Business>> call, Throwable t) {
call.cancel();
textViewResult.setText(t.getMessage());
}
});
}
You can then call it like so:
getBusinesses(new OnBusinessListReceivedCallback() {
public void onBusinessListReceived(List<Business> list){
// list holds your data
}
});

Custom serializer not working in Web API 2 for oData 4 when the URL contains $select

I implemented a custom serializer by inheriting ODataEntityTypeSerializer. The serializer sets the value of "MessageStateName" by getting the name of BayStateEnum from the value of "MessageState".
It works well only except when the URL contains "$select". I debugged the code and found it was executed and entityInstanceContext.EntityInstance had the correct value, but entityInstanceContext.EdmModel, which was of type System.Web.OData.Query.Expressions.SelectExpandBinder.SelectSome, still had an empty "MessageStateName".
public class CustomEntitySerializer : ODataEntityTypeSerializer
{
public CustomEntitySerializer(ODataSerializerProvider serializerProvider)
: base(serializerProvider)
{
}
public override ODataEntry CreateEntry(SelectExpandNode selectExpandNode, EntityInstanceContext entityInstanceContext)
{
if (entityInstanceContext.EntityInstance is SmartLinkInfoModel)
{
var smartLinkInfo = entityInstanceContext.EntityInstance as SmartLinkInfoModel;
if (smartLinkInfo.ModemIMEI != null)
{
smartLinkInfo.ModemIMEIString = "0x" + string.Join(string.Empty, smartLinkInfo.ModemIMEI.Select(b => (b - 48).ToString()));
}
if (smartLinkInfo.SmartLinkHardwareId != null)
{
smartLinkInfo.SmartLinkHardwareIdString = "0x" + string.Join(string.Empty, smartLinkInfo.SmartLinkHardwareId.Select(b => b.ToString()));
}
if (smartLinkInfo.XbeeSourceId != null)
{
smartLinkInfo.XbeeSourceIdString = "0x" + string.Join(string.Empty, smartLinkInfo.XbeeSourceId.Select(b => b.ToString()));
}
}
else if (entityInstanceContext.EntityInstance is BayMessageModel)
{
var bayMessage = entityInstanceContext.EntityInstance as BayMessageModel;
bayMessage.MessageStateName = Enum.GetName(typeof(BayStateEnum), bayMessage.MessageState);
}
return base.CreateEntry(selectExpandNode, entityInstanceContext);
}
}
Your code to change the entityInstanceContext.EntityInstance is right, but it won't change the result of select, you can see
object propertyValue = entityInstanceContext.GetPropertyValue(structuralProperty.Name);
in ODataEntityTypeSerializer 's CreateStructuralProperty method, you should override this method, if the structuralProperty.Name is MessageStateName, then use (entityInstanceContext.EntityInstance as BayMessageModel).MessageStateName

dynamic Using in FindsBy with selenium

I have this spec
Scenario Outline: Display widget
Given I have a valid connection
When I navigate to home using <browser>
Then The element in css selector #<id> > svg > g.x.axis.percent > text:nth-child(1) should be <value>
Examples:
| browser | id | valye |
| Chrome | Widget1 | 213.00 |
With this page definition
class BarSummaryPage
{
[FindsBy(How = How.CssSelector, Using="#{DYNAMIC-ID} > svg > g.x.axis.percent > text:nth-child(1)")]
private IWebElement Mes;
}
I need to configure the Using property in FindsBy dynamic, like above: SEE #{DYNAMIC-ID}
As far as I know, this doesn't exist out of the box. The FindBy annotation takes static Strings only. You probably need to custom modify the FindBy annotation processor similarly to what this blogger did: https://web.archive.org/web/20180612042724/http://brimllc.com/2011/01/selenium-2-0-webdriver-extending-findby-annotation-to-support-dynamic-idxpath/
Another discussion thread here: https://groups.google.com/forum/#!topic/webdriver/awxOw0FoiYU where Simon Stewart shows an example of how this could be accomplished.
UPDATE:
I have actually implemented this because I needed it enough to try. I didn't create a custom finder annotation (which I may have to do in the future).
I wrote implementations for ElementLocator and ElementLocatorFactory that allow for string substitutions for locators specified using the existing annotations. If you know, or can determine, at runtime the values to substitute, this will work for you.
By default, PageFactory uses the classes DefaultElementLocator and DefaultElementLocatorFactory implementations of the ElementLocator and ElementLocatorFactory interfaces for setting up the processing of annotations, but the real logic is in the Annotations class. I wrote my own implementations of ElementLocator, and ElementLocatorFactory and wrote my own version of Annotations to do the processing. There are just a few differences between the source of my customized classes and the ones that are in the Selenium source code.
public class DynamicElementLocator implements ElementLocator {
private static final XLogger log = XLoggerFactory.getXLogger(DynamicElementLocator.class.getCanonicalName());
private final SearchContext searchContext;
private final boolean shouldCache;
private final By by;
private WebElement cachedElement;
private List<WebElement> cachedElementList;
//The only thing that differs from DefaultElementLocator is
//the substitutions parameter for this method.
public DynamicElementLocator(final SearchContext searchContext, final Field field, final Map<String,String>
substitutions) {
log.entry(searchContext, field, substitutions);
this.searchContext = searchContext;
//DynamicAnnotations is my implementation of annotation processing
//that uses the substitutions to find and replace values in the
//locator strings in the FindBy, FindAll, FindBys annotations
DynamicAnnotations annotations = new DynamicAnnotations(field, substitutions);
shouldCache = annotations.isLookupCached();
by = annotations.buildBy();
log.debug("Successful completion of the dynamic element locator");
log.exit();
}
/**
* Find the element.
*/
public WebElement findElement() {
log.entry();
if (cachedElement != null && shouldCache) {
return log.exit(cachedElement);
}
WebElement element = searchContext.findElement(by);
if (shouldCache) {
cachedElement = element;
}
return log.exit(element);
}
/**
* Find the element list.
*/
public List<WebElement> findElements() {
log.entry();
if (cachedElementList != null && shouldCache) {
return log.exit(cachedElementList);
}
List<WebElement> elements = searchContext.findElements(by);
if (shouldCache) {
cachedElementList = elements;
}
return log.exit(elements);
}
}
And here is the DynamicElementLocatorFactory:
public final class DynamicElementLocatorFactory implements ElementLocatorFactory {
private final SearchContext searchContext;
private final Map<String,String> substitutions;
//The only thing that is different from DefaultElementLocatorFactory
//is that the constructor for this class takes the substitutions
//parameter that consists of the key/value mappings to use
//for substituting keys in locator strings for FindBy, FindAll and
//FindBys with values known or determined at runtime.
public DynamicElementLocatorFactory(final SearchContext searchContext, final Map<String,String> substitutions) {
this.searchContext = searchContext;
this.substitutions = substitutions;
}
//This produces an instance of the DynamicElementLocator class and
//specifies the key value mappings to substitute in locator Strings
public DynamicElementLocator createLocator(final Field field) {
return new DynamicElementLocator(searchContext, field, substitutions);
}
}
And here is my custom annotation processor. This is where most of the work was:
public class DynamicAnnotations extends Annotations {
private static final XLogger log = XLoggerFactory.getXLogger(DynamicAnnotations.class.getCanonicalName());
private final Field field;
private final Map<String,String> substitutions;
//Again, not much is different from the Selenium default class here
//other than the additional substitutions parameter
public DynamicAnnotations(final Field field, final Map<String,String> substitutions) {
super(field);
log.entry(field, substitutions);
this.field = field;
this.substitutions = substitutions;
log.debug("Successful completion of the dynamic annotations constructor");
log.exit();
}
public boolean isLookupCached() {
log.entry();
return log.exit((field.getAnnotation(CacheLookup.class) != null));
}
public By buildBy() {
log.entry();
assertValidAnnotations();
By ans = null;
FindBys findBys = field.getAnnotation(FindBys.class);
if (findBys != null) {
log.debug("Building a chained locator");
ans = buildByFromFindBys(findBys);
}
FindAll findAll = field.getAnnotation(FindAll.class);
if (ans == null && findAll != null) {
log.debug("Building a find by one of locator");
ans = buildBysFromFindByOneOf(findAll);
}
FindBy findBy = field.getAnnotation(FindBy.class);
if (ans == null && findBy != null) {
log.debug("Building an ordinary locator");
ans = buildByFromFindBy(findBy);
}
if (ans == null) {
log.debug("No locator annotation specified, so building a locator for id or name based on field name");
ans = buildByFromDefault();
}
if (ans == null) {
throw log.throwing(new IllegalArgumentException("Cannot determine how to locate element " + field));
}
return log.exit(ans);
}
protected By buildByFromDefault() {
log.entry();
return log.exit(new ByIdOrName(field.getName()));
}
protected By buildByFromFindBys(final FindBys findBys) {
log.entry(findBys);
assertValidFindBys(findBys);
FindBy[] findByArray = findBys.value();
By[] byArray = new By[findByArray.length];
for (int i = 0; i < findByArray.length; i++) {
byArray[i] = buildByFromFindBy(findByArray[i]);
}
return log.exit(new ByChained(byArray));
}
protected By buildBysFromFindByOneOf(final FindAll findBys) {
log.entry(findBys);
assertValidFindAll(findBys);
FindBy[] findByArray = findBys.value();
By[] byArray = new By[findByArray.length];
for (int i = 0; i < findByArray.length; i++) {
byArray[i] = buildByFromFindBy(findByArray[i]);
}
return log.exit(new ByAll(byArray));
}
protected By buildByFromFindBy(final FindBy findBy) {
log.entry(findBy);
assertValidFindBy(findBy);
By ans = buildByFromShortFindBy(findBy);
if (ans == null) {
ans = buildByFromLongFindBy(findBy);
}
return log.exit(ans);
}
//The only thing that is different from the default Selenium implementation is that the locator string is processed for substitutions by the processForSubstitutions(using) method, which I have added
protected By buildByFromLongFindBy(final FindBy findBy) {
log.entry(findBy);
How how = findBy.how();
String using = findBy.using();
switch (how) {
case CLASS_NAME:
log.debug("Long FindBy annotation specified lookup by class name, using {}", using);
String className = processForSubstitutions(using);
return log.exit(By.className(className));
case CSS:
log.debug("Long FindBy annotation specified lookup by css name, using {}", using);
String css = processForSubstitutions(using);
return log.exit(By.cssSelector(css));
case ID:
log.debug("Long FindBy annotation specified lookup by id, using {}", using);
String id = processForSubstitutions(using);
return log.exit(By.id(id));
case ID_OR_NAME:
log.debug("Long FindBy annotation specified lookup by id or name, using {}", using);
String idOrName = processForSubstitutions(using);
return log.exit(new ByIdOrName(idOrName));
case LINK_TEXT:
log.debug("Long FindBy annotation specified lookup by link text, using {}", using);
String linkText = processForSubstitutions(using);
return log.exit(By.linkText(linkText));
case NAME:
log.debug("Long FindBy annotation specified lookup by name, using {}", using);
String name = processForSubstitutions(using);
return log.exit(By.name(name));
case PARTIAL_LINK_TEXT:
log.debug("Long FindBy annotation specified lookup by partial link text, using {}", using);
String partialLinkText = processForSubstitutions(using);
return log.exit(By.partialLinkText(partialLinkText));
case TAG_NAME:
log.debug("Long FindBy annotation specified lookup by tag name, using {}", using);
String tagName = processForSubstitutions(using);
return log.exit(By.tagName(tagName));
case XPATH:
log.debug("Long FindBy annotation specified lookup by xpath, using {}", using);
String xpath = processForSubstitutions(using);
return log.exit(By.xpath(xpath));
default:
// Note that this shouldn't happen (eg, the above matches all
// possible values for the How enum)
throw log.throwing(new IllegalArgumentException("Cannot determine how to locate element " + field));
}
}
//The only thing that differs from the default Selenium implementation is that the locator string is processed for substitutions by processForSubstitutions(using), which I wrote
protected By buildByFromShortFindBy(final FindBy findBy) {
log.entry(findBy);
log.debug("Building from a short FindBy annotation");
if (!"".equals(findBy.className())) {
log.debug("Short FindBy annotation specifies lookup by class name: {}", findBy.className());
String className = processForSubstitutions(findBy.className());
return log.exit(By.className(className));
}
if (!"".equals(findBy.css())) {
log.debug("Short FindBy annotation specifies lookup by css");
String css = processForSubstitutions(findBy.css());
return log.exit(By.cssSelector(css));
}
if (!"".equals(findBy.id())) {
log.debug("Short FindBy annotation specified lookup by id");
String id = processForSubstitutions(findBy.id());
return log.exit(By.id(id));
}
if (!"".equals(findBy.linkText())) {
log.debug("Short FindBy annotation specified lookup by link text");
String linkText = processForSubstitutions(findBy.linkText());
return log.exit(By.linkText(linkText));
}
if (!"".equals(findBy.name())) {
log.debug("Short FindBy annotation specified lookup by name");
String name = processForSubstitutions(findBy.name());
return log.exit(By.name(name));
}
if (!"".equals(findBy.partialLinkText())) {
log.debug("Short FindBy annotation specified lookup by partial link text");
String partialLinkText = processForSubstitutions(findBy.partialLinkText());
return log.exit(By.partialLinkText(partialLinkText));
}
if (!"".equals(findBy.tagName())) {
log.debug("Short FindBy annotation specified lookup by tag name");
String tagName = processForSubstitutions(findBy.tagName());
return log.exit(By.tagName(tagName));
}
if (!"".equals(findBy.xpath())) {
log.debug("Short FindBy annotation specified lookup by xpath");
String xpath = processForSubstitutions(findBy.xpath());
return log.exit(By.xpath(xpath));
}
// Fall through
log.debug("Locator does not match any expected locator type");
return log.exit(null);
}
//This method is where I find and do replacements. The method looks
//for instances of ${key} and if there is a key in the substitutions
//map that is equal to 'key', the substring ${key} is replaced by the
//value mapped to 'key'
private String processForSubstitutions(final String locator) {
log.entry(locator);
log.debug("Processing locator '{}' for substitutions");
List<String> subs = Arrays.asList(StringUtils.substringsBetween(locator, "${", "}"));
log.debug("List of substrings in locator which match substitution pattern: {}", subs);
String processed = locator;
for(String sub : subs) {
log.debug("Processing substring {}", sub);
//If there is no matching key, the substring "${ ..}" is treated as a literal
if(substitutions.get(sub) != null) {
log.debug("Replacing with {}", substitutions.get(sub));
processed = StringUtils.replace(locator, "${" + sub + "}",substitutions.get(sub));
log.debug("Locator after substitution: {}", processed);
}
}
return log.exit(processed);
}
private void assertValidAnnotations() {
log.entry();
FindBys findBys = field.getAnnotation(FindBys.class);
FindAll findAll = field.getAnnotation(FindAll.class);
FindBy findBy = field.getAnnotation(FindBy.class);
if (findBys != null && findBy != null) {
throw log.throwing(new IllegalArgumentException("If you use a '#FindBys' annotation, " +
"you must not also use a '#FindBy' annotation"));
}
if (findAll != null && findBy != null) {
throw log.throwing(new IllegalArgumentException("If you use a '#FindAll' annotation, " +
"you must not also use a '#FindBy' annotation"));
}
if (findAll != null && findBys != null) {
throw log.throwing(new IllegalArgumentException("If you use a '#FindAll' annotation, " +
"you must not also use a '#FindBys' annotation"));
}
}
private void assertValidFindBys(final FindBys findBys) {
log.entry(findBys);
for (FindBy findBy : findBys.value()) {
assertValidFindBy(findBy);
}
log.exit();
}
private void assertValidFindAll(final FindAll findBys) {
log.entry(findBys);
for (FindBy findBy : findBys.value()) {
assertValidFindBy(findBy);
}
log.exit();
}
private void assertValidFindBy(final FindBy findBy) {
log.entry();
if (findBy.how() != null) {
if (findBy.using() == null) {
throw log.throwing(new IllegalArgumentException(
"If you set the 'how' property, you must also set 'using'"));
}
}
Set<String> finders = new HashSet<>();
if (!"".equals(findBy.using())) {
log.debug("Locator string is: {}", findBy.using());
finders.add("how: " + findBy.using());
}
if (!"".equals(findBy.className())) {
log.debug("Class name locator string is {}", findBy.className());
finders.add("class name:" + findBy.className());
}
if (!"".equals(findBy.css())) {
log.debug("Css locator string is {}", findBy.css());
finders.add("css:" + findBy.css());
}
if (!"".equals(findBy.id())) {
log.debug("Id locator string is {}", findBy.id());
finders.add("id: " + findBy.id());
}
if (!"".equals(findBy.linkText())) {
log.debug("Link text locator string is {}", findBy.linkText());
finders.add("link text: " + findBy.linkText());
}
if (!"".equals(findBy.name())) {
log.debug("Name locator string is {}", findBy.name());
finders.add("name: " + findBy.name());
}
if (!"".equals(findBy.partialLinkText())) {
log.debug("Partial text locator string is {}", findBy.partialLinkText());
finders.add("partial link text: " + findBy.partialLinkText());
}
if (!"".equals(findBy.tagName())) {
log.debug("Tag name locator string is {}", findBy.tagName());
finders.add("tag name: " + findBy.tagName());
}
if (!"".equals(findBy.xpath())) {
log.debug("Xpath locator string is {}", findBy.xpath());
finders.add("xpath: " + findBy.xpath());
}
// A zero count is okay: it means to look by name or id.
if (finders.size() > 1) {
throw log.throwing(new IllegalArgumentException(
String.format("You must specify at most one location strategy. Number found: %d (%s)",
finders.size(), finders.toString())));
}
}
}
Example usage:
public class ExampleClass extends SlowLoadableComponent<ExampleClass> {
private final Map<String, String> substitutions;
#FindBy(how = How.ID, using = "somelocator_with_a dynamic_${id}")
private WebElement someElement;
public ExampleClass(final WebDriver driver, final int
loadTimeoutInSeconds, final String idValue) {
substitutions = new HashMap<>(); substitutions.put("id", idValue);
}
//When you call PageFactory.initElements, you need to tell it to use the DynamicElementLocatorFactory
protected void load() {
PageFactory.initElements(new DynamicElementLocatorFactory(getDriver(), substitutions), this);
}
}
UPDATED 5/1/2019: I had to use a Web Archive link for the blog post I referenced at the beginning of my answer because that blog post is not accessible at its original link.

declare generic parents statement in aspectj

Is it possible to use generic types with declare parents such that a class defined with generics implements an interface with the same generic types
i.e declare parents: AClass<Generic1,Generic2> implements
AnInterface<Generic1,Generic2>
What I am saying is whether it is possible to pass the generic types of the child to parents
Kind of. Check this out:
Generic class:
package de.scrum_master.app;
public class KeyValuePair<K,V> {
private K key;
private V value;
KeyValuePair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
#Override
public String toString() {
return "KeyValuePair [key=" + key + ", value=" + value + "]";
}
}
Generic interface:
package de.scrum_master.app;
public interface KeyValueComparator<K, V> {
boolean equalsKey(K otherKey);
boolean equalsValue(V otherValue);
}
Aspect with ITD:
The ITD (inter-type definition) makes sure that the class implements the interface and also gets method implementations for the interface at the same time.
package de.scrum_master.aspect;
import de.scrum_master.app.KeyValuePair;
import de.scrum_master.app.KeyValueComparator;
public aspect InterfaceIntroductionAspect {
declare parents : KeyValuePair implements KeyValueComparator;
public boolean KeyValuePair.equalsKey(K otherKey) {
return this.getKey().equals(otherKey);
}
public boolean KeyValuePair.equalsValue(V otherValue) {
return this.getValue().equals(otherValue);
}
}
Driver application:
Create two different types of class objects and try to cast them both to the introduced interface:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
KeyValuePair<Integer, String> pair1 = new KeyValuePair<>(11, "eleven");
System.out.println(pair1);
KeyValueComparator<Integer, String> comparator1 = (KeyValueComparator<Integer, String>) pair1;
System.out.println("equalsKey = " + comparator1.equalsKey(12));
System.out.println("equalsValue = " + comparator1.equalsValue("eleven"));
KeyValuePair<String, Integer> pair2 = new KeyValuePair<>("twelve", 12);
System.out.println(pair2);
KeyValueComparator<String, Integer> comparator2 = (KeyValueComparator<String, Integer>) pair2;
System.out.println("equalsKey = " + comparator2.equalsKey("twelve"));
System.out.println("equalsValue = " + comparator2.equalsValue(11));
}
}
Output:
KeyValuePair [key=11, value=eleven]
equalsKey = false
equalsValue = true
KeyValuePair [key=twelve, value=12]
equalsKey = true
equalsValue = false

How to get all visible variables for a certain method in JDT

I want to develop an Eclipse plug-in which get all visible variables for a specific method.
For example:
public class testVariable {
String test1;
Object test2;
void method_test1(){
int test3,test4;
}
void method_test2(){
int test5,test6;
//get variable here!!!!
}
}
I just want to get visible variable is: test1, test2,test5,test6 in method method_test2. What can I do?
Actually, JDT can be used outside of a plug-in, i.e., it can be used in a stand-alone Java application.
The following code can return the variables you want:
public static void parse(char[] str) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(str);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
cu.accept(new ASTVisitor() {
public boolean visit(VariableDeclarationFragment var) {
System.out.println("variable: " + var.getName());
return false;
}
public boolean visit(MethodDeclaration md) {
if (md.getName().toString().equals("method_test2")) {
md.accept(new ASTVisitor() {
public boolean visit(VariableDeclarationFragment fd) {
System.out.println("in method: " + fd);
return false;
}
});
}
return false;
}
});
}
The output is:
variable: test1
variable: test2
in method: test5
in method: test6
Check out more examples at JDT tutorials.