Bukkit Config - get Subsections and safe casting - java

I have the following config file:
arenas
arena1
info: infotest
info2: info2test
arena2
info: infotest
info2: info2test
So. Now i want to get one arena, and convert it to a arena object, i have a constructor there taking a Map. So i do following:
Arena a = new Arena((Map<String, Object>) getConfig().get("arenas.arena1"));
That is working. But: im getting the following warning in eclipse:
Type safety: Unchecked cast from Object to Map<String,Object>
I undestand why this apperas. but how can i change the way getting the informations to avoid this, so to make a "safe" cast?
And my second question: Now i want to get all the sub Map 's from arenas.""
and initialize them when the plugin loads. How can i get all of them? I cannot find something like arenas.getAll() or i dont know.. something like this.. anyone an idea?
Thank you.

For your first question, you can get the configuration section "arena1" and get all of the values as a Map without any warnings. To do this, use:
config.getConfigurationSection("arenas.arena1").getValues(false);
Alternatively, you can just put #SupressWarnings("unchecked") over the method where you're using that code. Since you know the type you're getting will be a Map, the warning doesn't really mean much, though some developers might consider this bad practice.
For your second question, you can use a similar method. getValues() is essentially a getAll() type of method, it gets a map of all of the keys and values in the section. So you could use:
config.getConfigurationSection("arenas").getValues(false);

Related

Incorrect number of arguments for type List<E>; it cannot be parameterized with arguments <JSONObject, JSONArray>

I have imported java.util.List interface.
trying to create a function as follow:
public List<JSONObject,JSONArray> getDetail(String s)
But it shows error as
"Incorrect number of arguments for type List; it cannot be parameterized with arguments <JSONObject, JSONArray>"
I have gone through many articles but they said ,import java.util.List instead java.awt.List but i already imported that.
Can anyone help here what i am missing here ?
I understand the problem here. This is what you are doing. Let's understand this by the below example.
This is the same error you are getting at compile time. So basically you are doing something wrong with the List. List can only store single elements but you are putting 2 elements (key & value). So Map is the data structure to store this kind of value. Below screenshot is your answer. Hope this is clear to you now.

Get variable name of object from an ArrayList

I am creating an ArrayList of JTextFields using the following code.
ArrayList<JTextField> cmp = new ArrayList<>();
cmp.add(txtAmount);
cmp.add(txtBillTo);
cmp.add(txtBranch);
After passing this ArrayList into a method, I need to print the "variable name" of the textfield. I can use the SetName and GetName to print some names. But I need the output as txtAmount, txtBillTo, txtBranch.
Is there anyway to find the variable name of textfield?
No, you can't do this. The information you are asking for is just not recorded. The only way to do it would be to store it yourself:
Map<String, JTextField> cmp = new HashMap<>();
cmp.put("txtAmount",txtAmount);
cmp.put("txtBillTo", txtBillTo);
cmp.put("txtBranch", txtBranch);
If you need to keep things in the same order you put them into the collection then use a LinkedHashMap instead of a HashMap as the HashMap may change the order.
What you are looking for would require reflection of method code, something supported by languages such as Scala via macros/compile time reflection. However Java itself does not support runtime or compile time reflection of method code, only runtime reflection of classes/fields/functions, although some people have pulled together their own Java parsers to grab the information from source files and others have pulled the information from the Class files debug information. Neither of which has an officially supported API.
Your best bet is to place the name that you want along with the field, which is obviously duplication and thus could diverge by accident but your options are limited.

How to create a variable name at runtime?

I am not able to create the name of the object at runtime. My statement is:
Map<String,String> objectName+""+lineNumber = new HashMap<String,String>();
It's giving me compiletime error. I want to create the HashMap object at runtime depending upon the line number.
Java is not a interpreted but rather a compiled language. So the compiler does not knows how to handle this. Such a thing might make sense in a scripting language.
If you need a custom Name for a "variable" maybe a construct like the following might make sense:
Map<String,Map<String,String>> varMap = new HashMap<String,Map<String,String>>();
varMap.put(objectName+" "+lineNumber, new HashMap<String, String>());
You can't do this directly in Java (without major tricks)
What you can (and probably should) do:
Put your Map in another map which has the 'variable' name as a key.
If you really want to do that you have to do code generation. For this again you have multiple options:
Generate Java Source Code and compile it
Generate Java Byte Code on the fly. You might wanna look at this list: http://java-source.net/open-source/bytecode-libraries for libraries available.
Having a dynamic object name is of No Use.
At first, it's not possible to give reference a dynamic name. The bigger question is Why do you want to do it?
If, just for learning and doing experiments, I'll suggest you should follow proper exercises.
But, if you are trying to achieve some project requirement, Pls. explain the requirement. There will be some other way to achieve that.

How to properly get a Collection out of an Entity using getProperty()

When I put an ArrayList into an Entity using setUnindexedProperty(), how does it come back out?
I'm doing this:
Collection<Key> keys = (Collection<Key>) entity.getProperty(propName);
And I get this warning:
warning: [unchecked] unchecked cast
found : java.lang.Object
required: java.util.Collection<com.google.appengine.api.datastore.Key>
Collection<Key> keys = (Collection<Key>) entity.getProperty(propName);
Is this the best I can do? Is there at least a way to get rid of the warning?
UPDATE: I do not get this warning on other entity.getProperty() calls that return an object that I downcast to, say a String or a Blob.
entity.getProperty() returns an Object. It has no way of knowing what you're actually putting in or getting out, so it's always going to warn you unless you #SuppressWarnings. If you aren't comfortable doing it this way you have to use something like Objectify/Twig/JDO instead of the native datastore.
You can use the following annotation to ignore the unchecked cast warning.
#SuppressWarnings("unchecked")
But that assumes that you want to suppress the warnings rather than to fix the issue that it complained about.

Passing information between Java LoginModules (Generic Map Problem)

I am currently trying to write some LoginModules to enable users to log into a Java application. Here is my .java.login.config file:
"Java Application" {
path.to.login.module.PamLoginModule sufficient;
path.to.login.module.OtherLoginModule sufficient;
};
So if the PamLoginModule fails, I want to pass information to the OtherLoginModule. This way, the OtherLoginModule doesn't have to ask for the user name and password again. So I am guessing that this is what the sharedState Map is for in the initialize() function:
initialize(Subject subject, CallbackHandler callbackHandler,
Map<String,?> sharedState, Map<String,?> options)
The problem is that you can't put things into the sharedState map. If I do something like:
sharedState.put("key", value); // Value is a string
The compiler complains:
path/to/login/module/PamLoginModule.java:48: put(java.lang.String,capture#833 of ?) in java.util.Map<java.lang.String,capture#833 of ?> cannot be applied to (java.lang.String,java.lang.String)
this.sharedState.put("key", value);
I have found a way to get around this, but I want to know what the correct way is.
First, I can use the java 1.4.2 version of initialize which is:
initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
This way I just receive generic maps and I can just cast the Map object to a Map
Map<String,Object> this.sharedState = (Map<String,Object>)sharedState;
The problem is that I still get unchecked cast exceptions. Now, I know the people who made the LoginModule interface aren't stupid, so I am wondering why they made the sharedState map a Map<String,?> as opposed to a Map<String,Object>. Also, is there a better way to put things into the sharedState map?
Thanks!
If you look at the LoginModule implementations in the Java SDK, they save those maps into local fields without the generics info, that is plain Maps. And in the code they do put objects there (at least when the user is authenticated). So the use of the question mark in the LoginModule interface has to be a design mistake.
I am wondering why they made the
sharedState map a Map<String,?> as
opposed to a Map<String,Object>.
This is exactly what I'm wondering.
I guess the purpose of using ? is to accept anything (I don't really see another explanation), so using Object would be completely right and standard.
If you're posting here I guess you cannot ask who coded it this way (using ?) to know why.
Therefore you should investigate a bit the related classes/methods to discover if there is really a meaningful and specific use for ?. Otherwise you should make it a <String, Object>.
I've personnally never seen that current use, except when ? is specified as <? implements MyInterface> or <T extends MySuperClass> for example. In the first case, you should be able to do Map<String, MyInterface> anyway with the same result.
Sorry if I don't have a specific answer but I hope this helps you!

Categories

Resources