I need to convert a Tree to a JavaTree. But i am getting ClassCastException, obviously.
public Javadoc(Tree tree) {
if (tree.is(METHOD_KINDS)) {
elementParameters = ((MethodTree) tree).parameters().stream().map(VariableTree::simpleName)
.map(IdentifierTree::name).collect(Collectors.toList());
elementExceptionNames = ((MethodTree) tree).throwsClauses().stream().map(Javadoc::exceptionName)
.filter(Objects::nonNull).collect(Collectors.toList());
} else if (tree.is(CLASS_KINDS)) {
elementParameters = ((ClassTree) tree).typeParameters().stream().map(TypeParameterTree::identifier)
.map(IdentifierTree::name).map(name -> "<" + name + ">").collect(Collectors.toList());
elementExceptionNames = Collections.emptyList();
} else {
elementParameters = Collections.emptyList();
elementExceptionNames = Collections.emptyList();
}
List<String> javadocLines = cleanLines(PublicApiChecker.getApiJavadoc((JavaTree)tree));
mainDescription = getDescription(javadocLines, -1, "");
blockTagDescriptions = extractBlockTags(javadocLines, Arrays.asList(BlockTag.values()));
undocumentedNamedTags = new EnumMap<>(BlockTag.class);
}
It happens in jadocLines variable. I have just a Tree, but i need to set a JavaTree for that getApiJavadoc, because of some methods and classes that it calls forward. I tried to create a javatree object and give my tree data to it. But i couldn't, 'cause JavaTree class is abstract. JavaTree class have other classes inside, but i am not getting this. Can anyone helps me in that part?
Edit 1 : Thanks for answers, but i cannot create another class as simples as that, because i need to give some arguments to the class i need that i do not have(because it dont even exist). The class i need to instantiate is:
public static class ImportTreeImpl extends JavaTree implements ImportTree {
private final boolean isStatic;
private final Tree qualifiedIdentifier;
private final SyntaxToken semicolonToken;
private final SyntaxToken importToken;
private final SyntaxToken staticToken;
public ImportTreeImpl(InternalSyntaxToken importToken, #Nullable InternalSyntaxToken staticToken,
Tree qualifiedIdentifier, InternalSyntaxToken semiColonToken) {
super(Kind.IMPORT);
this.importToken = importToken;
this.staticToken = staticToken;
this.qualifiedIdentifier = qualifiedIdentifier;
this.semicolonToken = semiColonToken;
isStatic = staticToken != null;
}
This class is inside JavaTree class and i need to instatiate it, but i dont have any SyntaxToken, and I cant create a null one to put here just for instantiate it. Can you help with this part?
OBS1: That JavaTree cast is wrong, i know, that was just a test. But Thank you!
EDIT2:I know that getApiChecker need a tree, but the problem is not the getApiChecker, but some methods that are called after. Look:
List<String> javadocLines = cleanLines(PublicApiChecker.getApiJavadoc(tree));
Calls :
#Nullable
public static String getApiJavadoc(Tree tree) {
if (!tree.is(API_KINDS)) {
return null;
}
ModifiersTree modifiersTree = getModifierTrees(tree);
// FIXME token should be retrieved in a much simpler way.
if (modifiersTree != null && !(modifiersTree.modifiers().isEmpty() && modifiersTree.annotations().isEmpty())) {
return getCommentFromTree(modifiersTree);
}
if (tree.is(Tree.Kind.METHOD)) {
MethodTree methodTree = (MethodTree) tree;
return getCommentFromMethod(methodTree);
}
return getCommentFromTree(tree);
}
That calls :
private static String getCommentFromTree(Tree tokenTree) {
return getCommentFromSyntaxToken(FirstSyntaxTokenFinder.firstSyntaxToken(tokenTree));
}
That calls:
#Nullable
public static SyntaxToken firstSyntaxToken(#Nullable Tree tree) {
if (tree == null || tree.is(Tree.Kind.INFERED_TYPE)) {
return null;
} else if (tree.is(Tree.Kind.TOKEN)) {
return (SyntaxToken) tree;
}
for (Tree next : ((JavaTree) tree).children()) {
SyntaxToken syntaxToken = firstSyntaxToken(next);
if (syntaxToken != null) {
return syntaxToken;
}
}
return null;
}
And my problem is :
for (Tree next : ((JavaTree) tree).children()) {
Because this is trying to make that cast, that bugs everything. And i can't change this last one, because this is a sonar code, and i can't change it.
Related
Take the following POJOs:
public class Widget {
private String fizz;
private Long buzz;
private List<Fidget> collaborators;
// Constructor, getters & setters
}
public class Fidget {
private String fizz;
private String foo;
// Constructor, getters & setters
}
And the following (working) method:
public void compriseWidgets(List<Fidget> fidgetList) {
List<Widget> widgets = new ArrayList<Widget>();
Widget currentWidget = null;
for (Fidget fidget : fidgetList) {
if (currentWidget == null ||
!currentWidget.getFizz().equals(fidget.getFizz())) {
currentWidget = new Widget();
widgets.add(currentWidget);
currentWidget.setFizz(fidget.getFizz());
currentWidget.setBuzz(fidget.getFoo().length());
}
currentWidget.getCollaborators().add(fidget);
}
return widgets;
}
Here we want to return a List<Widget> and populate that list only:
From the first Fidget in the input list (hence currentWidget == null); and
If the Fidget and currentWidget have the same fizz value
Furthermore, we want to keep appending collaborators to the currentWidget regardless of whether the fizzes match or not.
My problem
A new code style guideline is requiring that we declare ALL variables with final...meaning I need to get the above code refactored to look like so:
public void compriseWidgets(final List<Fidget> fidgetList) {
final List<Widget> widgets = new ArrayList<Widget>();
final Widget currentWidget = null;
for (final Fidget fidget : fidgetList) {
...
}
return widgets;
}
Because it requires both the creation of a new Widget inside the loop, but an external (outside the loop) reference to a Widget that we can add collaborators to, I'm at a total loss for how to rewrite this with final. Any ideas? Also, please note, this is nothing that I can "push back" on, I just need to figure it out and get it working with the new coding standard.
To expand on my comment, you could convert your example code more or less mechanically, like so:
public List<Widget> compriseWidgets(final List<Fidget> fidgetList) {
final List<Widget> widgets = new ArrayList<Widget>();
final Widget[] currentWidget = new Widget[] {null};
for (final Fidget fidget : fidgetList) {
if (currentWidget[0] == null ||
!currentWidget[0].getFizz().equals(fidget.getFizz())) {
currentWidget[0] = new Widget();
widgets.add(currentWidget);
currentWidget.setFizz(fidget.getFizz());
currentWidget.setBuzz(fidget.getFoo().length());
}
currentWidget.getCollaborators().add(fidget);
}
return widgets;
}
Many variables can be made final without any particular impact, including the lists of Fidgets and Widgets, and the loop variable in the enhanced for loop. The only other variable in the original method was currentWidget, which the implementation modifies. This can be replaced with a (final) array of length 1, whose zeroth element can then be used as a drop-in replacement for the original variable.
A more troublesome requirement along the same lines would be that you may not use assignment statements (initializers in variable declarations not being considered "assignments"). This is pushing toward a more functional style of programming, which I suppose may be the intent of your new guideline. You might, then, approach it something like this:
public List<Widget> compriseWidgets(final List<Fidget> fidgetList) {
final List<Widget> widgets = new ArrayList<Widget>();
final ListIterator<Fidget> fidgets = fidgetList.listIterator();
while (addWidget(widgets, fidgets)) { /* empty */ }
return widgets;
}
private boolean addWidget(final List<Widget> widgets, final ListIterator<Fidget> fidgets) {
if (fidgets.hasNext()) {
final Fidget firstFidget = fidgets.next();
final Widget currentWidget = new Widget();
widgets.add(currentWidget);
currentWidget.setFizz(firstFidget.getFizz());
currentWidget.setBuzz(firstFidget.getFoo().length());
currentWidget.getCollaborators().add(firstFidget);
while (fidgets.hasNext()) {
final nextFidget = fidgets.next();
if (currentWidget.getFizz().equals(nextFidget.getFizz())) {
currentWidget.getCollaborators().add(nextFidget);
} else {
fidgets.previous();
return true;
}
}
}
return false;
}
This is pretty much the same trick, just a little less obvious. The mutable state is hidden in the call stack (each invocation of addWidget() stands in for a mutation of the original method's currentWidget()) and in a container object, this time a ListIterator.
One could go further in the functional programming direction. In general, for example, you could look toward Stream-based approaches, though I don't think that works out completely cleanly in this particular case. More general functional programming does not have the constraints that apply to Streams, however.
The Builder design pattern is a great way to build immutable objects.
Source:
https://stackoverflow.com/a/15461337/4245294
What I love about this version of this design pattern is how it gives you the perfect spot for validation rules before object creation.
Example applied to this problem:
public class Widget {
private final String fizz;
private final Long buzz;
private final List<Fidget> collaborators;
private Widget(Builder builder) {
this.fizz = builder.fizz;
this.buzz = builder.buzz;
this.collaborators = builder.collaborators;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String fizz;
private Long buzz;
private List<Fidget> collaborators = new ArrayList<>();
public Builder addFizz(String fizz) {
this.fizz = fizz;
return this;
}
public Builder addBuzz(Long buzz) {
this.buzz = buzz;
return this;
}
public Builder addCollaborators(List<Fidget> fidgets) {
collaborators.addAll(fidgets);
return this;
}
public Builder addCollaborator(Fidget fidget) {
collaborators.add(fidget);
return this;
}
private void validate() throws InvalidArgumentException{
ArrayList<String> invalidArguments = new ArrayList<>();
boolean failedValidation = false;
if (collaborators.isEmpty()) {
invalidArguments.add("collaborators");
failedValidation = true;
}
if (this.fizz == null) {
invalidArguments.add("fizz");
failedValidation = true;
}
if (this.buzz == null) {
invalidArguments.add("buzz");
failedValidation = true;
}
if (failedValidation) {
throw new InvalidArgumentException(invalidArguments.toArray(new String[0]));
}
}
public Widget build() {
validate();
return new Widget(this);
}
}
}
And you create a valid Widget object like so:
Widget widget = Widget.builder().addFizz("test").addBuzz(999).addCollaborators(fidgets).build();
Your compriseWidget method has problems that I mentioned in a comment to the Question, otherwise I would provide an example for that as well.
I am trying to filter list but it returning null value for every search. I tried every possible ways but nothing happened. please help me on this
public class IssuerCreditDetailsUpdate implements ItemProcessor<Isin_Master, Issuer_credit_rating_details> {
protected final Logger logger = Logger.getLogger(this.getClass().getName());
static ArrayList<Credit_rating_details> Credit = new ArrayList<Credit_rating_details>();
private String validCreditRating = null;
#Override
public Issuer_credit_rating_details process(Isin_Master item) throws Exception {
Issuer_credit_rating_details row = new Issuer_credit_rating_details();
if(isCreditRatingValid(item.getIssuer_Id())!= null) {
row.setIssuer_id(item.getIssuer_Id());
row.setName_of_issuer(item.getIssuerName());
return row;
}
return null;
}
private String isCreditRatingValid(String issuerid) {
System.out.println(Credit.stream().filter(i-> i.getIssuer_id().contains(issuerid)).collect(Collectors.toList()));
List<Credit_rating_details> result = Credit.stream().filter(i-> i.getIssuer_id().contains(issuerid)).collect(Collectors.toList());
if(!result.isEmpty() ) {
validCreditRating = result.get(0).getCredit_rating();
return result.get(0).getCredit_rating();
}else {
return null;
}
}
}
Possibly, i-> i.getIssuer_id().contains(issuerid) is not matching the way you are expecting.
What is the type returned by Credit_rating_details.getIssuer_id()? Is it also a String?
Is it possible that the input issuerid and the Credit_rating_details issuer_id are in different cases?
Try i-> i.getIssuer_id().equalsIgnoreCase(issuerid) to see if you get a different result.
I am trying to brushup java after a long time.
Any help is much appreciated.
For demonstration I have Animal Class that has an array of innerclass of Organs.
public class Animal
{
String nameOfAnimal;
Organs [] vitalOrgans = new Organs[3];
public Animal()
{
}
public String getNameOfAnimal() {
return nameOfAnimal;
}
public void setNameOfAnimal(String nameOfAnimal) {
this.nameOfAnimal = nameOfAnimal;
}
#Override
public String toString() {
return "Animal{" + "nameOfAnimal=" + nameOfAnimal + "}";
}
class Organs{
String nameOfOrgan;
public String getNameOfOrgan() {
return nameOfOrgan;
}
public void setNameOfOrgan(String nameOfOrgan) {
this.nameOfOrgan = nameOfOrgan;
}
#Override
public String toString() {
return "Organs{" + "nameOfOrgan=" + nameOfOrgan + '}';
}
}
}
Now in driver file when I make call there is no syntactical error but I get "Exception in thread "main" java.lang.NoSuchFieldError: vitalOrgans"
Animal mamal = new Animal();
mamal.setNameOfAnimal("Chimp");
mamal.vitalOrgans[0].setNameOfOrgan("Heart");
System.out.println(mamal.vitalOrgans[0].getNameOfOrgan());
What would be the way to make this (or similar idea) to work.
Thanks.
You would need to initialize the vitalOrgrans with new Organs(). Like:
public Animal() {
for (int i = 0; i < vitalOrgans.length; i++) {
vitalOrgans[i] = new Organs();
}
}
Because when you say :
Organs[] vitalOrgans = new Organs[3];
You are creating an array of 3 null Organs. Hence the null pointer exception, when accessing "vitalOrgans[i].".
Taking the relevant bit of code:
public class Animal
{
//...
Organs [] vitalOrgans = new Organs[3];
//...
}
Since your declaration of vitalOrgans was never given an access modifier (i.e. one of private, public, protected) it took on default access, which means only other classes in the same package can see it. Since your other block of code is not in the same package, it cannot see the field.
A minimally viable modification to just make it work would be to set the access to public:
public class Animal
{
//...
public Organs [] vitalOrgans = new Organs[3];
//...
}
While this works, it's not necessarily the best solution, as if you ever change how vitalOrgans is represented, or need to perform any validation, those edits would have to be done throughout the application. Thus, a better solution (and also, a major stylistic convention in Java for those exact reasons) is to make it (and all your fields, in fact) private and access via methods:
public class Animal {
private String nameOfAnimal;
private Organs[] vitalOrgans = new Organs[3];
//...
public Organs[] getVitalOrgans() {
return vitalOrgans;
}
//Alternative accessor that fetches only one organ.
public Organs getVitalOrgan(int index) {
if(index >= 0 && index < vitalOrgans.length)
return vitalOrgans[index];
else
return null;
}
public void setVitalOrgans(Organs[] vitalOrgans) {
this.vitalOrgans = vitalOrgans
}
//...
}
Your caller could then access Organs via either form of the get method (note, you probably want Organs to be public):
Animal.Organs futureMammalHeart = mamal.getVitalOrgan(0); //Animal.Organs due to Organs being an inner class.
if(futureMammalHeart != null) //Demonstration of null check. Safety first!
futureMammalHeart.setNameOfOrgan("Heart");
Animal.Organs[] mammalianVitalOrgans = mamal.getVitalOrgans();
if(mammalianVitalOrgans != null) //Just in case...
System.out.println(mamal.mammalianVitalOrgans[0].getNameOfOrgan());
Also, as Ari mentioned in his answer, don't forget to initialize the organs in your array, otherwise you will get a NullPointerException!
I wrote a class in Java called Nod.java.
import java.util.ArrayList;
import java.util.Arrays;
class Nod {
int[] vol;
String op="";
Nod parent;
int adancime;
Nod (int[] vol, String op,Nod parent,int adancime){
this.vol=vol;
this.op=op;
this.parent = parent;
this.adancime=adancime;
}
public String toString() {
return op;
}
public int getAdancime() {
return adancime;
}
public ArrayList<Nod> getCale(ArrayList<Nod> lnoduri) {
lnoduri.add(0, this);
if (parent != null) lnoduri = parent.getCale(lnoduri);
return lnoduri;
}
public ArrayList<Nod> getCale()
{ return(getCale(new ArrayList<Nod>())); }
}
and I want to rewrite it in C++ but I don't know how to rewrite these two functions in C++:
public ArrayList<Nod> getPath(ArrayList<Nod> lnoduri) {
lnoduri.add(0, this);
if (parent != null) lnoduri = parent.getPath(lnoduri);
return lnoduri;
}
public ArrayList<Nod> getPath(){
return(getPath(new ArrayList<Nod>()));
}
These functions store the path of each nod to the parent.
Can you help me please?
EDIT
Because it is a related question, I add it here.
I wrote a function to "Vase" class in Java:
public ArrayList<Nod> succesori(Nod parent) {
// "Nod" is another class.
ArrayList<Nod> listTest = new ArrayList<Nod>();
// operations/conditions;
listTest.add(new Nod(vol,op,parent,adancime+1));
return(listTest);
}
and I want to rewrite in C++:
vector<Nod*> Vase::succesori(Nod *parinte)
{
vector<Nod*> *listTest = new vector<Nod*>();
// operations/conditions;
listTest.insert(new Nod(vol,op,parent,adancime+1));
return (*listTest);
}
But I get an error when I try to execut this command:
listTest.insert(new Nod(vol,op,parent,adancime+1));
IntelliSense: expression must have class type
Error 1 error C2228: left of '.insert' must have class/struct/union
How can I add/insert in listTest a new Nod class?
The Java code looks a bit strange. If you really want to use recursion, then I recommend rewriting the methods as follows.
public void getCale(ArrayList<Nod> lnoduri) {
if (parent != null) {
parent.getCale(lnoduri);
}
lnoduri.add(this);
}
public ArrayList<Nod> getCale() {
ArrayList<Nod> result = new ArrayList();
getCale(result);
return result;
}
In C++, I would use only one member function.
std::vector<Nod*> getCale()
{
std::vector<Nod*> result;
for (Nod* n = this; n; n = n->_parent) {
result.push_back(n);
}
std::reverse(result.begin(), result.end());
return result;
}
You can write a direct translation into C++, but if you do this the program will probably be difficult to maintain and slow. Just remember that all methods are virtual by default, objects are passed by pointer, and vector substitutes ArrayList:
virtual vector<nod*> *getCale(vector<nod*> *lnoduri) {
lnoduri->insert(lnoduri->begin(), this);
if (parent != nullptr) lnoduri = parent->getCale(lnoduri);
return lnoduri;
}
virtual vector<nod*> *getCale() {
return getCale(new vector<nod*>());
}
In Lucene, I am using the TaxonomyReader to read an index of a taxonomy stored in my disk. For a given category, I need to find all categories that are its children. However, in the Lucene's API I could find a method to retrieve the parent but not with the children. There is a method called getChildrenArrays() that returns a ChildrenArrays object. As you can see, this class only has two methods:
getYoungestChildArray
getOlderSiblingArray
I want to implement Enumerator using these two methods. Does someone know how to do it?
I got the following:
private class EnumChildren implements Enumeration<Integer> {
int category, current;
int[] next, first;
public EnumChildren(int category) {
ChildrenArrays childrenArrays = tr.getChildrenArrays();
first = childrenArrays.getYoungestChildArray();
next = childrenArrays.getOlderSiblingArray();
current = first[category];
}
public boolean hasChildren() {
return (current != TaxonomyReader.INVALID_ORDINAL);
}
#Override
public boolean hasMoreElements() {
current = next[current];
return (current != TaxonomyReader.INVALID_ORDINAL);
}
#Override
public Integer nextElement() {
return current;
}
}
Ans is used as:
ordinal = tr.getOrdinal(new CategoryPath(nodeCategory.getPath(), '/'));
EnumChildren childrenEnumeration = new EnumChildren(ordinal);
if (childrenEnumeration.hasChildren()) {
do {
int current = childrenEnumeration.nextElement();
Category child = new Category(tr.getPath(current).toString());
addChildren(child);
nodeCategory.children.add(child);
} while (childrenEnumeration.hasMoreElements());
}