As topic states, I want to remove non-objects from List of objects.
I have a web service (xml file with some data) and generated classes from XSD file. Among generated XSD classes there is a class ASMENYS and it has method getContent(). This method returns a list of generated.ASMUO objects.
Now the problem is, that this method for some reason returns empty lines (spaces?) among objects. I need to iterate through asmenysList, and because of empty spaces I'm forced to use if() which deprecates my code performance...Any ideas? Why are those empty spaces generated? Or maybe some ideas how to better filter them without iteration if possible?
//m here is generated.ASMENYS object,.: generated.ASMENYS#10636b0
List<Object> asmenysList = ((ASMENYS) m).getContent();
System.out.println(asmenysList);
[
, generated.ASMUO#1799640,
, generated.ASMUO#b107fd,
, generated.ASMUO#10636b0,
...
, generated.ASMUO#1df00a0,
]
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"content"
})
#XmlRootElement(name = "ASMENYS")
public class ASMENYS {
#XmlElementRef(name = "ASMUO", type = ASMUO.class, required = false)
#XmlMixed
protected List<Object> content;
/**
* Gets the value of the content property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the content property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getContent().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link ASMUO }
* {#link String }
*
*
*/
public List<Object> getContent() {
if (content == null) {
content = new ArrayList<Object>();
}
return this.content;
}
}
EDIT
/**
* Gets the value of the asmId property.
*
*/
public int getAsmId() {
return asmId;
}
List<Object> asmenysList = ((ASMENYS) m).getContent();
for(Object asm : asmenysList){
//trying to cast empty asmenysList element, gives me an error.
//that's why I'm forced to use if() as I said before.
if(asm.getClass().getName() == "generated.ASMUO"){
int asm_id = ((ASMUO) asm).getAsmId();
}
}
By definition a List<Object> only holds Object(s). If there are primitive types in there, they must be autoboxed. If it's an array, that is an Object. The only empty spaces I see are from the toString() method of List.
Edit
based on your edit,
if(asm.getClass().getName() == "generated.ASMUO"){
Is not how you test String equality,
if(asm.getClass().getName().equals("generated.ASMUO")) {
Related
I am using org.json library to convert Object to Json format. Kindly check the below code snippet.
public enum JobStatus implements Serializable{
INCOMPLETE,
INPROGRESS,
ABORTED,
COMPLETED
}
public class Job implements Serializable {
private string id;
private JobStatus status;
...
}
...
// Create Job Object
Job job = new Job("12345", JobStatus.INPROGRESS);
// Convert and print in JSON format
System.out.println(new JSONObject(job).toString());
It shows the output like this :
{"id":"12345", "status" : {}}
It shows blank and adds Curly bases. What does it mean? Is anybody gone through this problem?
First of all I highly recommend do not use this library (org.json), this is very old and unsupported (as i know) library. I suggest Jackson or Gson.
But if you really need JSONObject, you can add getter into enum:
public enum JobStatus implements Serializable{
INCOMPLETE,
INPROGRESS,
ABORTED,
COMPLETED;
public String getStatus() {
return this.name();
}
}
result of serialization:
{"id":"12345","status":{"status":"INPROGRESS"}}
As I know, JSONObject don't support correct serialization of enums which not have any additional data inside.
ObjectMapper mapper= new ObjectMapper();
new JSONObject(mapper.writeValueAsString(job));
would do the trick. Now Enums and DateTime types looks normal and is converted properly in json objects.
I came to this page as a person seeking answer and my research helped me to answer this question.
It seems JSONObject doesn't support enums. You could alter your Job class to add a getter like this:
public String getStatus() {
return status.name();
}
then, invoking new JSONObject(job).toString() produces:
{"id":"12345","status":"INPROGRESS"}
for me, i made an interface that shuold be implemented by any enum i will have to use in Json, this interface forces the enum to know the proper enum itself from a value, and also it should return a value ... so every enum.CONSTANT is mapped to a value of any type (weather a number or a String)
so when i want to put this enum in a Json Object, i ask the enum.CONSTANT to give me it's value, and when i have this value (from Json), i can request from the enum to give me the proper enum.CONSTANT mapped to this value
the interface is as follows (you can copy it as it is) :
/**
*
* this interface is intended for {#code enums} (or similar classes that needs
* to be identified by a value) who are based on a value for each constant,
* where it has the utility methods to identify the type ({#code enum} constant)
* based on the value passed, and can declare it's value in the interface as
* well
*
* #param <T>
* the type of the constants (pass the {#code enum} as a type)
* #param <V>
* the type of the value which identifies this constant
*/
public interface Valueable<T extends Valueable<T, V>, V> {
/**
* get the Type based on the passed value
*
* #param value
* the value that identifies the Type
* #return the Type
*/
T getType(V value);
/**
* get the value that identifies this type
*
* #return a value that can be used later in {#link #getType(Object)}
*/
V getValue();
}
now here is an example for a small enum implementing this interface:
public enum AreaType implements Valueable<AreaType, Integer> {
NONE(0),
AREA(1),
NEIGHBORHOOD(2);
private int value;
AreaType(int value) {
this.value = value;
}
#Override
public AreaType getType(Integer value) {
if(value == null){
// assume this is the default
return NONE;
}
for(AreaType a : values()){
if(a.value == value){ // or you can use value.equals(a.value)
return a;
}
}
// assume this is the default
return NONE;
}
#Override
public Integer getValue() {
return value;
}
}
to save this enum in a Json :
AreaType areaType = ...;
jsonObject.put(TAG,areaType.getValue());
now to get your value from a Json Object :
int areaValue = jsonObject.optInt(TAG,-1);
AreaType areaType = AreaType.NONE.getType(areaValue);
so if the areaValue is 1 for example, the AreaType will be "Area", and so on
Similar to what #Denys Denysiuk has answered. But if you want to return any value instead of String We can use like this. In below example i wanted to return value 1, or 15 instead of String
#Getter
public enum PaymentCollectionDay {
FIRST_OF_MONTH(1), FIFTEENTH_OF_MONTH(15);
PaymentCollectionDay(int day) {
this.day = day;
}
#JsonValue
final int day;
}
I'm working with Mybatis 3.2.6 and implementing a custom resulthandler. I've done this before using a simple datatype parameter and have had no problems. This time around I need to pass in several arguments... The signature I'm using is
session.select(statement, parameter, handler);
For parameter I've created a simple POJO to easily send in what I need. It is as follows:
public class DifferenceParam {
private int current;
private int compare;
private String table;
private String comparator;
/**
* Constructor excluding comparator. Will default a value of
* "code" to compare content on, e.g., <br/>
* {#code select * from a minus select * from b where a.code = b.code } <br/>
* #param table
* #param current
* #param compare
*/
public DifferenceParam(String table, int current, int compare) {
this(table, "code", current, compare);
}
/**
* Constructor providing a specific column to compare on, e.g. <br/>
* {#code select * from a minus select * from b where a.[comparator] = b.[comparator] } <br/>
* #param table
* #param comparator
* #param current
* #param compare
*/
public DifferenceParam(String table, String comparator, int current, int compare) {
this.table = table;
this.comparator = comparator;
this.current = current;
this.compare = compare;
}
/** Appropriate setters and getters to follow **/
}
The handler implementation is irrelevant at the moment, because I get an exception well in advance... The query I'm executing is:
<select id="getCodeSetModifications" parameterType="DifferenceParam" resultType="Code">
select *
from
(
select * from ${param.table} where revision_seq = #{param.current}
minus
select * from ${param.table} where revision_seq = #{param.compare}
) a, ${param.table} b
where a.${param.comparator} = b.${param.comparator}
and b.revision_seq = #{param.compare}
</select>
Here is the interface as well
public List<Code> getCodeSetModifications(#Param("param") DifferenceParam param);
The problem I'm having is that execution via a mapper e.g.,
session.getMapper(DifferenceParam.class);
works just fine, but when I invoke through a select on the session I get the following exception.
Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'param' in 'class com.mmm.his.cer.cerval.uidifference.map.param.DifferenceParam'
Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'param' in 'class com.mmm.his.cer.cerval.uidifference.map.param.DifferenceParam'
I've debugged as far as I can go into Mybatis, but am having no luck.
Thanks in advance...
When you use session.getMapper(DifferenceParam.class);, mybatis looks for #Param annotation and uses it's value in query.
When you invoke session.select(statement, parameter, handler);, such mapping doesn't occur.
Try to add public DifferenceParam getParam() { return this; } to DifferenceParam to workaround this.
when the MyBatis query only have one param. Don't need #{param.} reference.
because it default use the only param.
so when u use ${param.table}, it actually using #{DifferenceParam.param.table}.
because it think the ${param.} inside of the #{DifferenceParam.}
For a GeoSPARQL test project I want to have a custom datatype set in Jena. Howerver when I try this through the example provided at the Jena website, it still doesn't work. I get the following result:
_:b0 <http://www.opengis.net/ont/geosparql#asWKT> "POINT (52.83525867111958 6.870789811954563)^^http://www.opengis.net/ont/sf#wktLiteral "^^<java:com.hp.hpl.jena.rdf.model.impl.LiteralImpl> .
And of course I don't want the java:com.hp.hpl.jena.rdf.model.impl.LiteralImpl but http://www.opengis.net/ont/sf#wktLiteral because I wan to work with GeoSPARQL. On this page they have example data that works perfectly with my triple store and spatial index. But the above data doesn't work at all with spatial indexing.
So, my question is, I do I define a custom datatype in my RDF in Jena?
The syntax is
"POINT (52.83525867111958 6.870789811954563)"^^<http://www.opengis.net/ont/sf#wktLiteral>
I just found the answer to my question after a lot of trial and error. To add a custom RDFDatatype to my RDF model I first had to create my own class which extends BaseDatetype and which I called WktLiteral, looking like this:
public class WktLiteral extends BaseDatatype {
public static final String TypeURI = "http://www.opengis.net/ont/sf#wktLiteral";
public static final String CRS84 = "<http://www.opengis.net/def/crs/OGC/1.3/CRS84>";
public static final RDFDatatype wktLiteralType = new WktLiteral();
private WktLiteral() {
super(WktLiteral.TypeURI);
}
/**
* Convert a value of this datatype out
* to lexical form.
*/
public String unparse(Object value) {
return value.toString();
}
/**
* Parse a lexical form of this datatype to a value
*/
public Object parse(String lexicalForm) {
return new TypedValue(String.format("%s %s", WktLiteral.CRS84, lexicalForm), this.getURI());
}
/**
* Compares two instances of values of the given datatype.
* This does not allow rationals to be compared to other number
* formats, Lang tag is not significant.
*
* #param value1 First value to compare
* #param value2 Second value to compare
* #return Value to determine whether both are equal.
*/
public boolean isEqual(LiteralLabel value1, LiteralLabel value2) {
return value1.getDatatype() == value2.getDatatype()
&& value1.getValue().equals(value2.getValue());
}
Where it was quite important to return a TypedLiteral in the parse() method. After which I had to do the following to add something to my RDF model:
TypeMapper.getInstance().registerDatatype(WktLiteral.wktLiteralType);
item.addLiteral(GeoSPARQL.asWKT, ResourceFactory.createTypedLiteral(geom, WktLiteral.wktLiteralType));
Where GeoSPARQL.asWKT is the predicate in the GeoSPARQL vocabulary that I generated through schemagen. geom is the geometry object as well known text and WktLiteral.wktLiteralType is an instance of the above class.
In conclusion the result was the following (notation 3):
_:b0 <http://www.w3.org/2003/01/geo/wgs84_pos#lat_long> "POINT (51.61821756986111 5.542408362751153)" .
thus exactly what I wanted... Thanks for all the input.
I use JAXB for mapping XML configuration to Java object. This configuration could be edited from UI, that's why in order to transfer it to UI and vice versa. I definitely need to unmarshall json into Java object. Hence it's required to have setter method for List.
How to generate setter method for List property for POJO class using JAXB?
For security reasons setter are not generated for List objects.
/**
* Gets the value of the dateIntervals property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the dateIntervals property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getDateIntervals().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link DateInterval }
*
*
*/
For that you need create variable of List.The setter getter methods for this List variable are as below.
package foo.bar.me.too;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="VisitorDataList")
public class visitordatalist {
List<visitordata> vstd;
#XmlElement(name="VisitorData")
public List<visitordata> getVstd() {
return vstd;
}
public void setVstd(List<visitordata> vstd) {
this.vstd = vstd;
}
}
I'm trying to use GROUP BY in my criteria. I need to do this:
SELECT b FROM Book b GROUP BY volumeCode;
I have following code:
Criteria c = s.createCriteria(Book.class);
c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode")));
List<Book> result = c.list();
But this criteria returns only volumeCodes (a list of Strings). I need to get a list of Books. So I tried to use Transformers:
Criteria c = s.createCriteria(Book.class);
c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode")));
c.setResultTransformer(Transformers.aliasToBean(Book.class));
List<Book> result = c.list();
This code returns list of null values. Is it possible to do that with criteria?
First of all, the projecton filters the amount of data retrieved, if you want more data, you should add those properties to the projection too.
Example:
c.setProjection( Projections.projectionList()
.add( Projections.property("id").as("id") )
.add( Projections.property("descripction").as("description") )
.add( Projections.groupProperty("volumeCode").as("volumeCode") ));
Now, the transformer does what it says "Alias to Bean", it does an alias match with the properties of your java bean "Book.java".
Edit:
Without the transformer, if the projection has more than one property, the result comes out like this:
for(Object[] item:criteria.list()){
System.out.println( (String)item[0] ); //ID
System.out.println( (String)item[1] ); //Description
System.out.println( (String)item[2] ); //Volume code
}
Thats why you were getting the cast exception, about the transformer, try to match every alias with the property name of your java bean.
cz_Nesh.
sorry about my first answer.
i read Hibernate api and read some Hibernate source code i find that.
if you use this code
session.createCriteria(EmpUserImpl.class).list();
it will return List EmpUserImpl.
if you use this code
criteria.setProjection(Projections.projectionList()
.add(Projections.groupProperty("company").as("company"))
.add(Projections.property("name").as("name"))
.add(Projections.property("company").as("company")));
List list = criteria.list();
it will return List ,is not List EmpUserImpl why?
i see the criterion's parent class CriteriaSpecification i find that .
public interface CriteriaSpecification {
/**
* The alias that refers to the "root" entity of the criteria query.
*/
public static final String ROOT_ALIAS = "this";
/**
* Each row of results is a <tt>Map</tt> from alias to entity instance
*/
public static final ResultTransformer ALIAS_TO_ENTITY_MAP = AliasToEntityMapResultTransformer.INSTANCE;
/**
* Each row of results is an instance of the root entity
*/
public static final ResultTransformer ROOT_ENTITY = RootEntityResultTransformer.INSTANCE;
/**
* Each row of results is a distinct instance of the root entity
*/
public static final ResultTransformer DISTINCT_ROOT_ENTITY = DistinctRootEntityResultTransformer.INSTANCE;
/**
* This result transformer is selected implicitly by calling <tt>setProjection()</tt>
*/
public static final ResultTransformer PROJECTION = PassThroughResultTransformer.INSTANCE;
/**
* Specifies joining to an entity based on an inner join.
*
* #deprecated use {#link org.hibernate.sql.JoinType#INNER_JOIN}
*/
#Deprecated
public static final int INNER_JOIN = JoinType.INNER_JOIN.getJoinTypeValue();
/**
* Specifies joining to an entity based on a full join.
*
* #deprecated use {#link org.hibernate.sql.JoinType#FULL_JOIN}
*/
#Deprecated
public static final int FULL_JOIN = JoinType.FULL_JOIN.getJoinTypeValue();
/**
* Specifies joining to an entity based on a left outer join.
*
* #deprecated use {#link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN}
*/
#Deprecated
public static final int LEFT_JOIN = JoinType.LEFT_OUTER_JOIN.getJoinTypeValue();
}
can you see the public static final ResultTransformer PROJECTION ? it say that This result transformer is selected implicitly by calling setProjection()
is mean when you use criteria.setProjection,the result will not List EmpUserImpl,because ResultTransformer is change to "PROJECTION" from "ROOT_ENTITY".it will packaging by Projection(like select name,oid .. ).
so, if you want to return List EmpUserImpl you need set Projections.property("name").as("name").,(if you need name just set name).
this is my code .
Criteria criteria = session.createCriteria(EmpUserImpl.class);
criteria.setProjection(Projections.projectionList()
.add(Projections.groupProperty("company").as("company"))
.add(Projections.property("name").as("name"))
.add(Projections.property("company").as("company")));
criteria.setResultTransformer(Transformers.aliasToBean(EmpUserImpl.class));
List<EmpUserImpl> list = criteria.list();
for (EmpUserImpl empUserImpl : list) {
System.out.println(empUserImpl.getName());
}
it can work . i hope it can help you.
I think you can use : criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);