jXPath quering attribute in super class - java

I have a couple of domain classes which all inherit a BaseDomain class.
In this BaseDomain class I have a field that is public final String name;
The value of name is set in the constructor.
public class BaseDomain {
public final String name;
public BaseDomain() {
this.name = this.getClass().getCanonicalName();
}
}
This BaseDomain is extended by a few classes
public class Trip extends BaseDomain {
private int id;
public Trip(int id){
this.id = id;
}
}
So far so good.
I want to get the value of the field "name" in an object instance of Trip of a with the help of JXPath but can't. I can access the "id" field but not the "name" field.
JXPathContext jxPathContext = JXPathContext.newContext(trip);
jxPathContext.setLenient(true);
int id = (int)jxPathContext.getValue("/#id"); // This works.
String name = (String)jxPathContext.getValue("/#name"); // This does not work.
Is it possible to get the value of "name" with this setup and JXPath?
The code might have some syntax errors and/or other errors. I hope you all get the idea and understand my question.
Any help or pointer are welcome.
First of: I want to thank Kelly S. French for his quick replay.
It made me realize that I have to explain some more.
I want to use jxpath because I will eventually do a deeper search. For example: The Trip might hold a list of Locations which also extends the BaseDomain. Each Location can hold a list of PointOfInterest that extends BaseDomain.
Via reflection in other part of the code I want to be able to get a list of BaseDomain based on their type (class.getCanonicalName())
The object-tree is not based on xml, it is pure POJO.
As far as I have figured out, there is no way of writing a jxpath-query for finding a list of objects based on their type, class name and so on.
Is this correct?
Does some one know of a way to do that?
The easiest way out, even if it's ugly, is to have a field in the super class that holds the class-name. That is why I have done this ugly solution.
Eventually I want to create a jxpath-query that based on the trip returns an iterator of which ever object that is an instance of BaseDomain at any depth and not depending on which branch in the object tree the node is located, as long as I can get the class-name of the object I'm looking for.
Does any one know if it is possible to achive this with a jxpath-query?
Code example, links to blogs or other documentation is welcome and appreciated.
As before, I'm very grateful for any help.

if you have the trip instance, why can't you do this
string n = trip.name;
I can see that you have an XML representation of the trip, but using XPath would be for when you only have the XML for 'trip'.
If you still need to get name using XPath, post the XML that is generated. I would be willing to bet that the name attribute is not part of Trip, but part of the enclosing BaseDomain. If you are basing the jxPathContext on the Trip, you've already passed the nodes for the BaseDomain. You'd have to navigate back up somehow (like node.parent) or do that when you create the context,
// not sure about this approach
JXPathContext jxPathContext = JXPathContext.newContext(trip.super);
After looking at the JXPath manual on parent/child relationships why don't you try this:
String name = (String)jxPathContext.getValue("/Trip/../#name");
// or use "../#name", not sure it wouldn't need to be "/../#name"

Related

Design of Comment-Feature for multiple database objects

In my application I have multiple objects that I would like to add comments to. Every one of these objects is represented in its own database table. Beside being connected to a specific object, all comments share a common context in which the corresponding objects exist. What I tried for now is to use JPA-inheritance with InheritanceType.SingleTable so I can store the foreign keys to every 'commentable'-object in one table and the discriminator-feature to seperate that table into different Comment-Subclasses in JPA:
Superclass Comment.java
#Entity
#Table(name = "COMMENT_TABLE")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "COMMENT_OBJECT_TYPE")
public class Comment {
protected String text;
protected CommonContext context;
...
}
Subclass Object A
#Entity
#DiscriminatorValue(value = "OBJECT A")
public class ObjectAComment extends Comment {
private ObjectA objectA;
// OneToMany-Relation exists in Object A accordingly
#JoinColumn(name = "FK_OBJECT_A")
#ManyToOne
public ObjectA getObjectA() { return objectA; }
public void setObjectA(ObjectA objectA) { this.objectA = objectA; }
}
The other comment-classes for the other objects are designed just as for object A. The common context shall be used to get all comments for a specific situation and I would like to have a comment know its owner, so that I can easily link to that object in my application. Without the latter I had to go through all objects of that type to search for any that has comments, as not every object has them.
On designing the REST-endpoints and the EJBs I ended up creating specific methods for every subclass of Comment.java. For example for creating a comment I have
#POST
#Path("comments/objectA")
public Response createCommentForObjectA(ObjectAComment comment) { ... }
#POST
#Path("comments/objectB")
public Response createCommentForObjectB(ObjectBComment comment) { ... }
...
This feels a bit cumbersome as I would rather have
#POST
#Path("comments")
public Response createComment(Comment comment) { ... }
which is impossible with the current design as I would lose the specific information for the different objects. Now I see three possible ways to go on:
Version 1
I stick with the current solution and create CRUD-methods for every type of comment.
Version 2
A friend suggested, that I could use transient properties in Comment.java:
public class Comment {
...
private COMMENT_OBJECT_TYPE objectType;
private long idObject;
#Transient
public long getIdObject() { return idObject; }
...
#Transient
public COMMENT_OBJECT_TYPE getObjectType() { return objectType; }
...
}
With this I could generalize the parameter of the REST-endpoint and return specific objects depending on the object type:
#POST
#Path("comments")
public Response createComment(Comment comment) {
// return ObjectAComment, ObjectBComment, ... depending on the object type
}
Version 3
Ditch the whole #Inheritance and #DiscriminatorColumn, put everything in one JPA-class and do the whole organizing of the comment context myself. Additionaly I would lose type safety.
None of these solutions feels completely right to me, hence I would like to ask if there is a preferable way to design this kind of comment feature and is there maybe something I am missing completely?
Edit 1
Added information that all comments and objects share a common context. Renamed previous COMMENT_CONTEXT to COMMENT_OBJECT_TYPE to avoid a misunderstanding between this common context and the object type a comment is related to.
It seems to me like your Comment is a standalone entity without dependencies on other entities. A comment has an owner, but should not know who is owning it. So I would add a column on the comment table "ownerUuid". The entire comments "bounded context" knows nothing about the other entities.
When creating a comment you always provide the ownerUuid. Same for retrieval. So you can create comments for any entity having a uuid.
However this means you need to add UUID columns in your already existing tables.
This to me seems like the cleanest solution. This way your comment system can stand on it's own without heavy impact on other entities.
EDIT
Because of the extra information. I would suggest following approach.
Keep in mind that I do not know how the owner of the Comment is used, so the suggestion might not be perfect for this scenario.
As the comment should know the owner object I would suggest doing the following:
Have an interface CommentOwner with methods:
getUuid()
getContext()
Any other information you might need from the owner
A Comment will have a CommentOwner property.
Every entity that you want to contain Comments, should implement this interface. When creating a Comment you provide the CommentOwner.
This way you can retrieve comments Based on Context. A Comments has a direct link to its owner, but still does not need to know about the specific classes of the owners.
In the end I went with version 3, keeping every information in one Comment-class. The subclasses which I would've achieved with #Inheritance and #DiscriminatorColumn would only have one property, the foreign key to the commentable object, and wouldn't differ in what they represent in general and how they would be used.
My class looks something like this now:
public class Comment {
private String text;
private CommonContext context;
private COMMENT_OBJECT_TYPE objectType;
private ObjectA objectA;
private ObjectB objectB;
...
#JoinColumn(name = FK_OBJECT_A)
#ManyToOne
public ObjectA getObjectA() { return objectA; }
public void setObjectA(ObjectA objectA) { this.objectA = objectA; }
...
}

ZK MVVM Validation - Dependent Property Array content?

I'm playing around with the ZK 8 MVVM form validation system and generally it seems to do what I want, but I wonder what the definition of the dependent property index is...
Let's take a simple validator...
public class FormValidator extends AbstractValidator {
#Override
public void validate(final ValidationContext ctx) {
Property[] properties = ctx.getProperties("firstName");
Object value0 = properties[0].getValue();
Object value1 = properties[1].getValue();
}
}
So, when this is called before the save command, for every property, I get a Property[] array of length 2. But somehow, I have yet to find out what is stored in [0] and what is stored in [1]. Sometimes it seems that [0] stores the current value (which may or may not be valid according the field validator there) and [1] the last valid entry... But sometimes it seems to be the other way round...
The examples in the documentation always seem to simply take the first element ([0]) for validation, but I would like the understand what both parts of this pair actually mean...
Anyone got an idea for that?
I might be off the mark with my answer, but if you are using ZK8, you should look into using Form binding
That way you do not have to handle Properties in your validator and can retrieve a proxy object matching the bean you use for your form.
If you are using a User POJO with a firstName and lastName attribut.
User myProxy= (User ) ctx.getProperty().getValue();
And then you can validate both fields by simply doing getFirstName and getLastName on myProxy.
Hope it helps.

How to create a Java class with data fields

I am in a programming class that has provided me with a project but I have no idea where to start and was hoping someone could push me in the right direction. I am only posting part of the project so that someone can show me a bit of the code to get an idea of how its done as I have taken a programming class before but I am out of practice.
Create an application called Registrar that has the following classes:
A Student class that minimally stores the following data fields for a student:
Name
Student id number
Number of credits
The following methods should also be provided:
A constructor that initializes the name and id fields
A method that returns the student name field
Methods to set and retrieve the total number of credits
I have removed most of the question as I am not trying to get the full answer but to just get this little sample to try to get going on the rest of the project.
I am also having trouble with the 2nd part as to how I can create names and ID's on a second program and retrieve them into the first program with the classes.
Here is a bit of an translation for what you need to do, the words in bold are keywords that, when googled, will most likely return information relevant to what you are doing.
A Student class that minimally stores the following data fields for a student:
This basically means to create a class which has the following properties:
• Name
• Student id number
• Number of credits
Think hard about what types of data those would be? What type do you need to create to store somebody's name? Or their Id? Remember, these are all properties
A constructor that initializes the name and id fields
Google constructor and learn all about how they work, pay special attention when a learning source discusses how to initialize properties inside of the constructor.
A method that returns the student name field
Research about methods and how you can create one to return your property Student Name. Learn how you will actually use this method.
Methods to set and retrieve the total number of credits
Research Getters and Setters and understand how they interact with a classes properties
Best of luck buddy, google is your best friend/lover in programming..
public class Student {
private String name;
private String id;
private int numOfCredits;
public Student(String name, String id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public int getNumOfCredits() {
return numOfCredits;
}
public void setNumOfCredits(int numOfCredits) {
this.numOfCredits = numOfCredits;
}
}

Java Soap Services: Add non-persistent result field based on a persistent one

So I need to add a new field to a SOAP service response. The thing is that the field has to take the value from a persistent field. I cannot add that persistent field directly. The persistent field returns a "Calendar" instance, which is, in fact, a DATETIME from MySQL. The current object uses the XmlAdapter.
I did something like this:
class SomeClassImpl extends SomeClass
{
#Transient
#XmlSchemaType(name="someDate")
private String someDate;
...
public void defSomeDate()
{
this.someDate = this.getPersistentDate().toString();
}
public String retSomeDate()
{
return this.someDate();
}
}
The new field appears in the soap result, but the value is an exception, which I don't remember right now and I am not able to reproduce it now.
How would you do this? Is it possible to annotate a method instead of the member so it appears in the SOAP result? If yes, how would an annootation would look like?
Thank you in advance!
The problem was the following piece of code:
#XmlSchemaType(name="someDate")
There "name" parameter should be one of the standard data types for xml. In this case, because it contains the date and the time, it should be 'dateTime'. It could also be a string, but declaring it as dateTime makes the field more restrictive. Therefore, the correct annotation is:
#XmlSchemaType(name="dateTime")
With the date and time in mind, the second observation is that private String someDate; should be private CalendarsomeDate;, to be consistent and also for the actual code to work.
Annotating the methods is not required. Simply annotating the member/property is enough and as long as the member/property is set somewhere at runtime.
I hope this would be helpful for someone else too. It took me few hours to get this, but now I know how to proceed in the future.

Map as parameter for all fields for EJB backend calls

I am designing backend EJB calls to be called by REST api.
Example for EJB calls;
Get all Systems
getSystems(String systemId)
Now I know that i would get system id to get all systems.
There is a possibility of retrieving them by some another unique id as well
getSystemsByOtherId(String otherId)
There is requirement that there could be sort parameter passed in
getSystems(String systemId, String sort_by, String sort_how)
Would it be better to have something like Map as param and have it passed in with every information
getSystems(Map criteria)
So the key- value pair for Map would have systemId, otherId, sort_by, sort_how and more if needed in future. Or is it better to follow other approach to have unique methods for different params. Or if there is some other better approach.
Thank you.
The first solution is a little cumbersome, in case you want to add or remove parameters you'd have to modify the signature of your EJB every time, the map solution is a little dirty since you'd have to keep track of your parameters names at runtime and if you want to use parameters of a type other than String you'd lose typing info at runtime as well.
This is how I would do it, define a class that encapsulates your parameters:
public class Criteria {
private String systemId;
private String otherId;
private String sortBy;
private String sortHow;
.
.
.
}
and in your EJB,
getSystem(Criteria criteria)

Categories

Resources