Hash maps to link several domains into one report - Java Eclipse - java

I am new to Java and am using Java Eclipse, so please be kind! I hope I'm going to pose this question correctly so it makes sense.
I have four domains - each domain is pulling data from four different servers, hence the need to have them separate. But now I need to create a report that links all the data from the four domains into one report. Someone suggested using hashmaps, which I haven't used before. My four domains each have two fields that can be used as a key - CostCenter and Serial. The data being pulled is from machines all over the country. I need all the data for each machine in one report.
This is all being added to an existing project that creates a webpage with tabs for the user to click on for various tables and get data specific to a location, or to create a report for each page for all machines/locations. I just need to add a new link for the user to click on that will create this spreadsheet for them.
I've already created the domains (DAO, DAOImpl, DTO, and so on) and then I was going to create the combined report in my MainService.java. Here are the domains (lists) as declared in my MainService:
public List<Volume> getVolumeReport();
public List<BadFmPumps> getBadFmPumpsReport();
public List<BadCorobPumps> getBadCorobPumpsReport();
public List<McService> getMcServiceReport();
And here is data being pulled from the databases for each of them (domains):
public class Volume {
private String costCenter;
private String DAD;
private String division;
private String model;
private String serial;
private String numDispensers;
private String colorantSys;
private String CCEGals2017;
private String BACGals2017;
private String CCEGals2018;
private String BACGals2018;
private String DNR2017;
private String DNR2018;
private String DNR2019;
public class BadFmPumps {
private String costCenter;
private String model;
private String serial;
private String badFmPumps;
private String over10;
private String under10;
public class BadCorobPumps {
private String costCenter;
private String model;
private String serial;
private String badPumpCount;
public class McService {
private String costCenter;
private String model;
private String serial;
private String crChargeTotals;
private String emgCalls;
So I need to pull this data into one report wherever CostCenter + Serial matches. How do I declare the hashmaps for each object and how do I declare the key?
EDIT ----
I think I have something close here with
public List<Volume> getVolumeReport();
Map<String, Volume> VolumeMap = new HashMap<String, Volume>();
for (Volume dispenser : VolumeList)
{
String volumeKey = new StringBuilder().append(Volume.getCostCenter()).append(Volume.getSerial()).toString();
VolumeMap.put(volumeKey, dispenser);
}
Is this correct? I am getting one syntax error - the Map declaration
Map<String, Volume> VolumeMap = new HashMap<String, Volume>();
is giving me the error
Syntax error on token ";", { expected after this token
Is there something I need to change there?

There are some unusual things in your code. My guess is that you came from C# you are not using proper naming conventions see it here: https://www.oracle.com/technetwork/java/codeconventions-135099.html
You defined your method wrong, the error is not in the Map but the method definition
public List<Volume> getVolumeReport(); <-------- this
Should be
public List<Volume> getVolumeReport() {
And then close your method at its end (using }).
And inside your FOR you trying to direct access the Volume methods when you should use the variable you created: dispenser
String volumeKey = new StringBuilder()
.append(Volume.getCostCenter())
.append(Volume.getSerial())
.toString();
Should be
String volumeKey = new StringBuilder()
.append(dispenser.getCostCenter())
.append(dispenser.getSerial())
.toString();

Related

Adding attributes to existing object

I have an existing REST application which is caching a POJO (E.g Trade object) to ehcache and many other applications are using that. Some are sending that Trade object to REST service so that it can be persisted to Cache and DB and some are doing get operation on this cache using REST service.
public class Trade implements Serializable {
private static final long serialVersionUID = -92565215465632589L;
private String tradeNo = new String();
private String isin = new String();
private String quantity = new String();
.... //getters and setters
}
Now I want to add one more component to our application which uses many of the above trade attributes and many new also I want to add as a part of the functionality. I don't want to add new attributes to exist Trade POJO as it will impact existing code also. Shall I create new POJO which will extend Trade and add new attributes and persist this new POJO to cache? I will have almost similar object in cache with this approach :-( . any other good approach or design pattern is available?
public class ExtendedTrade extends Trade {
private String operation = new String();
private String dealType = new String();
private String identifier = new String();
.... //getters and setters
}
Above is the ExtendedTrade that I was describing in my approach.
Also please suggest any design so that I can avoid caching this similar type of object.
Embedding (maybe with delegate pattern) seems more solid under circumstances.
public class ExtendedTrade {
private Trade trade;
private String operation = "";
private String dealType = "";
private String identifier = "";
.... //getters and setters
}
Consider:
whether existing Trade can be extended to an ExtendedTrade (abstract).
whether an ExtendedTrade2 might come in existence, with other attributes.
whether you need to patch existing attributes of Trade.
I certainly won't insist that this is better.

Jackson Parser: Updating a mapped object with nested objects

I have been taking advantage of Jackson JSON parser to map out my objects. While testing out the api, I have come across an issue with creating/updating my object that includes nested objects.
Creating and Updating main object
Airplane plane = airplanes.get(planeId);
if(plane == null){
plane = mapper.readValue(jsonNode, Airplane.class)
}else{
mapper.readerForUpdating(plane).readValue(jsonNode);
}
Example of objects:
public class Airplane {
private static final String TAG = "Airplane Model";
#JsonProperty("id")
private String mId;
#JsonProperty("company")
private String mCompany;
#JsonProperty("pilot")
private Pilot mPilot;
#JsonProperty("passenger")
private Passenger mPassenger;
public Airplane() {
}
}
public class Pilot {
private static final String TAG = "Pilot Model";
#JsonProperty("id")
private String mId;
#JsonProperty("name")
private String mName;
public Pilot() {
//keeps getting called on airplane reader update
}
}
Everything maps correctly, however the issue is that every time an airplane object is updated, it creates a new nested object of 'Pilot' as commented in the Pilot() constructor. This becomes a larger issue because the airplane model is being updated by a web socket at a small time interval (Unnecessary object instantiation). Additionally, I am setting non-mapped fields in the Pilot object which are being lost due to a new Pilot object being created on every update.
What is the proper way to update an object via Jackson with nested objects? Am I missing any annotations to prevent repetitive instantiation of my nested objects.

ask for suggestions how fields to add to my message class

I'm building an IM program using java IO, and I have an Object called Message.
what field do you recommend me to add to Message Class?
I did the folowing:
public class Message implements Serializable {
static private final long serialVersionUID=12525452;
enum commands{
LEAVE,
ONLINELISTREQUEST,
SENT,
DELIVERED,
READ;
}
enum types{
TEXT,
VEDIO,
PICTURE,
AUDIO,
COMMAND,
//...... what to add??
}
// fields..
private String From;
private String To;
private String Body;
private int type;
private String url;
private int command;
//what to add??
ALso have variable as STATE which will be having values as:-
SEEN, SENT, etc..
This will help in tracking of message and also launch a threads which will keep on checking whether messages which don't have status as SENT/ RECEIVED just resend them
Just use the teachings of Object Oriented concepts. A class should have attributes that are really properties of the entity represented by that class.

Strategy to share static Strings across my app

I have lots of values in properties files, which are read in my app to setup values (DB connections, email servers, etc.).
db.properties:
db.user=admin
db.pwd=secret1234
Now in my DatabaseService class, I have something like this:
private static final String DB_USER = "db.user";
private static final String DB_PWD = "db.pwd";
private Properties dbProps = new Properties();
// read db.properties values into dbProps
String user = dbProps.getProperty(DB_USER);
Then in my DatabaseServiceTest class, I have repeated code:
private static final String DB_USER = "db.user";
private static final String DB_PWD = "db.pwd";
private Properties dbProps = new Properties();
// read db.properties values into dbProps
String user = dbProps.getProperty(DB_USER);
So I have repeated code. So instead I have put the static String values into a StaticVars class that hosts all of the Strings so the DatabaseService and DatabaseServiceTest now look like this (I could also put the Properties in the utility class, but there are scores of this example, so I haven't so far):
private Properties dbProps = new Properties();
// read db.properties values into dbProps
String user = dbProps.getProperty(StaticVars.DB_USER);
Is there a better way to share the static Strings across multiple class files? My current StaticVars class has about 150 static String values, and growing. It seems like I am going down the wrong path.
Thanks,
Sean
I think your general approach - using public static final String members of a public class - is a fine way to share strings across an application.
However don't underestimate the importance of naming. When you come back to this code in 6 months will you remember that the names of your properties are stored in a class called StaticVars? If you are truly only storing property names, then perhaps the class should be called PropertyNames. Now you have bounded the scope of the class and will be less likely mix in strings for error messages or regular expressions or whatever. (Those should go into different classes with meaningful names to help you remember what kind of values they store.)
Taking this a step further, since these are property names, they are likely to be used in getProperty calls. So why not rename the class PropertyUtils or ConfigUtils, and have matching static methods which use the property names. Then you can add default property values if certain properties are optional.
public static final String DB_HOST = "db.host";
public static final String DB_USER = "db.user";
public static final String DB_PWD = "db.pwd";
public static String getDbHost(Properties props)
{
return props.getProperty(DB_HOST, "localhost");
}
public static String getDbUser(Properties props)
{
return props.getProperty(DB_USER, "admin");
}
public static String getDbPwd(Properties props)
{
return props.getProperty(DB_PWD);
}

How to save an ArrayList in Play?

This might seem like a very basic question, but I have a model (User) which I want to store an ArrayList of Strings (they are the id's of other users). I declare the List like this:
public List<String> friends = new ArrayList<String>();
After I add an entry to the array, I save the user. But friends is always null when I try to use it. Is there a specific way to save an ArrayList? Any help would be appreciated.
My model:
#Entity
public class User extends Model {
#Id
public String username;
public String password;
public List<String> friends = new ArrayList<String>();
public static Finder<String, User> find = new Finder<String, User>(String.class, User.class);
// Constructor
public User(String username, String password){
this.username = username;
this.password = password;
}
// Methods
public void addFriend(String friend){
friends.add(friend);
}
// Static Methods
public static User authenticate(String username, String password){
return find.where().eq("username", username).eq("password", password).findUnique();
}
public static void befriend(String user1, String user2){
User.find.ref(user1).addFriend(user2));
User.find.ref(user2).addFriend(user1);
User.find.ref(user1).save();
User.find.ref(user2).save();
}
}
The controller method:
return ok(index.render(
User.find.byId(request().username()).friends,
));
And a very simple view:
#(friends: List[User])
<div id="current_friends">
#for(friend <- friends) {
#friend.username
}
</div>
You need to save the relations 'manually' with saveManyToManyAssociations(String fieldname), for an example:
public static void befriend(String userName1, String userName2){
User user1 = User.find.byId(userName1);
User user2 = User.find.byId(userName2);
user1.friends.add(user2);
user2.friends.add(user1);
user1.save();
user2.save();
// here...
user1.saveManyToManyAssociations("friends");
user2.saveManyToManyAssociations("friends");
}
(note: written from top of my had so debug it yourself pls)
One potential reason for this problem could be your view:
The first line of your view is
#(friends: List[User])
The User does not have a package name, which could cause the null pointer exception.
In my case, my User bean is under models package, so I have the following line:
#(friends: List[models.User])
I encountered the exact same problem, and here is how I fixed it (with a little explanation coming along).
In fact, you try to save an ArrayList (thus something which size is undefined) in a DataBase. And apparently (and quite logically), the Play Framework doesn't really like it ; you have to use whether annotations or a transient class. I decided to use the class way (also because i don't know how to use the annotations to make a sub table, so I didn't took the risk, but it's not the best way to do it. In fact, it's an horrible way of doing it. But still, here it is).
In your case, you could to this :
#Entity
public class Friends extends Model {
#Id
public Long id;
#Required
public String user1;
#Required
public String user2;
public static Finder<Long, Friends> find = new Finder<Long, Friends>(Long.class, Friends.class);
//Here put your functions, I myself only added an insert method for the moment :
public static void add(String user1, String user2){
Friends f = new Friends();
f.user1 = user1;
f.user2 = user2;
bu.save();
}
}
And in your User model, just change the part in which you save both user into each other's List by this function.
Hope this will help.
Note : the id is here because I like numeric ids, feel free to change it.
Note 2 : Of course, it would be much better to use #ManyToOne and #OneToMany annotations, but as I wrote before, I don't know exactly how does it work.

Categories