What is the structure of JSON to be read by google-gson - java

I was wondering, given the following JSON, how I can produce a ResultSet instance, which carry Query valued ppb?
package jsontest;
import com.google.gson.Gson;
/**
*
* #author yccheok
*/
public class Main {
public static class ResultSet {
public String Query;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
final String s = "{\"ResultSet\":{\"Query\":\"ppb\"}}";
System.out.println(s);
Gson gson = new Gson();
ResultSet resultSet = gson.fromJson(s, ResultSet.class);
// {}
System.out.println(gson.toJson(resultSet));
// null?
System.out.println(resultSet.Query);
}
}
Currently, here is what I get :
{"ResultSet":{"Query":"ppb"}}
{}
null
Without modified the String, how can I get a correct Java object?

Try first to construct a new object, call gson.toJson(object), and see the result.
I don't have gson, but jackson (another object-to-json mapper) prints this:
{"Query":"ppb"}
So, you don't include the class name. Actually, the gson user guide gives an example showing exactly this. Look at the BagOfPrimitives.
(And a final note - in Java, the accepted practice is that variables are lowercase - i.e. query rather than Query)
Update If you really can't change the json input, you can mirror the structure this way:
public static class Holder {
public ResultSet ResultSet;
}
public static class ResultSet {
public String Query;
}
(and then use Holder h = gson.fromJson(s, Holder.class);)

Related

How to create object using this given constructor

public Life(List<class> classes, int schoolwork) {
super(classes, schoolwork);
}
I am trying to make a Life object out of this code but am not doing it right what I have is
Life life = new Life();
but I can't figure out how to get the parameters right to include classes and schoolwork.
I tried to interpret your problem and I wrote a piece of code where I show you how to create a Life object by passing it the correct parameters.
Maybe your problem was creating the List object (?)
CODE
public class Main {
public static void main(String[] args) throws IOException {
List<CustomClass> customClass = new ArrayList<>();
int schoolwork = 1;
Life life = new Life(customClass, schoolwork);
}
}
class CustomClass {
}
class Life {
/**
* Constructor
*
* #param customClass
* #param schoolwork
*/
public Life(List<CustomClass> customClass, int schoolwork) {
// super(strings, schoolwork);
}
}

Cannot read or serialize POJO with enumerations using Java MongoDB driver

I have an existing object that I want to serialize in MongoDB using Java + POJO codec. For some reason the driver tries to create an instance of an enum instead of using valueOF:
org.bson.codecs.configuration.CodecConfigurationException: Failed to decode 'phase'. Failed to decode 'value'. Cannot find a public constructor for 'SimplePhaseEnumType'.
at org.bson.codecs.pojo.PojoCodecImpl.decodePropertyModel(PojoCodecImpl.java:192)
at org.bson.codecs.pojo.PojoCodecImpl.decodeProperties(PojoCodecImpl.java:168)
at org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:122)
at org.bson.codecs.pojo.PojoCodecImpl.decode(PojoCodecImpl.java:126)
at com.mongodb.operation.CommandResultArrayCodec.decode(CommandResultArrayCodec.java:52)
The enumeration:
public enum SimplePhaseEnumType {
PROPOSED("Proposed"),
INTERIM("Interim"),
MODIFIED("Modified"),
ASSIGNED("Assigned");
private final String value;
SimplePhaseEnumType(String v) {
value = v;
}
public String value() {
return value;
}
public static SimplePhaseEnumType fromValue(String v) {
for (SimplePhaseEnumType c: SimplePhaseEnumType.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}}
And the class the uses the enumeration (only showing the relevant fields):
public class SpecificPhaseType {
protected SimplePhaseEnumType value;
protected String date;
public SimplePhaseEnumType getValue() {
return value;
}
public void setValue(SimplePhaseEnumType value) {
this.value = value;
}}
I was looking for a way to maybe annotate the class to tell the driver to use a different method to serialize / deserialize those fields when they are encountered. I know how to skip them during the serialization / deserialization but that doesn't fix the problem:
public class SpecificPhaseType {
#BsonIgnore
protected SimplePhaseEnumType value;
Any help on where I could look (code, documentation)?. I already checked PojoQuickTour.java, MongoDB Driver Quick Start - POJOs and POJOs - Plain Old Java Objects
Thanks!
--Jose
I figured out what to do, you first need to write a custom Codec to read and write the enum as a String (an ordinal is another option if you want to save space, but string was more than OK with me):
package com.kodegeek.cvebrowser.persistence.serializers;
import com.kodegeek.cvebrowser.entity.SimplePhaseEnumType;
import org.bson.BsonReader;
import org.bson.BsonWriter;
import org.bson.codecs.Codec;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;
public class SimplePhaseEnumTypeCodec implements Codec<SimplePhaseEnumType>{
#Override
public SimplePhaseEnumType decode(BsonReader reader, DecoderContext decoderContext) {
return SimplePhaseEnumType.fromValue(reader.readString());
}
#Override
public void encode(BsonWriter writer, SimplePhaseEnumType value, EncoderContext encoderContext) {
writer.writeString(value.value());
}
#Override
public Class<SimplePhaseEnumType> getEncoderClass() {
return SimplePhaseEnumType.class;
}
}
Then you need to register the new codec so MongoDB can handle the enum using your class:
/**
* MongoDB could not make this any simpler ;-)
* #return a Codec registry
*/
public static CodecRegistry getCodecRegistry() {
final CodecRegistry defaultCodecRegistry = MongoClient.getDefaultCodecRegistry();
final CodecProvider pojoCodecProvider = PojoCodecProvider.builder().register(packages).build();
final CodecRegistry cvePojoCodecRegistry = CodecRegistries.fromProviders(pojoCodecProvider);
final CodecRegistry customEnumCodecs = CodecRegistries.fromCodecs(
new SimplePhaseEnumTypeCodec(),
new StatusEnumTypeCodec(),
new TypeEnumTypeCodec()
);
return CodecRegistries.fromRegistries(defaultCodecRegistry, customEnumCodecs, cvePojoCodecRegistry);
}
Jackson makes it easier to register custom serializer/ deserializer with annotations like #JsonSerializer / #JsonDeserializer and while Mongo forces you to deal with the registry. Not a big deal :-)
You can peek at the full source code here. Hope this saves some time to anyone who has to deal with a similar issue.

Passing variable values to the eval function

When this piece of code is executed the program uses the matlabcontrol library to open MATLAB and execute the given lines inside the eval(). The problem is in the first line i.e. m.eval("image1=imread('D:/My Hand Gestures/f.jpg');"); takes a fixed String value as input. But here i want to store the path in a variable and pass it to the imread() function. How am i supposed to do that? Any help is appreciated. Here is the code.
package Interface;
import matlabcontrol.MatlabConnectionException;
import matlabcontrol.MatlabInvocationException;
import matlabcontrol.MatlabProxy;
import matlabcontrol.MatlabProxyFactory;
/**
*
* #author Rajdeep
*/
public class Output {
private static String check;
private static String path;
Output(){
//default constructor
}
Output(String s,String p){
check = s;
path=p;
}
//GrayScale Conversion Function
public static void grayScale(String p,MatlabProxy m)throws MatlabConnectionException, MatlabInvocationException{
m.eval("image1=imread('D:/My Hand Gestures/f.jpg');");
m.feval("image1","imread(path)");
m.eval("figure,imshow(image1);");
m.eval("image_gray=rgb2gray(image1);");
m.eval("figure,imshow(image_gray);");
m.eval("final_image=imresize(image_gray,0.03125);");
m.eval("figure,imshow(final_image);");
m.eval("imwrite(final_image,'C:/Users/Desktop/f.jpg');");
//Disconnect the proxy from MATLAB
m.disconnect();
}
//Median Filtering Function
public static void Filter(String p, MatlabProxy m)throws MatlabConnectionException, MatlabInvocationException{
m.eval("I=imread('D:/gestures/f.jpg');");
m.eval("J = medfilt2(I, [4 4]);");
m.eval("figure,imshow(J);");
m.eval("imwrite(J,'C:/Users/Rajdeep/Desktop/f.jpg');");
//Disconnect the proxy from MATLAB
m.disconnect();
}
/**
*
* #param args
* #throws MatlabConnectionException
* #throws MatlabInvocationException
*/
public static void main(String[] args) throws MatlabConnectionException, MatlabInvocationException
{
//Create a proxy, which we will use to control MATLAB
MatlabProxyFactory factory = new MatlabProxyFactory();
MatlabProxy proxy = factory.getProxy();
Output out=new Output("GrayScale","D:/My Hand Gestures/f.jpg");
if(check == "GrayScale") {
grayScale(path, proxy);
}
if(check== "Filter"){
Filter(path,proxy);
}
}
}
Here i created a path variable that has a predefined path. I want to use this variable instead of giving the path as in the above mentioned process.
I would try this to start with. See if it helps.
String path_variable = "D:/My Hand Gestures/f.jpg";
m.eval("image1=imread('" + path_variable + "');");

How to translate the AST generated by ANTLR 4 to its source code

I am writing a simple parser to translate the query to SQL.
I've completed the parser and got the AST, but now I need to translate those grammar to SQL using ANTLR 4.
Does anybody knows how to print or translate the query "SELECT" as "SELECT", "FROM" to "FROM", etc in ANTLR 4?
I have followed the definitive ANTLR 4 reference book. In that we have to create 2 java files.
In the 1st java file I thought to follow these steps but instead of
public void enterInit(ArrayInitParser.InitContext ctx)
{
System.out.print('"');
}
I have changed to
public void enterSelect(ArrayInitParser.SelectContext ctx)
{
System.out.print('SELECT');
}
ShortToUnicodeString.java
public class ShortToUnicodeString extends ArrayInitBaseListener
{
/** Translate { to " */
#Override
public void enterInit(ArrayInitParser.InitContext ctx)
{
System.out.print('"');
}
/** Translate } to " */
#Override
public void exitInit(ArrayInitParser.InitContext ctx)
{
System.out.print('"');
}
/** Translate integers to 4-digit hexadecimal strings prefixed with \\u */
#Override
public void enterValue(ArrayInitParser.ValueContext ctx)
{
// Assumes no nested array initializers
int value = Integer.valueOf(ctx.INT().getText());
System.out.printf("\\u%04x", value);
}
}
In the 2nd java file I followed these steps:
Translate.java
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
public class Translate
{
public static void main(String[] args) throws Exception
{
// create a CharStream that reads from standard input
ANTLRInputStream input = new ANTLRInputStream(System.in);
// create a lexer that feeds off of input CharStream
ArrayInitLexer lexer = new ArrayInitLexer(input);
// create a buffer of tokens pulled from the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer);
// create a parser that feeds off the tokens buffer
ArrayInitParser parser = new ArrayInitParser(tokens);
ParseTree tree = parser.init(); // begin parsing at init rule
// Create a generic parse tree walker that can trigger callbacks
ParseTreeWalker walker = new ParseTreeWalker();
// Walk the tree created during the parse, trigger callbacks
walker.walk(new ShortToUnicodeString(), tree);
System.out.println(); // print a \n after translation
}
}
TRIED WITH STRINGTEMPLATE
I have tried with StringTemplate in antlr 4. I can able to translate the query select, from, where but when I translate the query and I couldn't. My code looks like:
import org.stringtemplate.v4.*;
public class ToSql extends BaseListener
{
/** Translate select to select */
#Override
public void enterSelect( Parser.SelectContext ctx)
{
ST select = new ST("select");
System.out.print(select.render()+"\t");
}
/** Translate from to from */
#Override
public void enterFrom( Parser.FromContext ctx)
{
ST from = new ST("from");
System.out.print(from.render()+"\t");
}
/** Translate where to where */
#Override
public void enterWhere( Parser.WhereContext ctx)
{
ST where = new ST("where");
System.out.print(where.render()+"\t");
}
/** Translate boolOp to AND|OR|XOR */
#Override
public void enterBoolOp( Parser.BoolOpContext ctx)
{
ST boolOp = new ST("<and>");
if (boolOp == and)
{
boolOp.add("and", "AND");
System.out.print(boolOp.render()+"\t");
}
}
}
PART OF MY GRAMMAR:
boolOp : OR|XOR|AND;
Thank you.
I don't know how code generation works in v4, but in my little experience, i think you could accomplish this by doing syntax directed translation by making your rules in your grammar spit out the generated output.
boolOp returns[String output] : OR {$output=$OR.text}
| XOR {$output=$XOR.text}
| AND{$output=$AND.text}
;
Then in your select statement, you could also do same to return string "select" "where" etc.
You could walk the tree and print out the output by passing the object of the walker to sysout.
You just have to work on your formatting(newline,tab etc) to have a good pretty print output.

Automatically opening and closing connection

NOTE: Please ignore my use of MultivaluedMap instead of multiple vargs String...args.
Is there a standard way in java of doing this?
What I have is a resource, that is returned from a remote server. But before each query, the remote connection must be open, and after the returns are returned - it must be closed.
So a natural way of doing this is something like:
Connection c = config.configureConnection();
c.open(); //open
List<Car> cars;
try{
cars = c.getCars();
}finally{
c.close(); //close
}
Now I want to implement something that operates on the level of the resources themselves, without worrying about connection, for example:
List<Car> cars = new CarResource().all(); //opens and closes connection
The way I am currently doing it is by having one abstract class, AbstractQueriable call abstract methods query(String ...args) and query(int id), which any class extending it must implement.
The AbstractQuerieable implements the Queriable interface, which makes it expose the three public methods filter(String ...args), all() and get(int id) - which are the public facing methods.
Here is the Queriable interface:
public interface Queriable <T>{
public T get(String id);
/** Simply returns all resources */
public Collection<T> all();
public Collection<T> filter(MultivaluedMap<String, String> args);
}
here is the AbstractQueriable class that implements it:
public abstract class AbstractQueriable<T> implements Queriable<T> {
#Override
public final T get(String id) {
setup();
try {
return query(id);
} finally {
cleanup();
}
}
#Override
public final Collection<T> filter(MultivaluedMap<String, String> args) {
setup();
try {
return query(args);
} finally {
cleanup();
}
}
/**
* Returns all resources.
*
* This is a convenience method that is equivalent to passing an empty
* arguments list to the filter function.
*
* #return The collection of all resources if possible
*/
#Override
public final Collection<T> all() {
return filter(null);
}
/**
* Queries for a resource by id.
*
* #param id
* id of the resource to return
* #return
*/
protected abstract T query(String id);
/**
* Queries for a resource by given arguments.
*
* #param args
* Map of arguments, where each key is the argument name, and the
* corresponing values are the values
* #return The collection of resources found
*/
protected abstract Collection<T> query(MultivaluedMap<String, String> args);
private void cleanup() {
Repository.close();
}
private void setup() {
Repository.open();
}
and finally my resource, which I want to use in the code, must extend the AbstractQueriable class, for example (please note that the details of these methods are not important):
public class CarRepositoryResource extends AbstractQueriable<Car> {
#Override
protected Car query(String id) {
MultivaluedMap<String, String> params = new MultivaluedMapImpl();
params.add("CarID", id);
// Delegate the query to the parametarized version
Collection<cars> cars = query(params);
if (cars == null || cars.size() == 0) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
if (cars.size() > 1) {
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
return cars.iterator().next();
}
#Override
protected Collection<Car> query(MultivaluedMap<String, String> params) {
Collection<Car> cars = new ArrayList<Car>();
Response response = Repository.getConnection().doQuery("Car");
while (response.next()) {
Returned returned = response.getResult();
if (returned != null) {
cars.add(returned);
}
}
return cars;
}
}
which finally, I can use in my code:
Collection<Car> cars = new CarRepositoryResource().all();
//... display cars to the client etc...
There are a few things I don't like about this kind of setup:
I must instantiate a new instance of my "CarRepositoryResource" every time I do a query.
The method names "query", while internal and private, are still confusing and clunky.
I am not sure if there is a better pattern or framework out there.
The connection that I am using does not support/implement the JDBC api and is not sql-based.
You could use a variation of the (in)famous Open session in view pattern.
Basically it comes down to this:
Define a "context" in which connections are available
(usually the request in web applications)
Handle (possibly lazy) initialization and release of a connection when entering/exiting the context
Code your methods taking for granted they will only be used inside such a context
It is not difficult to implement (storing the connection in a static ThreadLocal to make it thread safe) and will definitely spare a few open/close calls (performance-wise that could be a big gain, depending on how heavy your connection is).
The context class could look something like (consider this pseudo-code);
public class MyContext{
private static final
ThreadLocal<Connection> connection = new ThreadLocal<Connection>();
public static void enter() {
connection.set(initializeConnection());
// this is eager initialization
// if you think it will often the case that no connection is actually
// required inside a context, you can defer the actual initialization
// until the first call to get()
}
public static void exit() {
try { connection.close(); }
catch(Throwable t) { /* panic! */ }
finally { connection.set(null); }
}
public static Connection get() {
Connection c = connection.get();
if (c == null) throw new IllegalStateException("blah blah");
return c;
}
}
Then you would use connections like this:
MyContext.enter();
try {
// connections are available here:
// anything that calls MyContext.get()
// gets (the same) valid connection instance
} finally {
MyContext.exit();
}
This block can be put wherever you want (in webapps it usually wraps the processing of each request) - from the main method if you are coding a simple case when you want a single connection available for the whole lifespan of your application, to the finest methods in your API.
You might want to take a look at fluent interfaces (with an interesting example here) and its "Builder" pattern.
You would query like this:
cars().in(DB).where(id().isEqualTo(1234));
This way you can hide the connection/disconnection code in the outermost cars() method, for example.

Categories