Java Enum Returns Null - java

I am currently creating a plugin for Minecraft using the SpigotAPI. Reason I'm posting this here is because this I believe is a Java error. I am creating a duels plugin where inside my code it'll loop through an enum, and see if it's a specific type. The first time using it around it properly works, no problems. But when I try it for a second time without restarting my plugin/program/code it'll return the enum as null. Here is the code, is there a fix to this?
public DuelArenas[] getArenasWithType(DuelTypes type) {
String suffix = "_NORMAL";
List<DuelArenas> arenasAsList = new ArrayList<>();
switch (type) {
case NORMAL:
suffix = "_NORMAL";
break;
}
for (DuelArenas arena : duelArenaStatus.keySet()) {
if (arena.toString().endsWith(suffix)) {
arenasAsList.add(arena);
}
}
DuelArenas[] arenas = new DuelArenas[arenasAsList.size()];
return arenasAsList.toArray(arenas);
}
Stacktrace:
Caused by: java.lang.NullPointerException
at me.nick.acore.duels.DuelsAPI.getArenasWithType(DuelsAPI.java:97) ~[?:?]
And yes I've checked to see if the enum was null, and it was in fact null. Also line 97 is
if (arena.toString().endsWith(suffix)) {
And finally here is the DuelArena class
public enum DuelArenas {
ARENA_1_NORMAL, ARENA_2_NORMAL, ARENA_3_NORMAL, ARENA_4_NORMAL, ARENA_5_NORMAL,
ARENA_6_NORMAL, ARENA_7_NORMAL, ARENA_8_NORMAL, ARENA_9_NORMAL, ARENA_10_NORMAL,
ARENA_11_NORMAL, ARENA_12_NORMAL }
Thanks!

Your problem is that you cannot directly convert your custom DuelArenas class to a string. However when you are comparing to see if a .toString() ends with suffix, I feel that something is also going wrong. You would only ever use .toString to convert things like numbers to strings, and if your are converting a number to a string there is no way it will end in _NORMAL.
So if you want me to troubleshoot further please post your DuelArenas class, but until then my best guess is that when you do arena.toString you are looking to pull some sort of value from that class that is stored in it, and to do this you would do arena.variableInsideArenaName and work with that.
EDIT:
After seeing the class scratch that, the error in going to be somewhere in this line DuelArenas arena : duelArenaStatus.keySet()

Related

JavaCC creating custom Token class

I'm working on a school assignment for my compiler and interpreters course and our current task is to create a scanner and a set of tokens using JavaCC. I have a pretty solid understanding of how JavaCC works but my problem is finding resources online to help me out when I get stuck. I am working on creating a custom Token class, let's call it NewToken.Java. I know that the base Token class has an image variable and a kind variable but I want to implement my own variable "value". Furthermore I want to figure out how I can assign this value. I want the value variable to hold the literal value of what I scan, for example, my NewToken is being matched to the following
< IDENTIFIER:(< LETTER >)+ ( < LETTER > | < DIGIT >)* >
< #LETTER:["a" - "z"] >
< #DIGIT: ["0" - "9"] >
so something along the lines of Name123Name would get caught and when it does I want to store the string "Name123Name" into the 'value' variable of my NewToken object. I hope this makes sense, I am still new to JavaCC and may be calling things by there wrong name here.
public NewToken(){}
public NewToken(int kind){
this(kind,null);
}
public NewToken(int kind, String image){
this.kind=kind;
this.image=image;
this.value=image;
}
public String toString(){
return image;
}
public static Token newToken(int ofKind, String image){
switch(ofKind){
default : return new Token(ofKind, image);
}
}
public static Token newToken(int ofKind){
return newToken(ofKind, null);
}
}
Above is part of my code for the NewToken class, I have it extending Token and implementing java.io.serializable. I created by using the code generated for Token.java. I also have my variable declarations and my getValue() function which are not listed here to save space. I'm not looking for anyone to do my work for me I just need some guidance on how I would get this working, thank you in advance.
First off, I think the newToken routine should return objects of type NewToken rather than Token.
public static Token newToken(int ofKind, String image){
return new NewToken(ofKind, image);
}
public static Token newToken(int ofKind){
return new NewToken(ofKind, null);
}
(I don’t think you need that second method. But, I’m not completely sure, so I’ll leave it.)
It’s a bit unclear to me how you want value to differ from image, but I’m going to assume that you can compute the desired value for value from the image and the kind. And I’ll further assume that you have implemented this function as a static method.
private static String computeValue(int kind, String image) {...}
Delete the first two constructors and the remaining one should be:
private NewToken(int kind, String image){
this.kind = kind;
this.image = image;
this.value = computeValue( kind, image );
}
The answer that Professor Norvell is giving you is based on using a very old, obsolete version of JavaCC. The way he's suggesting you go about things is probably about the best way of doing it, if you were going to use the legacy JavaCC.
However, the most advanced version of JavaCC is JavaCC 21 and it handles this sort of use case straight out of the box in a very clean, elegant manner. See here for information on this specifically.
As you can see, you can put annotations in your grammar file that cause the various Token subclasses to be generated and used.
Also, JavaCC 21 has code injection that allows you to inject code directly into the any generated files, including the Token subclasses. That feature is not at all present in legacy JavaCC either. But using that, you could just inject your computeValue method right into the appropriate Token subclass.
INJECT NewToken :
{
private static String computeValue(int kind, String image) {...}
}
You put that in your grammar and the computeValue method just gets inserted into the generated NewToken.java file.
By the way, there is an article about JavaCC 21 that appeared recently on dzone.com.

JDBC SqlParameterValue - determine SQL Type of parameter

I'm working in Java and trying to determine something like so:
I have a SqlParameterSource with an array named "ids" in it. I need to determine what type these ids are in, for example numeric or varchar. I specify that earlier in the code with for example:
return con.createArrayOf("varchar")
or
return con.createArrayOf("numeric")
I have tried this:
if (parametersource.getSqlType("ids") == something) {
// do something
}
else {
//do something else
}
I can't figure out how to do this. getSqlType seems to return an int but I don't know what to compare it to to get the correct comparison.
There is another method named getTypeName but I don't get how this works.
I solved it with:
parameterSource.getValue("objtype").toString();
Fetches the value from "objtype" which I set in my ParameterSource alongside my array to make my end goal easier.
Thanks friends, I love you all. :)
If you're talking about Spring SqlParameterSource,try parametersource.getTypeName("ids")which is inherited from AbstractSqlParameterSource

Play 2.5: Form validation - on error, value of form is "Optional.empty"

I am developing an application with Play 2.5. Models and Form data are separate classes, so I have a class "Page" and "PageForm".
In PageForm is a method "validate()" which returns null if there was no error or a List if the validation failed:
public List<ValidationError> validate() {
List<ValidationError> errors = new ArrayList<>();
Page checkForDuplicatePage = PageRepository.getInstance().getByName(name);
if(checkForDuplicatePage != null && checkForDuplicatePage.id != id) {
errors.add(new ValidationError("name", "The name is already in use by another page"));
}
// ...
return errors.isEmpty() ? null : errors;
}
In my controller I call:
Form<PageForm> form = formFactory(PageForm.class).bindFromRequest();
This works really well if the data in the form is correct. However, if validate() finds an error (and it really doesn't matter what kind, even a return new ArrayList<>() triggers this), the "value" attribute of my form is Optional.empty. The "data" attribute actually has all the data passed to the form.
This means I can't use the form to pass it to my view, which should display the data with error messages. Instead I get a [CompletionException: java.util.NoSuchElementException: No value present]. Sometimes (I haven't figured out why that happens yet) it also says [CompletionException: java.util.NoSuchElementException: None.get].
I compared my code with other projects and the official docs, but they all seem to be doing what I have here.
I use Scala Play rather than Java, so YMMV. But to me, I don't think that validate should return null at all. It should return the empty ArrayList if there are no errors. I suspect that this will eliminate the None.get error message. I'm not sure how much I can help, though, because I don't really understand very well what your code is intended to do. For example, the sentence
However, if validate() finds an error (and it really doesn't matter what kind, even a return new ArrayList<>() triggers this)
seems kind of ambiguous to me. Where is the return new ArrayList<>() call that triggers the error?

java associative array sort of thing with more than one data type

imagine this:
DataTypeForConfigs config
with
String keys, but values of either String, Integer, or Boolean,
in Java, JSON can do that, but I'm making a format That goes along the lines of:
number "coolness" is 9001 means
int coolness = 9001;
It's method is: Read line, read each word, think what to make of it, set it to a Variable within it's reach
Also: what would happen if another thing had its own place to put config? a null would be read? WHY? constructor thinks a file has null on it? Rage face.
Say... should I make a class called SettingVal that when given a getValue() call it would say what it is?
SO:
config["Coolness"].getValue();
return's 9001
WAIT:
How on earth would I make the getValue() method? HOW? RETURN VALUE WONT LIKE THIS!! OH CRAP!
Solution:
Another Data type comes in and checks its 'gender' (String, Bool, Int) and then checks it's value of that 'gender' (strVal, boolVar, intVar)
Return values are a big problem when dealing with this. I need a stress free version, so maybe I can have a void returning method that runs another method based on what data type it is said to hold! Am I right?
I have a temporary solution, setVar works, getVar is get*Var, where * is Str, Bool or Int.
Sadly, I Haven't yet been able to properly read it from a file, the method I made to read from a file is not working. It makes a Map<String,SettingVar>, using a HashMap constructor and returns that map, but seems whenever I try to access a variable from it that variable is null. It is probably because of IOExceptions and FileNotFoundExceptions, FileNotFound? Why? It Shouldn't be running until called. Oh, and also NullPointerExceptions Please Help!
SUBQUESTION: what happens when you MapVariable.put({NAME HERE}, varToPutIn) many times in a for loop? what about MapVariable.put({NAME HERE},new ...)?
My code in links:
https://gist.github.com/anonymous/66c4d1c2d2718a4cc9b9
because I don't have enough reputation
P.S: OK! ive made the config reader work now, and SettingVar, and SettingContainer and im working on ConfigWriter which is good, now working on a prototype for a java command prompt like thing, and soon a WHOLE OS!! wait... java is an os. thats why java virtual machine... oh. Well, how can I close this question and turn the outcome into a revolutionary new thingy for kids who want to learn to code java *cough cough* especialy ones with higher learning ability than social ability... and like to hang around with mature people who dont bully them like all the kids in their school. (Wow, that was specific)
I would use a Plain Old Java Object which you can read from JSON.
class Config {
int coolness = 9001;
String hello = "world";
boolean cool = true;
}
This way you can have fields with a variety of types.
The type you're looking for is Map<String,Object>, but it is not type-safe and you'll have to do a bunch of casting:
Map<String,Object> config = new HashMap<>();
config.put("coolness",9001);
config.put("hello","world");
config.put("cool", true);
boolean cool = (Boolean) config.get("cool");
String hello = (String) config.get("world");
int coolness = (Integer) config.get("coolness");
Generally, I'd recommend creating a dedicated class for holding your configuration (each field = one property), which is strongly typed and doesn't require casting, and then use something like Jackson to serialize/deserialize it from json, yaml, or xml.
This provides structure to your configuration, and will cause any issues with malformed configurations to show up when you start your application/load your configuration, and not in the middle of your application.
SUBQUESTION: what happens when you MapVariable.put(varToPutIn) many times in a for loop?
A Map represents a mapping. If you do this:
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
map.put("myKey", Integer.valueOf(i));
}
what happens is that you add a mapping from "myKey" to zero, then update it to one, two, three and so on. When the loop ends, "myKey" will map to nine.
In short, the map entry for "myKey" is behaving like a variable of type Integer that you assign to repeatedly.
I'm afraid your Gists are telling me that you simply didn't take on board what #Darth Android wrote. Rather that hashing through your code, here's a simple way to parse your config file syntax (more or less) and load it into a Map<String, Object>
Note: I have not compiled or tested this code. It is written to be read and understood, rather than borrowed.
Map<String,Object> config = new HashMap<>();
try (Scanner s = new Scanner(new FileReader(someFile))) {
while (s.hasNext()) {
// Syntax is '<type> <name> is <value>'
String[] words = s.nextLine().split("\\s+");
if (words.length != 4 || !words[2].equals("is")) {
throw MySyntaxException("unrecognizable config");
}
String type = words[0];
String name = words[1];
String val = words[3];
switch (type) {
case "number":
map.put(name, Integer.valueOf(val));
break;
case "boolean":
map.put(name, Boolean.valueOf(val));
break;
case "string":
map.put(name, val);
break;
default:
throw MySyntaxException("unknown type");
}
} catch (NumberFormatException ex) {
throw MySyntaxException("invalid number");
}
}

Java : Parsing a Json formated String to Java

I do a Action on Middle ware and if its success i get the Value as
String result = ["RESULT","DELETE","OK"]
And in Case if the Operation is Failed i get the resposne as
String result = ["RESULT","DELETE","ERROR"]
I need to know if the Operation is success Or Fail so for this i have done this
public class Test {
public static void main(String args[]) {
String result = "[\"RESULT\",\"DELETE\",\"ERROR\"]";
if (!result.contains("ERROR")) {
System.out.println("success");
} else {
System.out.println("Failed");
}
}
This is working fine , but not sure if this has any negative impact / or in cases the code may Fail .
Please suggest if there is a better approach .
Your code can fail if, for instance, you get a success message containing ERROR (not likely, but can happen).
You should use a library to parse the result into a List/Array, look here on StackOverflow for a ton of solutions for parsing Json Strings to Objects in Java (Jackson is a library to do this, for instance).
You should also validate against a pre-set number of hypothesis, for instance, creating an enum for the possible result types, and checking if it's one of them.
I would suggest to use object presentation instead of array here:
{
"RESULT": {
"operation": "DELETE",
"status" : "ERROR"
}
}
There is you can find a lot of tools to parse JSON in Java objects:
http://www.json.org/
In other case it will be hard to extend set of codes. E.g.
String result = "[\"RESULT\",\"CREATE\",\"USER\", \"LOGIN\", \"ERROR\", \"SUCCESS\"]";
Was there error? or user with login ERROR was successfully created?
String[] result = {"RESULT","DELETE","OK"};
if(Arrays.asList(result).contains("OK"))
System.out.println("Ok");
Try Arrays.asList() method to check given arrays contains that element or not.

Categories