Newbie in Jspresso

10 posts / 0 new
Last post
diega
Offline
Joined: 06/17/2009
Newbie in Jspresso

Hello, I am new at Jspresso and currently evaluating it, and first of all I wanted to congratulate the Jspresso team for such an amazing framework.

I wanted to know if there is anyway to customize the way Jspresso creates Hibernate mappings and creates my tables, since I already have a model and my hibernate mappings in another application. Of course I am willing to adapt to the framework since it has such great and many features, but for instance I use a table-per-class-hierarchy mapping strategy with a discriminator value for each sub-class, is it possible to achieve this with Jspresso? I've seen in the examples that Jspresso uses joined-subclass by default.

Thank you in advance. Regards,

 

DiegA.

vvandens
Offline
Joined: 05/29/2008
Newbie in Jspresso

Hi DiegA,

Thank you for the support. I't's always good to hear Wink.

I wanted to know if there is anyway to customize the way Jspresso creates Hibernate mappings and creates my tables, since I already have a model and my hibernate mappings in another application

Jspresso uses a freemarker template to generate the domain model (the XDoclet annotated entities and components). Once the domain model is generated, it is  then processed by XDoclet to generate the actual hibernate mapping files. If you want to customize what's generated, modifying the template is the way to go. The default one is located in jspresso-tools jar:

/org/jspresso/framework/tools/entitygenerator/HibernateXdocletEntity.ftl

You can configure the hibernate generated mapping by creating a new template starting from the default one. Then you have to register it into your maven build. Up to 3.0.0 included, you have to modify the archetype generated pom.xml in [your project root]/core so that it references your new template and the package from where it's loaded : update the <id>generate-entities</id> section.

Starting from 3.0.1 (still snapshot but useable), the template location has been variabilized, so you would just pass properties to the maven execution, e.g. :

mvn package -Dgenerator.templateName=[your template file name] -Dgenerator.templateResourcePath=[/package/where/your/template/resides]

I use a table-per-class-hierarchy mapping strategy with a discriminator value for each sub-class, is it possible to achieve this with Jspresso?

I don't think that it will be problematic, although I've not tested it. Just beware that Jspresso assumes some features on the domain model to allow for generically implemented features. Take a look at this post where I've listed them.

But in the case of only changing the inheritance strategy, it should be completely encapsulated by Hibernate, so it should remain invisible to the framework.

Don't hesitate to post if you have any further question.

 

Regards,

Vincent

diega
Offline
Joined: 06/17/2009
Customizing the mappings and model

Thanks Vincet for your prompt answer. I will take a look at HibernateXdocletEntity.ftl to see how could I customize inheritance, also because I would like to use my own column names for the tables (since I have already a model and a DB), and I didn't see this feature anywhere.

On the other hand, in the case I consider using my own mappings and entities (taking your constraints in consideration, which sound pretty fair!), I have a few questions:

1) how could the model.xml be written, do my beans have to be like the regular ones:

  <bean
    id="City"
    class="org.jspresso.framework.model.descriptor.entity.basic.BasicEntityDescriptor">
    <constructor-arg
      value="org.jspresso.hrsample.model.City" />

I mean, the property class is the same? and the constructor-arg?

do you have any example?

2) Do my hbm's have to be written with the same headers Jspresso generates:

<hibernate-mapping default-access="org.jspresso.framework.model.persistence.hibernate.property.EntityPropertyAccessor">
  <class persister="org.jspresso.framework.model.persistence.hibernate.entity.persister.EntityProxyJoinedSubclassEntityPersister" dynamic-update="true" table="CITY" dynamic-insert="true" name="org.jspresso.hrsample.model.City">

Or this is just for Jspresso to control access to properties and all that stuff?

Thanks again for your help, and excuse me if I am not all that clear.

 

DiegA.

 

vvandens
Offline
Joined: 05/29/2008
Customizing the mappings and model

Hi DiegA,

As I wrote it on the post I've referred to above, using an existing domain model with Jspresso is a fairly unexplored road and may be full of traps. Having said that, I'm actually very interested in helping you along if you wish. Jspresso has been built with "coding against interfaces" in mind so that layers remain as loosely coupled as possible.

Regarding your questions :

1/ Your entities (and inline components) still have to be described using regular Jspresso descriptors. They form an extensive description of the domain model that will traverse all the layers and help, for instance, the UI factories in generating adapted screens. And yes, you have to keep the "name = classname" scheme since it is used to retrieve the entity class at runtime (see the AbstractComponentDescriptor.getComponentContract() implementation). Of course you could write your own subclass of BasicEntityDescriptor, override this behaviour if needed and use it in model.xml.

2/ As you surely noticed it, Jspresso generated entities and components don't hold any implementation by themselves. They are just interfaces that are materialized at runtime using a generic implementation wrapped in J2SE proxies. That's why we can't use Hibernate direct accessors to operate on them. We could have used Hibernate property accessors that work with beans accessors, but hydrating an entity would have then triggered all kind of behaviour (through the registered Jspresso property processors) that we don't want during this technical stage.

That's why we've introduced the straightGet/straightSet methods that are used by the EntityPropertyAccessor you mention. Technically, you don't have to use them on "classic" beans. But be aware that Jspresso has to know when a property has changed (through a PropertyChangeEvent), even when this change is operated by the ORM engine. Using direct accessors on your beans will be fine on the ORM side but will break this notification contract.

Regarding EntityProxyJoinedSubclassEntityPersister it is useless in your case. We had to write it for Hibernate to handle inheritance hierarchy of J2SE proxies as it is not ready for it. And it is used for joined-subclass strategy...

I'm sorry, but I can't provide you with a concrete example for achieving what you need (never done it myself). Again, there will certainly be incompatibilities with the current implementation but they should be workable. One of them I can think of is the way Jspresso deals with the Hibernate session and the "well-known" LazyInitializationException. As of now, the job of resolving Hibernate lazy loaded references is being trigerred by the generic component/entity implementation. This would surely have to change to support an existing model.

And don't worry, that was all clear. I hope my answer is too Wink.

 

Best,

Vincent

diega
Offline
Joined: 06/17/2009
Table per hierarchy implementation for Jspresso

Hello, We 've been working quite a bit with my good friend Bauna (more him than me), with the table per hierarchy implementation and we think we have a very nice approach on it.

We have created a couple of new classes to telll Jspresso that we want to map our class with discriminators. Here is a sample:

 

    <bean id="Producto" class="com.zetti.ftpos.jspresso.model.descriptor.entity.basic.DiscriminatorEntityDescriptor">
        <constructor-arg value="com.zetti.ftpos.model.Producto" />
        <property name="discriminatorValue" value="0"/>
        <property name="discriminatorDescriptor">
            <bean class="org.jspresso.framework.model.descriptor.basic.BasicIntegerPropertyDescriptor">
                <property name="name" value="discriminador"/>
                <property name="mandatory" value="true"/>
            </bean>
        </property>

and the subclass only needs the discriminatorValue Tag.

We have also changed the ftl file for generating the Interfaces and added a new class EntityProxySingleTableEntityPersister to replace the one you use (EntityProxyJoinedSubclassEntityPersister) in this situations.

Also we changed the pom file (we are not using version 3.0.1) in the core folder:

                <java classname="org.jspresso.framework.tools.entitygenerator.EntityGenerator" classpathref="spring.beans.classpath" failonerror="true">
                  <arg value="-applicationContextKey" />
                  <arg value="ftpos-model-context" />
                  <arg value="-templateResourcePath" />
                  <!-- arg value="/org/jspresso/framework/tools/entitygenerator" / -->
                        <arg value="/com/zetti/ftpos/tools/entitygenerator" />
                  <arg value="-templateName" />
                  <arg value="HibernateXdocletEntity.ftl" />
                  <arg value="-outputDir" />
                  <arg value="${generator.dest}" />
                  <arg value="-includePackages" />
                  <arg value="com.zetti.ftpos.model" />
                </java>

Here I am sending you a link for you (and everyone else who wants this) to download an Eclipse project containing this files

http://drop.io/jspresso_with_discriminator

Check it out and tell me what do you think, and if you consider including some of this in your next release dont forget about us ;).

Greetings,

 

DiegA and Bauna.

vvandens
Offline
Joined: 05/29/2008
Table per hierarchy implementation for Jspresso

Hi DiegA,

This is a nice and smart job! It can definitely find its way to the Jspresso codebase.

I still have a minor concern with the way you implemented it. Hibernate inheritance mapping is tied to the physical implementation of the OR mapping. The application itself will actually never care about it on the logical level. As of now, all model descriptors (including entity descriptors) are there to describe the domain model in a physical agnostic way (at least as agnostic as possible...). Then, I would maybe try to separate the OR hints somehow from the descriptor themselves since those hints will only serve at compile time (during the mapping generation phase).

I've created a feature request in the Jspresso tracker for you to be able to follow the implementation progress : https://sourceforge.net/tracker/?func=detail&aid=2810906&group_id=231671... . I don't have much time for it right now (working on the Qooxdoo front-end) but I will definitely take care about the more general "use an existing model with Jspresso" in the near future.

BTW, what do you mean by "dont forget about us" ?

 

Thanks again.

Best,

Vincent

diega
Offline
Joined: 06/17/2009
About agnostics ways

Vincent, I am so glad you liked our job!. And I agree about what you say about the way we implemented it, it definitely trascends the logical tier, and it looks a little bit un-elegant (if there is such an expression). But we think that in some way it becomes inevitable because sadly there are many times in the real world when you have to deal with physical constraints, and it's not always possible to keep our code as pretty as we would like to. Our case now is the fact that we have already an existing model, and we yet have to deal with our own column and table names, but consider also performance optimizations in querys and batch processing in production stage, is it always possible for Jspresso to address this kind of concerns from the logical approach?, my experience tells me that there will be many issues in the way.

Actually we had recently dropped a very nice framework for similar reasons (JMatter, I don't know if you are familiar with it), it implements the Naked Object Pattern, and it generates beatiful Swing applications (it's working on extending the UI generation engine to use Wings like Jspresso already does) but it only has one tier, and it's a mess, you end up without much control over many aspects of your application, or the work you need to put in the customization is greater than the time you save using the framework in the first place.

I think that it would be great if Jspresso had this concerns in mind, since you are already using Spring, you could make the framework even more pluggable than it already is. Like for example the EntityGenerator and the GenerateSQLName class, you could inyect your own Name Generator into the EntityGenerator so as to customize the naming strategy or to send a mapping file where you could put exceptions to the automatic name generator algorithm taht you use (which works great for 90% of my column names) like "clientFirstInvoice" -> "cli_first_inv".

Another suggestion If I may, and I don't want to sound too demanding, is that since you have such an amazing feature for generating an automatic default UI without writing anything in view.xml whatsoever, it would be great if instead of it, the view.xml would be automatically generated. Maybe it could be done at compile time (optionaly), just like you generate the Model Interfaces, this would be very helpful for generating customized UI even faster, since you could learn the howto write the view.xml more easily and most of the job would already be done, because you could cut & paste components here and there, which is very useful.

I am just starting with Jspresso and have yet to learn a lot (for example the ActionsMaps, maybe you have a more extensive documentation on it), we will keep on suggesting and posting our achievements to you if you dont have any problems with us collaborating on everything that we can.

Regards,

 

DiegA.

 

PS: by "dont forget about us" we meant just an acknowledgement somewhere in tiny fonts.. that's all! :P

vvandens
Offline
Joined: 05/29/2008
About agnostics ways

Hi DiegA !

 

sadly there are many times in the real world when you have to deal with physical constraints...is it always possible for Jspresso to address this kind of concerns from the logical approach?

I completely agree with your point here and of course, there are a lot of room for physical optimizations (one of them is DB indices, for instance) that Jspresso doesn't handle from scratch (is it even possible ?). I've also been part of large ERP-like projects and I think know what you mean Wink.

I would just try to keep things cleanly separated whenever it's possible. For instance, we could have another kind of physical "descriptors" that would only be used at compile/generation time, living in another Spring context file that is only registered when the generator runs in the maven build. This special generation context would hold everything that doesn't need to be kept at runtime (e.g. the Hibernate inheritance mapping strategy).

 

we had recently dropped a very nice framework for similar reasons (JMatter, I don't know if you are familiar with it)

I've heard/read about JMatter but never practiced. Jspresso still has a small community and in a way, that's an opportunity for fast improvements when needed. So don't hesitate. Even if we have to make a living outside of Jspresso, we try hard to be as responsive as possible.

 

I think that it would be great if Jspresso had this concerns in mind, since you are already using Spring, you could make the framework even more pluggable than it already is.

Well, a Jspresso application is "just" an assembly of Spring beans. And Spring brings the magic of being able to override bean definitions whenever you need it. For instance, you can override standard Jspresso beans (keeping the same id , of course) in the your application spring config files and adapt each and every default behaviour. This can lead to feature enhancements for the price of a few lines of code (e.g. introduce KPIs, change part of the UI generation, ...), or even clean patching of features you would like to fix/improve (until Jspresso offers a solution Wink).

This is mainly due to the fact that your application spring config files are registered after the Jspresso framework ones and thus take precedence.

 

...Like for example the EntityGenerator and the GenerateSQLName class...

Well, I'm not on the same road here. For this precise example, I would rather make a Maven plugin out of the entity generator; and the naming strategy would be one of the configuration options among others. But time is running out and the antrun plugin was (sadly) the quick way to go to get everything integrated in a single maven command build.

 

it would be great if instead of it, the view.xml would be automatically generated

I like the idea of generating "ready to use" view parts that you could assemble. But today the view.xml is produced by the Maven archetype to bootstrap the application development. Afterwards, e.g. when you have begun to describe your model, it will never be touched again by the build process. In this area, I really think that the future of Jspresso lies in an Eclipse plugin that would help the developer in designing (assembling) the application by "hiding" the application Spring config files.

But having said that, It would be possible to include, during the Maven generation process, the creation of an XML file that would serve as a depot for generated views that you could cut and paste in your actual view.xml.

 

maybe you have a more extensive documentation

All I have written is available. There is no hidden stuff that I would keep for super-privileged customers (until now, at least Wink). I know that there are a lot of areas that are not covered enough (actions is one of them), but ultimately, there is the source-code... and the forum. I will be glad to answer your questions in detail (it will be then a good source for improving the reference manual). Moreover, I've received a very clever suggestion of building a showcase application that would demonstrate interactively each and every Jspresso features (from the model to the views, passing by the actions, the workspaces and modules, printing, external components integration, wizards, ...), along with their individual sourcecode. This is high priority on the @TODO and I think it will really help. But I definitely want to finish the Qooxdoo integration before so that we can have an AJAX fron-end that is even better than the Flex one. I'm 80% done on it.

 

...if you dont have any problems with us collaborating on everything that we can.

Of course, you're warmly welcome!

 

..."dont forget about us" we meant just an acknowledgement somewhere in tiny fonts.

What about a section on the site that would list suggestions / ideas / pieces of code that have been suggested/contributed ? Would it fit ?

 

Best regards,

Vincent

diega
Offline
Joined: 06/17/2009
Thank you so much!

Vincent, thanks so much for your time. I agree a showcase application would really help, of course an Eclipse plugin would be awesome.

The Qooxdoo integration sounds really cool (I really dont know much about it, is it so different than Wings, why both?), but for the moment I wont be needing it, definitely in the future. Right now I am developing a POS application for the desktop, that will integrate with an ERP web application (we have that one in common) that's already in production. Maybe in the future I can migrate my ERP to Jspresso, who knows!. BTW, do you have a Roadmap somewhere? I couldn't find it.

Right now I am trying to create a prototype of some screens and I have some dumb questions for you:

1) How can I display a my view directly without the initial filter screen?

2) Is there an easy way to make the icons bigger?

3) Why do the child-windows dont have the X button for closing them? How could I add that button?

4) About the grid in the filtered views. Is it possible to make them readonly? and to edit the rows by double-clicking them?

I told you the questions were kind of dumb!, just point me in the right direction and I'll do the rest.

 

BTW, the "dont forget about us" was kind of a joke nevermind about it!

 

vvandens
Offline
Joined: 05/29/2008
Your questions

DiegA,

Nothing is dumb outhere Wink. And your questions are just valuable feedback and help improving Jspresso.

 

1) How can I display a my view directly without the initial filter screen?

Well, in that case, you have to declare a org.jspresso.framework.application.model.BeanModule explicitely in the modules list of your workspace. Configure it with a projectedViewDescriptor that references your view and a componentDescriptor that references the root model it works on. Of course, you should configure other properties like name, description, ... Then, you have to tell Jspresso how to populate the model when the module shows. This is done by registering a startupAction on the module itself that will do the job of retrieving the model from somewhere (or maybe create it in memory). Here is a skeleton of such a module startup action :

public class MyStartupAction extends AbstractBackendAction {
@Override
public boolean execute(IActionHandler actionHandler, Map<String, Object> context) {
BeanModule myModule = (BeanModule) getModuleConnector(context).getConnectorValue();
Object myBean = [retrieve or create your model]
myModule.setModuleObject(myBean);
return super.execute(actionHandler, context);
}
}

 

2) Is there an easy way to make the icons bigger?

Not in the 3.0.0 version. Icon dimensions are hardcoded in final static constants and yep, this is bad. But I've just improved it in the new 3.0.1-SNAPSHOT so that the icon factory can now be configured with the dimensions to use for the icons. If you want to change them, you can do it by overriding the abstractIconFactory bean definition in your application Spring config files (this is the parent of all icon factories), e.g. :

  <bean
abstract="true"
id="abstractIconFactory"
class="org.jspresso.framework.view.AbstractIconFactory">
<property
name="okYesIconImageURL"
value="classpath:org/jspresso/framework/application/images/ok-48x48.png" />
<property
name="noIconImageURL"
value="classpath:org/jspresso/framework/application/images/no-48x48.png" />
<property
name="cancelIconImageURL"
value="classpath:org/jspresso/framework/application/images/cancel-48x48.png" />
<property
name="infoIconImageURL"
value="classpath:org/jspresso/framework/application/images/info-48x48.png" />
<property
name="warningIconImageURL"
value="classpath:org/jspresso/framework/application/images/warning-48x48.png" />
<property
name="errorIconImageURL"
value="classpath:org/jspresso/framework/application/images/error-48x48.png" />
<property
name="forbiddenIconImageURL"
value="classpath:org/jspresso/framework/application/images/forbidden-48x48.png" />
<property
name="backwardIconImageURL"
value="classpath:org/jspresso/framework/application/images/backward-48x48.png" />
<property
name="forwardIconImageURL"
value="classpath:org/jspresso/framework/application/images/forward-48x48.png" />
<property
name="upIconImageURL"
value="classpath:org/jspresso/framework/application/images/1uparrow-48x48.png" />
<property
name="downIconImageURL"
value="classpath:org/jspresso/framework/application/images/1downarrow-48x48.png" />
<property name="tinyIconSize">
<bean class="org.jspresso.framework.util.gui.Dimension">
<property name="width" value="32"/>
<property name="height" value="32"/>
</bean>
</property>

</bean>

There are 4 icon dimensions that are used in Jspresso depending on the context (button, message dialog, ...), and thus 4 dimensions that can now be configured : tiny, small, medium and large icon sizes.

 

3) Why do the child-windows dont have the X button for closing them? How could I add that button?

Well, not easily workable by overriding. Depending on the UI channel used, the different UI controllers may use a MDI UI with internal frames (Swing, ULC and Qooxdoo) or a simple stacked view (WingS and Flex). This desicion is made in the UI controller (DefaultXXXController) but is not easily changeable as of 3.0.0. But I also improved it in the new snapshot so that MDI workspaces internal frames are now closeable.

 

4) About the grid in the filtered views. Is it possible to make them readonly?

As a general tip you can make any Jspresso view readonly by setting the readonly property to true in the view descriptor. If you want to change the default state of the filter view table, you just have to do the following (look for your module definition in frontend.xml that should extend abstractFilterableBeanCollectionModule) :

  ...
<bean parent="abstractFilterableBeanCollectionModule">
...
<property name="projectedViewDescriptor">
<bean parent="filterableBeanCollectionModuleView">
<property name="readOnly" value="true"/>
</bean>
</property>
</bean>

 

and to edit the rows by double-clicking them?

Well again, I had to slightly improve the framework to achieve this. In the new 3.0.1 snaphot, collection property views (list and table) now have a rowAction property that will react on a user double-click. Note that this property will be ignored on the WingS frontend since WingS does not allow to distinguish a double from a simple click. So, to do what you want, you just have to reference the standard addAsChildModuleFrontAction to the filterableBeanCollectionModuleView we've updated above, i.e. :

  ...
<bean parent="abstractFilterableBeanCollectionModule">
...
<property name="projectedViewDescriptor">
<bean parent="filterableBeanCollectionModuleView">
<property name="readOnly" value="true"/>
<property name="rowAction" ref="addAsChildModuleFrontAction"/>
</bean>
</property>
</bean>

 

The Qooxdoo integration sounds really cool (I really dont know much about it, is it so different than Wings, why both?)

There are several advantages over WingS. Qooxdoo relies on HTML divs rather than tables to layout components. This leads to much more flexible layout and richer components (table columns can be moved, split panes, ...), and greater performance (FF has a big performance hole on deeply nested HTML tables) . And I love the look and the design; you should have a look to the Qooxdoo demos to make your mind. But Qooxdoo is a client UI technology and we had to leverage the generic communication layer we have developed for the Flex integration (100% reused Wink).

 

BTW, do you have a Roadmap somewhere?

Not written. But there are plenty of exciting things that are waiting for us.

 

BTW-1, it would be nice if we could try to keep 1 forum thread == 1 subject. This one "Newbie in Jspresso" is quite not a newbie thing anymore Wink. This will help for refering back to single-subject threads when needed.

BTW-2, linking to Jspresso 3.0.1-SNAPSHOT should be just a matter of changing the root pom of your application and replace 3.0.0 by 3.0.1-SNAPSHOT. Or generate a new one by pointing to the jspresso snapshot repos :

mvn archetype:generate -DarchetypeCatalog=http://repository.jspresso.org/maven2-snapshots/

 

Hope this helps,

Have a good time with Jspresso.

 

Best

Vincent