If I have an object with BigDecimal property, I want to display it in a Table with a specific formatting: 2 fractions, and a "+" or "-" sign according to the amount.
Eg: +10.50, -3.20
How can this be achieved in a vaadin table? There is a method table.setConverter(..), but this would actually force to convert between eg a BigDecimal.class and a String.class. What I'm more after is just a view formatter that just displays the object data differently.
While using Table.formatPropertValue() for formatting table columns is a viable option, I strongly discourage from using this method when working with Vaadin 7. formatPropertValue() is the old Vaadin 6 way of formatting Table values. This method is still available in Vaadin 7 for downward compatibility. Using this method is problematic in several ways:
It is not typesafe. Since you only get a Property<?> as a parameter you first have to check for the concrete type of the property value.
You have to inherit from Table only to adapt the formatting of one or more columns. Class inheritance is definitely the wrong approach for adapting a class's behavior for one particular use case. If you have more than one such cases, you'll end up implementing a bunch of Table subclasses which later can't be easily interchanged.
You hard-wire conversion code (BigDecimal to String) to the concrete implementation of some UI component. That's bad for re-use. What if you need that conversion in some other place, say when you display a BigDecimal on a Label? You'd have to duplicate this code or somehow extract it into a separate class or method.
The last point is exactly what Vaadin 7 does for you: keep conversion logic separate from some concrete UI component. This is what the com.vaadin.data.util.converter.Converter interface is for. So, the OP was quite right in his/her first assumption: Table.setConverter() is the way to go with Vaadin 7. Converters are typesafe and allow for separation of concerns.
The objection that the Converter which can be set with Table.setConverter() only converts from BigDecimal to String is not justified in this case. Table.formatPropertValue() doesn't do anything different - it also converts to String. But this is obvious, a Table doesn't display anything other than String data in its columns. In fact, the default behaviour of Table is to call the toString() method on Property value types that it can't convert on its own.
For using Converters, see section 9.2.3 of the Book of Vaadin.
Override the protected method Table.formatPropertValue():
public class My_table
extends Table
{
#Override
protected String formatPropertyValue(final Object a_row_id,
final Object a_col_id,
final Property<?> a_property)
{
if (a_property.getType() == BigDecimal.class
&& null != a_property.getValue())
{
return "formatted-value";
}
return super.formatPropertyValue(a_row_id, a_col_id, a_property);
}
}
See Book of Vaadin section 5.16.6. Formatting Table Columns.
You have to write your own table class extending Table and override formatPropertyValue(Object rowId, Object colId, Property<?> property).
See section 5.15.6 in the book of Vaadin
Related
I have a Java enum as an input in a DMN decision table. The DMN call is embedded directly in the Java app. So take some enum:
public enum Foo {
ONE, TWO
}
I pass an instance of this enum as an input - dmnContext.set("Foo", foo);
I hoped to be able to set a decision table input for foo of type string, and have a rule that matched "ONE". However, this doesn't work, because there is no POJO-String conversion. In the Java code, I could store foo as a String and validate it against the enumerated values (i.e. check foo is in the set ["ONE", "TWO"]), but this will complicate other parts of the application.
How can I achieve this while still using an enum type?
Please refer to this existing JIRA record comment section, for the explanation about:
why you are experiencing that behaviour
and why you should convert your Java-enum to the expected DMN type (which I guess) is a FEEL:string , and not an enum
You can use Jackson to achieve this, instead of resorting to custom code or DMN model modification.
Don't hesitate to Subscribe to the JIRA linked above, as we're hoping of making that work out-of-the-box; but is not trivial since the DMN RTF is thinking about introducing Enumerations directly in DMN eventually, so we need to take into account today what might happen tomorrow.
Since you are linking to Red Hat Product documentation, a reminder that you are strongly encouraged to open a Customer Portal ticket at https://access.redhat.com/support/cases/#/ if you have a Subscription.
I will appreciate your feedback following there references/pointers and I hope those helps
I have created my own Java Class (type) to have life just a little easier when displaying money (euro)-values in jasper reports.
public class Euro extends Number implements Comparable<Euro> {
#Override
public String toString() {...}
#Override
public boolean equals(Object obj) {...}
#Override
public int hashCode() {...}
}
The data is displayed in table and everything works fine. Even sorting the whole column works great. But, if i want to filter the column like "is greater than" - no data is displayed after filtering.
When i changed the type of the data to BigDecimal sorting works.
What i'm doing wrong? Or can anyone tell me what exaclty jasper do when it tries to filter data?
The problem was hat jasper doesn't know the correct data-type of the column, which should be filtered.
So, you have to define which field or variable should be filtered:
The columns in the table that are neither sortable nor filterable contain complex formulas in their detail text field expressions. JIVE looks at the expression in the detail text field to understand what is the data source field or variable it needs to sort and filter after. When the text field uses a simple expression with only the name of a field or variable, things work smooth.
Another approach is to [...] specify at column level in the table component, which is the field or variable to use for sorting and filtering, using one of the following two custom properties that can be set in the column tag/object:
net.sf.jasperreports.components.table.column.field
net.sf.jasperreports.components.table.column.variable
How to make JIVE filtering/soring feature work on column in the table that contains expression
Trying to create my own shiny ORM system (not that important information), I'm currently struggling with java inheritance limits. Here is the concept:
public class UserDescriptor implements TableDescriptor {
public static final UserDescriptor INSTANCE = new UserDescriptor();
private UserDescriptor() {
}
public String getTableName() {
return "user";
}
// ======= Columns definition
public static final AbstractColumn<Integer> ID =
new IntegerColumn("id", AbstractColumn.Attribute.NOT_NULL);
public static final AbstractColumn<String> ALIAS =
new StringColumn("alias");
// ... and some more...
}
Hope it's clear enough. These are then used with static import like:
map = JDBCHelper.selectFirst(UserDescriptor.INSTANCE, Arrays.asList(ID, ALIAS));
where the list (2. param) is what I need to fetch from table defined by UserDescriptor. map variable holds custom map, which internally has signature similar to <AbstractColumn<T>, T> and method
public T getValue(AbstractColumn<T> col);
so I'm getting the value then type-safe
Integer id = map.getValue(ID);
String alias = map.getValue(ALIAS);
This concept is currently working, but:
TableDescriptor concept is a bit verbose. I have many tables and need many times to write twice the type and this long start of each column definition
public static final AbstractColumn<Integer>
This line is result of well-know java limitation - not possible to extend enum class. Otherwise the TableDescriptor would be abstract class with field AbstractColumn<T> defined by explicit constructor and every successor would be enum with columns defined within instances.
This would come with following advantages:
Possibility to make whole thing (conditions, returning columns definition, .....) more type-safe, eg. only enum of specific type can be listed in List parameter for select from single table,
better readability and basis for new developers,
getAllColumns functionality can be done without reflection.
This is unfortunately not possible, so you're now my last hope. I know enum inheritance stuff is on SO many times, but I already have already working solution and maybe it's possible to improve it some other way in this specific case..
What may be some kind of hint - these descriptors must now be int the API part of project to selects to be possible. I was struggling with the way I'd put it to impl. and in API I'll let only some enum listing only overview of the columns:
public enum UserTableColumns {
ID,
ALIAS
}
and map it somehow to UserDescriptor - then I'd be able to use in most cases only this enum, but I didn't figure out yet how this should work..
Current signature of selectFisrt method is following:
CustomResultMap selectFirst(TableDescriptor td, List<AbstractColumn<?>> cols);
and one possible modification would be to change List<AbstractColumn<?>> to some list of enum values, which will be mapped to TableDescriptor so I can check that the values are from single table.
Edit: clarification
I'll try to summarize what I understood from your question and the comments:
Your API should contain an enum like UserTableColumn as well as a method that currently looks like T get(AbstractColumn<T>) but should return the correct type based on the generic type of the column. Since AbstractColumn basically is meant to be an implementation detail you'd like to replace that with the enum, e.g. to get something like this (which won't compile): T get(UserTableColumn<T>).
(Please correct me if I made a mistake somewhere.)
The problem with that is that generics are a compile time tool, i.e. the compiler needs to know about the type that is being used. However, enum values can't have generic types and any parameter (e.g. ID(Integer.class)) would not be available at compile time since it's basically an instance (i.e. runtime) value.
Thus you'll need something like AbstractColumn<T> although that might be another class that only contains the generic type (and implements some interface). That probably requires some manual definition or the use of a preprocessor (have a look at how Hibernate does it for its criteria api).
To end 2014 year I got a simple question I think.
I would like to use "DDD" a bit more, and I'm currently trying to experiment various usecases to learn more about DDD.
My current usecase is the following :
we have a new database schema that is using a classic pattern in our company : modeling our nomenclature table as "id / code / label". I think it's a pretty classic case when using hibernate for example.
But in the OO world things get "complciated" for something this simple when using a API like JDBC or QueryDSL. I need to fetch an object by its code, retrieve its id or load the full object and then set it as a one to one relation in another object.
I wondering :
this kind of nomenclature can be an enum (or a class with String cosnatnts depending on the developer). in DDD terms, it is my ValueObject
the id /code / label in the database is not i18n friendly (it's not a prerequisite) so I don't see its advantages. Except when the table can be updated dynamically and the usecase is "pick something in a combobox loaded from this table and build a relation with another object : but that's all because if you have business rules that must be applied you need to know the new code etc etc).
My questions are :
do you often use the id / ocde / label pattern in your database model.
how do your model your nomenclature data ? (country is perhaps not the best example :) but no matter what how do you model it ? without thinking much I would say database table for country; but for some status : "valid, waiting validation, rejected" ?
do you model your valueObjects using this pattern ?
or do you use lots of enum and only store their toString (or ordinal) in the database ?
In the Java OO objects world, I'm currently thinking that it is easier to manipulate enum that objects loaded from the database. I need to build repositories to load them for example. And it will be so simple to use them as enums. I'm searching some recomfort here or perhaps am I missing something so obvious ?
thanks
see you in 2015 !
Update 1 :
We can create a "Budget" and the first one is mark as Initial and the next ones are marked as "Corrective" (with a increment). For example, we can have a list of Budgets :"Initial Budget", "Corrective budget #1", "Corrective budget #2".
For this we have this database design : a Budget Table, a Version Budge with a foreign key between the two. the Version budget only contains an ID, a CODE and a LABEL.
Personnaly, I would like to remove this table. I don't see the advantages of this structure. And from the OO perspective, when I'm creating a budget I can query the databse to see if I need to create an Inital or Corrective budget (using a count query) then I can set the right enum to my new budget. But with the current design I need to query the database using the CODE that I want, select the ID and set the ID. So yes, it's really database oriented. Where is the DDD part ? a ValueObject is something that describe, quantify something. In my case seems good to me. A Version describe the current status of my Budget. I can comapre two versions just but checking their code, they don't have lifecycle (I don't want this one in particular).
How to you handle this type of usecases ?
It's only a simple example because I found that if you ask a database admin he would surely said that all seems good : using primary key, modeling relations, enforing constraints, using foreign key and avoid data duplication.
Thanks again Mike and Doctor for their comments.
I will hook in in your country example. In most cases, country will be a value object. There is nothing that will reference a country entity and that should know that if the values of the country changes it is still the same country. In fact, the country could be represented as an enum, and some nasty resource lookup functions that translate the Iso3 into a usefull display text. What we do is, we define it as a value object class with iso3, displayname and some other static information. Now out of this value object we define a kind of "power enum" (I still miss a standard term here). The class implementing the country value object gets a private constructor and static properties for each of its values (for each country) and explicit cast operators from and to int. Now you can treat it just like a normal enum of your programing language. The advantage to a normal enum beside having more property fields is, that it also can have methods (of course query methods, that don't change the state of the object). You can even use polymorphism (some countries with different behaviour than others). You could also load the content of the enums from a database table (without the statics then and a static lookupByIso3 method instead).
This you could make with some other "enum like" value objects, too. Imagine Currencies (it could have conversion methods that are implemented polymorphic). The handling of the daily exchange rates is a different topic though.
If the set of values is not fixed (for example another value object candidate like postal adress) then it is not a value object enum, but a standard value object that could be instantiated with the values you want.
To decide if you can live with something as a value object, you can use the following question: Do you want copy semantic, or reference semantic? If you ever change a property of the object, should all places where you used it update, too, or should they stay as they are? If the latter, than the "changed" object is a new and different value object. Another question would be, if you need to track changes to an object realizing that it remains the "same" despite of changing values. And if you have a value object, where you only want specific instances to exist, it is a kind of enum described above.
Does that somehow help you?
My question more specificity is this:
I want users on multiple front ends to see the "Type" of a database row. Let's say for ease that I have a person table and the types can be Student, Teacher, Parent etc.
The specific program would be java with hibernate, however I doubt that's important for the question, but let's say my data is modelled in to Entity beans and a Person "type" field is an enum that contains my 3 options, ideally I want my Person object to have a getType() method that my front end can use to display the type, and also I need a way for my front end to know the potential types.
With the enum method I have this functionality but what I don't have is the ability to easily add new types without re-compiling.
So next thought is that I put my types in to a config file and simply story them in the database as strings. my getType() method works, but now my front end has to load a config file to get the potential types AND now there's nothing to keep them in sync, I could remove a type from my config file and the type in the database would point to nothing. I don't like this either.
Final thought is that I create a PersonTypes database table, this table has a number for type_id and a string defining the type. This is OK, and if the foreign key is set up I can't delete types that I'm using, my front end will need to get sight of potential types, I guess the best way is to provide a service that will use the hibernate layer to do this.
The problem with this method is that my types are all in English in the database, and I want my application to support multiple languages (eventually) so I need some sort of properties file to store the labels for the types. so do I have a PersonType table the purely contains integers and then a properties file that describes the label per integer? That seems backwards?
Is there a common design pattern to achieve this kind of behaviour? Or can anyone suggest a good way to do this?
Regards,
Glen x
I would go with the last approach that you have described. Having the type information in separate table should be good enought and it will let you use all the benefits of SQL for managing additional constraints (types will be probably Unique and foreign keys checks will assure you that you won't introduce any misbehaviour while you delete some records).
When each type will have i18n value defined in property files, then you are safe. If the type is removed - this value will not be used. If you want, you can change properties files as runtime.
The last approach I can think of would be to store i18n strings along with type information in PersonType. This is acceptable for small amount of languages, altough might be concidered an antipattern. But it would allow you having such method:
public String getName(PersonType type, Locale loc) {
if (loc.equals(Locale.EN)) {
return type.getEnglishName();
} else if (loc.equals(Locale.DE)){
return type.getGermanName();
} else {
return type.getDefaultName();
}
}
Internationalizing dynamic values is always difficult. Your last method for storing the types is the right one.
If you want to be able to i18n them, you can use resource bundles as properties files in your app. This forces you to modify the properties files and redeploy and restart the app each time a new type is added. You can also fall back to the English string stored in database if the type is not found in the resource bundle.
Or you can implement a custom ResourceBundle class that fetches its keys and values from the database directly, and have an additional PersonTypeI18n table which contains the translations for all the locales you want to support.
You can use following practices:
Use singleton design pattern
Use cashing framework such as EhCashe for cashe type of person and reload when need.