I'm quite new in Java and need some help implementing the following:
In a mongodb-instance I save follwing data-structure:
{
name: String,
type: String // or anything else that might make this task easier
data [Array of objects]
}
The data structure of the data field depends of the type of the document.
The type also declares a certain Class, that handles populating and parsing the data.
My idea of accomplishing something like this with my current knowlegde would be to have a HashMap<String, Class> and then registering the type and the appropriate class.
Another way (which I don't know yet how to implement) would be to store the excat classname as the type and then trying to cast this string to a Class, but since the HashMap-way would probably be easier I thought I'd rather try this way.
What would be a good approach solving this problem?
Related
I have a FieldDescriptor for a message field defined in my protocol buffer. I want to start constructing a value for that field, but I'm stuck trying to get a Message.Builder for that FieldDescriptor. The code I'm writing is extremely generic - It's designed to serialize between MongoDB and Protocol Buffers - so I can't use any specialized logic for the Objects I happen to be using today.
The FieldDescriptor's JavaType is MESSAGE. It's MessageType is a bit better, as it contains the message's Type, but the Type is in protocol buffer namespace, so I still can't use reflection to get a Message for it (at least not cleanly).
I'm not sure what else to do. Anyone know how to construct a Message.Builder from a FieldDescriptor?
If you have an instance of the containing type's builder, you can get the builder for the field with:
containingBuilder.getFieldBuilder(fieldDescriptor)
or you can get a new builder for a message of the field's type (but not specifically the field of the existing instance):
containingBuilder.newBuilderForField(fieldDescriptor)
If you don't have an instance of the containing type at all, but you know the containing class, you can do:
ContainingType.getDefaultInstanceForType()
.getField(fieldDescriptor)
.newBuilderForType()
If you don't even know the containing class (perhaps it isn't even in your jar), and all you have is a descriptor, then you can use DynamicMessage:
DynamicMessage.newBuilder(fieldDescriptor)
However, note that DynamicMessage only emulates the reflection interface of the real class; it is not actually an instance of the real class (as would be generated by protoc). Also, it is a lot slower than the real class.
What would you use if you wanted to pass a list of options into a function?
For example, if you have an interface to a server:
public interface Server {
public void authUser(String username, String password, <xyz> options);
}
What structure would use use for to pass a set of options? Something like a HashMap?
The reason I'm saying that it comes from tunnel vision is because I feel that this goes against Java standards. Java has method overloading. So if I get flames for raising the question I understand. But overall, maybe in different cases, would you ever pass bulk data in some collection and, if yes, which one?
Option1 : If you are choosing any collections like List or Set these are specific to an object . I mean,
Lets Assume, Set sets = new HashSet();
If I want 5 Object of different different class having no relationship to be send, then It would be very difficult to recognize that which Object is belong to which class while Iteration. So, I wont recommend Collections.
Option2 : If you are choosing Map, the same above problem may occurs while getting the Object Dynamically. So, This Options is also not recommended.
Option3 :
Why cann't you create your own DTO and in that DTO place your reqyired datastructure and pass it over.
If you want 5 different Object to be pass then, you can pass. If all are of same type then you may use Collection or array or Variable Arguement based on your scenerio.
I think anything Serializable is exactly the thing. If you can serialize the object, then you can pass (store, transmit...) it, passing it's properties in bulk. What format of serialized data to choose, is another question.
It depends on the data you want to pass.
You can use a map(hashmap) if you are passing key-value pairs.
If it is just a list of diffrent object, you can use List(ArrayList)
Other option is to create DTO(data transfer object) with getter and setter methods.
You may want to take a look at VARARGS feature that was introduced in JAVA5.
I'd suggest a Map [HashMap] as you can then access the argument values via their Keys.
I am deserialising a json object as below
{
"b":"value1",
"a":"value2",
"d":"value3",
"c":"value4",
"f":"value5",
"e":"value6"
}
But i am getting ClassCastException as below
java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap
My deserialisation code is
LinkedHashMap<String, String> map = new JSONDeserializer<LinkedHashMap<String, String>>().deserialize(JSONstring);
But when i use HashMap instead of LinkedHashMap it works but output gets sorted as below (Its not original order).
{
a=value2,
b=value1,
c=value4,
d=value3,
e=value6,
f=value5
}
I want to get the output in original order.
I found this related link
Flex JSON unable to properly serialize/deserialize LinkedHashMap
but didn't get how to use ObjectFactory.
I would appreciate any help!
Thanks in advance!
(Disclaimer: I just downloaded flexjson and debugged through its source code, so my answer might be slightly incomplete.)
In short:
You generally cannot get the entries in original order using flexjson.
Even writing a custom ObjectFactory will not work.
This is most likely intended and correct.
In detail:
First, the use of generics in new JSONDeserializer<LinkedHashMap<String,String>>() only affects the compilable code, flexjson cannot use this information to actually return a LinkedHashMap<String,String> (this is because the compiler removes the generic and the implementing class has no information of this generic type at runtime).
So, looking deeper into what happens during deserialization, it seems that during parsing the input string, the data is automatically converted to the correct type (string, date, number, list, etc.). This is done using some kind of autodetection of the required data type, because JSON does not provide type information in its data, so flexjson has a build-in list to support data types. It can also use custom mappings to assign values to object properties when proper class information is given (on serialization, flexjson adds a field class to the data to store this type information; or you can manually set this, see documentation).
But the main point is that - according to http://json.org -
An object is an unordered set of name/value pairs.
flexjson internally uses an (unordered) map to store the temporary object keys and values. Even if you tell flexjson to return the data as a LinkedHashMap the data is yet put into a HashMap before it will be converted to a LinkedHashMap, so the original order is not available at that point. (This might be fixed by replacing the map creation in flexjson.JSONTokener, line 442 with a LinkedHashMap but I didn't try that myself.)
Conclusion:
It looks like this behaviour even cannot be changed by providing a custom ObjectFactory, so as far as I understand the code, you cannot retain the original field order. (May I ask why this is important for your project?)
So, if anybody finds a solution anyway, don't hesitate to correct me.
This is again, I guess, a 'best practices' question because i can think of some inelegant ways of getting my use case implemented.
My use case is as follows
Im writing a MethodManager(sort of) module which helps in the end user dealing with actual method(function) calls through a UI.
For this specific purpose i have a methodDefinition class which is an object form of what a method(function) looks like to my system.
A brief overview of what my methodDefinition's members look like is as follows
methodName -- String
methodInputs -- ArrayList<String>
methodResultType -- enum(STRING,MAP,LIST)
methodResult -- <<variable, on the basis of methodResultType>>
Now methodResult is variable and can be any of String, Map or List based on what methodResultType is set as.
I have created a MethodResultType class to account for methodResultType and it looks as follows
public enum MethodResultType {
LIST,
MAP,
STRING;
}
Now i know i have to write a class to account for methodResult and its variable nature based on methodResultType but cant think of a non botched up way to.
Any suggestions/ pointers in this regard would be greatly appreciated.
Thanks
p1ng
List, Map and String have a common ancestor class: java.lang.Object. methodResult can thus be an Object.
You could also wrap the result and its type into a MethodResult object, that would provide methods such as getType(), getValueAsString(), getValueAsList() and getValueAsMap(). These last three methods would throw an IllegalStateException if the type of the value is not the type returned by the method.
I have an application that saves its context to XML. In this application, there is a hierarchy of classes, that all implement a common interface, and that represent different settings. For instance, a first setting class may be made of 4 public float fields, another one can be made of a sole HashMap.
I am trying to determine what is the best way to handle writing and reading to XML in a generic way. I read on this site a lot about JAXB and XStream for instance, which are able to make a specific class instance from XML.
However my question is related to the fact that the actual class can be anything that implement a given interface. When you read the XML file, how would you guess the actual class to instantiate from the XML data? How do you do that in your applications?
I thought that I could write the .class name in a XML attribute, read it and compare it to all possible class .class names, until I find a match. Is there a more sensible way?
Thanks
xstream should already take care of this and create the object of correct type.
The tutorial seems to confirm that:
To reconstruct an object, purely from the XML:
Person newJoe = (Person)xstream.fromXML(xml);
If you don't know the type, you will have to first assign it to the common interface type:
CommonInterface newObject = (CommonInterface)xstream.fromXML(xml);
// now you can either check its type or call virtual methods
In my case I just have a kind of header that stores the class name that is serialized and when de-serializing it I just use the header value to figure out to which class shall I de-serialize the values.
A best practice would to use an established, well documented XML parser/mapper. All of the serialization/deserialization work has been done, so you can worry about your business logic instead. Castor and Apache Axiom are two APIs that I have used to marshal/unmarshall(serialize/deserialize) Java Classes and XML.
http://www.castor.org
Apache Axiom