I have two POJOs (Person.java and User.java) that contain similar information. See below:
public class Person {
private String first_name;
private String last_name;
private Integer age;
private Integer weight;
private Integer height;
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}
public class User {
private String name_first;
private String name_last;
private Integer my_age;
private Integer my_weight;
private String social_security;
public String getName_first() {
return name_first;
}
public void setName_first(String name_first) {
this.name_first = name_first;
}
public String getName_last() {
return name_last;
}
public void setName_last(String name_last) {
this.name_last = name_last;
}
public Integer getMy_age() {
return my_age;
}
public void setMy_age(Integer my_age) {
this.my_age = my_age;
}
public Integer getMy_weight() {
return my_weight;
}
public void setMy_weight(Integer my_weight) {
this.my_weight = my_weight;
}
public String getSocial_security() {
return social_security;
}
public void setSocial_security(String social_security) {
this.social_security = social_security;
}
}
I have defined a mapping.json file as shown below using GSON.
{
"columnMap": [
{
"userColumn": "name_first",
"personColumn": "first_name"
},
{
"userColumn": "last_first",
"personColumn": "first_last"
},
{
"userColumn": "my_age",
"personColumn": "age"
},
{
"userColumn": "my_weight",
"personColumn": "weight"
}
]
}
public class Mapping {
private ArrayList<Pair> columnMap;
public Mapping(){
columnMap = new ArrayList<>();
}
public ArrayList<Pair> getColumnMap() {
return columnMap;
}
public void setColumnMap(ArrayList<Pair> columnMap) {
this.columnMap = columnMap;
}
}
I am writing a utility class helper function that converts between a Person and User object the mapped pairs.
public class Pair {
private String userColumn;
private String personColumn;
public String getUserColumn() {
return userColumn;
}
public void setUserColumn(String userColumn) {
this.userColumn = userColumn;
}
public String getPersonColumn() {
return personColumn;
}
public void setPersonColumn(String personColumn) {
this.personColumn = personColumn;
}
public static void main(String args[]){
}
}
My question is below:
As you can see the returnVal object is being set by me (the programmer) to convert from a User POJO to a Person POJO. How do I leverage the pre-defined mapping.json to do this? The reason I am asking is in the future, the mapping.json file may change (maybe the weight mapping no longer exists). So I am trying to avoid re-programming this Utility.userToPerson() function. How can I achieve this? I am thinking Java reflection is the way to go, but I would like to hear back from the Java community.
public class Utility {
public static Person userToPerson(User u){
Person returnVal = new Person();
returnVal.setAge(u.getMy_age()); // <-- Question How do I leverage mapping.json here?
returnVal.setFirst_name(u.getName_first());
returnVal.setLast_name(u.getName_last());
returnVal.setWeight(u.getMy_weight());
return returnVal;
}
}
You can introspect the beans (i.e. User and Person) for the field names and call corresponding getter from User to fetch the value. Later call corresponding setter in Person.
Here I have taken userToPersonFieldsMap for mapping the field, you can load mapping from JSON file and construct the map accordingly.
Important code section is the for loop, where it dynamically calls getter and setter and does the job.
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public class UserToPersonMapper {
public static void main(String[] args) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
Map<String, String> userToPersonFieldsMap = new HashMap<>();
userToPersonFieldsMap.put("name_first", "first_name");
userToPersonFieldsMap.put("last_first", "first_last");
userToPersonFieldsMap.put("age", "personAge");
//existing user
User user = new User("Tony", "Stark", 20);
//new person - to be initialised with values from user
Person person = new Person();
for (Map.Entry<String, String> entry : userToPersonFieldsMap.entrySet()) {
Object userVal = new PropertyDescriptor(entry.getKey(), User.class).getReadMethod().invoke(user);
new PropertyDescriptor(entry.getValue(), Person.class).getWriteMethod().invoke(person, userVal);
}
System.out.println(user);
System.out.println(person);
}
}
class User {
private String name_first;
private String last_first;
private int age;
public User(String name_first, String last_first, int age) {
this.name_first = name_first;
this.last_first = last_first;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName_first() {
return name_first;
}
public String getLast_first() {
return last_first;
}
public void setName_first(String name_first) {
this.name_first = name_first;
}
public void setLast_first(String last_first) {
this.last_first = last_first;
}
#Override
public String toString() {
return "User{" +
"name_first='" + name_first + '\'' +
", last_first='" + last_first + '\'' +
", age=" + age +
'}';
}
}
class Person {
private String first_name;
private String first_last;
private int personAge;
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public void setFirst_last(String first_last) {
this.first_last = first_last;
}
public String getFirst_name() {
return first_name;
}
public String getFirst_last() {
return first_last;
}
public int getPersonAge() {
return personAge;
}
public void setPersonAge(int personAge) {
this.personAge = personAge;
}
#Override
public String toString() {
return "Person{" +
"first_name='" + first_name + '\'' +
", first_last='" + first_last + '\'' +
", personAge=" + personAge +
'}';
}
}
You can tweak and try it out this example to make it more align with your requirement.
Note:
This solution uses reflection.
this is a class called Doglist to add the object to an array.
public class DogList {
private int numItems;
private DogItem[] dogListArray;
private int position;
DogList () {
numItems=0;
position = 0;
dogListArray = new DogItem[10];
}
public void add (DogItem item) {
dogListArray[numItems++]= new DogItem(item.getName(),
item.getBreed(),
item.getWeight(),
item.getOwner1(),
item.getOwner2()
);
}
public String toString() {
String result = "";
for (int i=0; i<numItems; i++) {
result += dogListArray[i].toString() + "\n";
}
return result;
}
public DogItem searchForDogItem (DogItem gi) {
System.out.println("Here is your obj value: " + gi );
return null;
}//This is the one im having trouble with.
}
I have all the setters and getters in the DogItem class.
and this is from the UI where i get the dog info(name, breed, weight, owners1&2 names)
public void searchForItem (String name ) {
DogItem gi = new DogItem (name);
gi = gl.searchForDogItem(gi);
if (gi==null) {
msgTextField.setText("Dog Not Found");
} else {
nameTextField.setText(String.valueOf(gi.getName()));
breedTextField.setText(String.valueOf(gi.getBreed()));
weightTextField.setText(String.valueOf(gi.getWeight()));
owner1TextField.setText(String.valueOf(gi.getOwner1()));
owner2TextField.setText(String.valueOf(gi.getOwner2()));
}
}
Ill try and clear things up as i go.
this is the output i get
Here is your obj value: null null 0.0 null null
Ok so here is what it probably should look like instead. Just from what I saw wrong already. However you'd probably want to override the toString() method of DogItem.
Main method example of this:
public class Main {
public static void main(String[] args) {
DogItem dogItem = new DogItem("Spot", "Dalmation", "45", "Bob", "Sandy");
DogItem.add(dogItem);
DogItem result = DogItem.searchForItem("Spot");
if (result == null) {
System.out.println("Dog not found");
// GUI error output goes here
} else {
System.out.println("Here is your obj value: " + result);
// Where your GUI stuff goes
}
}
}
DogItem example of this:
public class DogItem {
private static DogItem[] dogListArray = new DogItem[100];
private static int numItems = 0;
private String name;
private String breed;
private String weight;
private String owner1;
private String owner2;
public DogItem(String name, String breed, String weight, String owner1, String owner2) {
this.name = name;
this.breed = breed;
this.weight = weight;
this.owner1 = owner1;
this.owner2 = owner2;
}
public static void add(DogItem dogItem) {
dogListArray[numItems++] = dogItem;
}
public static DogItem searchForItem(String name) {
DogItem dogItem = null;
for (DogItem result : dogListArray) {
if (result != null) {
if (result.getName() == name) {
dogItem = result;
}
}
}
return dogItem;
}
#Override
public String toString() {
String result = name + ", " + breed + ", " + weight + ", " + owner1 + " " + owner2;
return result;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBreed() {
return breed;
}
public void setBreed(String breed) {
this.breed = breed;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public String getOwner1() {
return owner1;
}
public void setOwner1(String owner1) {
this.owner1 = owner1;
}
public String getOwner2() {
return owner2;
}
public void setOwner2(String owner2) {
this.owner2 = owner2;
}
}
These would be recommended changes from me though:
private static ArrayList<String> owners;
private static ArrayList<DogItem> dogsList;
public DogItem(String name, String breed, String weight, String owner) {
this.name = name;
this.breed = breed;
this.weight = weight;
this.owners.add(owner);
}
public void init() {
owners = new ArrayList<String>();
dogsList = new ArrayList<DogItem>();
}
public void addDog(DogItem dogItem) {
dogsList.add(dogItem);
}
public DogItem searchForItem(String name) {
DogItem dogItem = null;
for (DogItem result : dogsList) {
if (result != null) {
if (result.getName() == name) {
dogItem = result;
}
}
}
return dogItem;
}
public void addOwner(String owner) {
owners.add(owner);
}
public String getOwner() {
return owners.get(owners.size() - 1);
}
folks.... i have a child class GateNot which extends Gate. I'm not sure how to fill out the constructor of GateNot since Im not given any instance variables inside a child class. What would be the approach?
public class GateNot extends Gate {
public GateNot(Wire input, Wire output)
{
super()
}
}
import java.util.*;
public abstract class Gate implements Logic {
private List<Wire> inputs;
private Wire output;
private String name;
public Gate(String name, List<Wire> ins, Wire out)
{
this.name = name;
this.output = out;
if(ins.size() == 0 || ins.isEmpty())
throw new ExceptionLogicParameters(false, 1, 0);
else
this.inputs = ins;
}
#Override
public void feed(List<Signal> inSigs)
{
if(inSigs.size() != inputs.size())
throw new ExceptionLogicParameters(false, inputs.size(), inSigs.size());
else
{
for(int i = 0; i < inSigs.size(); i++)
{
inputs.get(i).setSignal(inSigs.get(i));
}
}
}
#Override
public void feed(String name)
{
if(!(this.name.equals(name)))
throw new ExceptionLogicMalformedSignal(name.charAt(0), "Invalid logic input");
else
{
Signal signalValue = Signal.fromString(name.charAt(0));
}
}
#Override
public List<Signal> read()
{
List<Signal> signals = new ArrayList<>();
signals.add(output.getSignal());
return signals;
}
#Override
public String toString()
{
return this.name+"( " + inputs.toString() + " | " + output.toString() + " )";
}
#Override
public boolean equals(Object other)
{
if(other instanceof Gate)
{
Gate someGate = (Gate)other;
return (this.inputs == someGate.inputs) && (this.output.equals(someGate.output)
&& (this.name.equals(someGate.name)));
}
else
return false;
}
public List<Wire>getInputs()
{
return this.inputs;
}
public Wire getOutput()
{
return this.output;
}
public String getName()
{
return this.name;
}
public void setInputs(List<Wire> inputs)
{
this.inputs = inputs;
}
public void setOutput(Wire output)
{
this.output = output;
}
public void setName(String name)
{
this.name = name;
}
}
You have to call the super class's constructor.
Based on the argument types and names of the super class's constructor, I'd say this is what you need :
public GateNot(Wire input, Wire output)
{
super("Not", Arrays.asList(new Wire[]{input}), output);
}
You can pass whatever String you wish as name
You should convert the input to a List of inputs
You can pass the output as is
i have created a package SimpleCustomer and used it in SimpleCustomerService file.I have generated .class file for SimpleCustomer where as when i am compiling SimpleCustomerService file it is given errors .i couldn't resolve my error.i am new to java.thanks in advance
my package file is:
package com.adobe.objects;
import java.util.Date;
public class SimpleCustomer
{
private int customerId;
private String customerName;
private String customerAddress;
private String customerType;
private Date entryModifiedDate;
public int getCustomerId()
{
return this.customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return this.customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCustomerAddress() {
return this.customerAddress;
}
public void setCustomerAddress(String customerAddress) {
this.customerAddress = customerAddress;
}
public String getCustomerType() {
return this.customerType;
}
public void setCustomerType(String customerType) {
this.customerType = customerType;
}
public void setEntryModifiedDate(Date entryModifiedDate) {
this.entryModifiedDate = entryModifiedDate;
}
public Date getEntryModifiedDate() {
return this.entryModifiedDate;
}
}
and my file which uses this package is:
package com.adobe.services;
import com.adobe.objects.SimpleCustomer;
import java.util.ArrayList;
import java.util.Date;
public class SimpleCustomerService
{
public static void main(String args[])
{
}
ArrayList<SimpleCustomer> getAllCustomers()
{
ArrayList customers = null;
try
{
int numberOfCustomers = 20;
SimpleCustomer customer = null;
customers = new ArrayList();
for (int loopCounter = 1; loopCounter <= numberOfCustomers; loopCounter++)
{
customer = new SimpleCustomer();
customer.setCustomerId(loopCounter);
customer.setCustomerName("Customer " + loopCounter);
customer.setCustomerType("Organization " + loopCounter);
customer.setCustomerAddress("Road # " + loopCounter + ", Bangalore, India");
customer.setEntryModifiedDate(new Date());
customers.add(customer);
}
}
catch (Exception e)
{
throw new RuntimeException(e);
}
return customers;
}
}
my error is:
illegal start of expression :public ArrayList getAllCustomers()
error 2: error ;excepted :public ArrayList getAllCustomers()
the first error is at public and second error is at getALlCustomers()
thanks in advance.
It seems you are trying to embed a method in your main method, which is i belive causing the error:
public static void main(String args[])
{
ArrayList<SimpleCustomer> getAllCustomers()
{
Not sure why you want to do it, but it is not permissible. You should move your getAllCustomers mehthod out of main method and see if it helps!
OK, I am getting null for whatever reason I cannot fathom.
Here is my code:
import java.util.*;
import java.io.*;
import com.google.gson.*;
public class readGoogle {
public static String MapTitle;
public static Data data;
public static Item item;
public static String dan;
public static FileReader fr;
public static void main(String[] args) {
/**
try {
fr = new FileReader("map1.txt");
}catch(FileNotFoundException fne) {
fne.printStackTrace();
}
StringBuffer sb = new StringBuffer();
char[] b = new char[1000];
int n = 0;
try {
while ((n = fr.read(b)) > 0) {
sb.append(b, 0, n);
}
}catch(IOException rex) {
rex.printStackTrace();
}
String fileString = sb.toString();
**/
String json =
"{"
+"'name': 'map_one.txt',"
+"'title': 'xxx One',"
+"'currentMap': 4,"
+"'rightMap': 3,"
+"'lefttMap': 5,"
+"'downMap': 1,"
+"'upMap': 2,"
+"'items': ["
+" { name: 'Pickaxe', x: 5, y: 1 },"
+" { name: 'Battleaxe', x: 2, y: 3 }"
+"],"
+" 'map': [ [ 1,3,1,1,1,24,1,1,1,1,1,1,1 ],"
+" [ 1,3,1,1,1,24,1,1,1,1,1,1,1 ],"
+" [ 1,7,1,1,1,24,1,1,24,1,1,1,1 ],"
+" [ 1,7,1,1,7,1,1,1,24,1,1,1,1 ],"
+" [ 1,7,7,7,1,24,24,24,24,1,1,1,1 ],"
+" [ 1,1,7,1,1,24,1,24,1,1,1,1,1 ],"
+" [ 1,1,1,1,1,24,1,1,1,1,1,1,1 ],"
+" [ 1,1,3,1,1,24,1,1,1,1,1,1,1 ],"
+" [ 1,3,3,1,1,24,1,1,1,1,1,1,1 ]]"
+"};";
try {
data = new Gson().fromJson(json, Data.class);
}catch (Exception er) {
er.printStackTrace();
}
System.out.println("Name of map: " + data.getTitle());
System.out.println("File of map: " + data.getName());
System.out.println("Current Map: " + data.getCurrentMap());
System.out.println(data.getItems().get(0).getName()); // Pickaxe
}
public class Item {
public String name;
public int x;
public int y;
public String getName() { return name; }
public int getX() { return x; }
public int getY() { return y; }
public void setName(String name) { this.name = name; }
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
}
public static class Data {
private String name;
private String title;
private int currentMap;
private int leftMap;
private int rightMap;
private int upMap;
private int downMap;
private List<Item> items;
private int[][] map;
public String getName() { return name; }
public String getTitle() { return title; }
public int getCurrentMap() { return currentMap; }
public int getUpMap() { return upMap; }
public int getDownMap() { return downMap; }
public int getLeftMap() { return leftMap; }
public int getRightMap() { return rightMap; }
public List<Item> getItems() { return items; }
public int[][] getMap() { return map; }
public void setName(String name) { this.name = name; }
public void setTitle(String title) { this.title = title; }
public void setCurrentMap(int currentMap) { this.currentMap = currentMap; }
public void setItems(List<Item> items) { this.items = items; }
public void setMap(int[][] map) { this.map = map; }
}
}
public static class Item {
public static String name;
public static int x;
public int y;
public static String getName() { return name; }
public static int getX() { return x; }
public int getY() { return y; }
public void setName(String name) { this.name = name; }
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
}
public static class Data {
private String name;
private String title;
private int currentMap;
private int leftMap;
private int rightMap;
private int upMap;
private int downMap;
private List<Item> items;
private int[][] map;
public String getName() { return name; }
public String getTitle() { return title; }
public int getCurrentMap() { return currentMap; }
public int getUpMap() { return upMap; }
public int getDownMap() { return downMap; }
public int getLeftMap() { return leftMap; }
public int getRightMap() { return rightMap; }
public List<Item> getItems() { return items; }
public int[][] getMap() { return map; }
public void setName(String name) { this.name = name; }
public void setTitle(String title) { this.title = title; }
public void setCurrentMap(int currentMap) { this.currentMap = currentMap; }
public void setItems(List<Item> items) { this.items = items; }
public void setMap(int[][] map) { this.map = map; }
}
}
Here is the output:
com.google.gson.JsonParseException: The JsonDeserializer com.google.gson.Default
TypeAdapters$CollectionTypeAdapter#6016a786 failed to deserialized json object [
{"name":"Pickaxe","x":5,"y":1},{"name":"Battleaxe","x":2,"y":3}] given the type
com.google.gson.ParameterizedTypeImpl#6c59096e
at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDese
rializerExceptionWrapper.java:63)
at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(J
sonDeserializationVisitor.java:88)
at com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCusto
mHandler(JsonObjectDeserializationVisitor.java:117)
at com.google.gson.ObjectNavigator.navigateClassFields(ObjectNavigator.j
ava:150)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:123)
at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(Json
DeserializationContextDefault.java:73)
at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDes
erializationContextDefault.java:51)
at com.google.gson.Gson.fromJson(Gson.java:495)
at com.google.gson.Gson.fromJson(Gson.java:444)
at com.google.gson.Gson.fromJson(Gson.java:396)
at com.google.gson.Gson.fromJson(Gson.java:372)
at readGoogle.main(readGoogle.java:62)
Caused by: java.lang.RuntimeException: No-args constructor for class readGoogle$
Item does not exist. Register an InstanceCreator with Gson for this type to fix
this problem.
at com.google.gson.MappedObjectConstructor.constructWithNoArgConstructor
(MappedObjectConstructor.java:64)
at com.google.gson.MappedObjectConstructor.construct(MappedObjectConstru
ctor.java:53)
at com.google.gson.JsonObjectDeserializationVisitor.constructTarget(Json
ObjectDeserializationVisitor.java:41)
at com.google.gson.JsonDeserializationVisitor.getTarget(JsonDeserializat
ionVisitor.java:56)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:101)
at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(Json
DeserializationContextDefault.java:73)
at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDes
erializationContextDefault.java:51)
at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize
(DefaultTypeAdapters.java:472)
at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize
(DefaultTypeAdapters.java:435)
at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDese
rializerExceptionWrapper.java:50)
... 11 more
Exception in thread "main" java.lang.NullPointerException
at readGoogle.main(readGoogle.java:67)
Press any key to continue . . .
Something is wrong within the Items json array... :S
are you sure the property 'name' of Item should be static? Doesn't seem right to me....
edit -- and the property 'x'
edit -- if you look at your stack trace, it says
Caused by: java.lang.RuntimeException: No-args constructor for class readGoogle$
Item does not exist.
So you need to provide a constructor that is public and takes no arguments.
I had a similar problem and solved it by reading the documentation http://sites.google.com/site/gson/gson-user-guide on nested inner classes. You need to define your items class as a nested class of data and declare it as static, with an empty constructor.