Thursday, November 20, 2014

JasperReports/iReports dynamically show and hide fields conditionally

Introduction

With JasperReports and its visual designer iReports you can have (blocks of) fields collapse based on certain conditions.
You can use a subreport, but that's not necessary. This post describes how to show/hide fields without subreports.

How

Basically you have to do two things:

  1. Put the elements (static text, textfields etc) you want to hide on a frame. Make sure the fields are not behind the frame.
  2. Set the correct properties on the frame, including the expression to show/hide it dynamically. By hiding the frame you hide all the fields on it. 
The most important thing is to make sure no other element besides those that need to be on it is overlapping with the frame! Below is a screenshot to make it clearer.
There are three static and three textfields on the frame. Plus two (separate!) vertical lines.


Note the green, red and black vertical lines in the screenshot: the red and black vertical lines are not on the frame at all. The frame has its own green vertical line. That way JasperReports can shrink it based on the condition. Otherwise it doesn't know what to do with the overlap, and doesn't (can't?) collapse it. Notice also the frame is selected (little square blue boxes on its lines) to make clear from where to where the frame runs.
So basically you have to make sure the frame is all by itself, all its elements only on the frame, and no other elements overlapping the frame.

PS: it might be possible to do it per field, but since I needed at least a label + field to be shown/hidden, I didn't even try that.

To put in the other necessary settings, you have two ways of doing that:

  1. Via the XML:

    Put in the condition of the frame. So if theObject is not null, the frame will be shown. Also make sure you add 'isRemoveLineWhenBlank="true"'. E.g:

  2. Or via the Eclipse properties tab: see below screenshot:


    Notice setting the flag and the expression, see the arrow pointing at $F, that's the start of the same above expression in the XML.


Thursday, July 3, 2014

Vaadin 7 + Spring 3 + JPA project summary and lessons learned

This blogpost is a short summary of the Vaadin 7.0 project I did last year, including tools used, lessons learned and a bunch of screenshots to show the results.

Tools used

  • Spring 3.2 including annotation based configuration, Spring Task*Executor framework
  • JPA2 with Hibernate 4.2 + JPA modelgen, including Envers for auditing
  • JMS 2
  • Vaadin 7.0.1
  • JAXB 2.1
  • Spring WS 2.1
  • Shiro 1.2
  • JUnit 4.8
  • Mockito
  • Eclipse 3.7
  • SOAP + SoapUI
  • MySql 5.5 + H2
  • Tomcat 7
  • Jenkins
  • Fisheye/Crucible
  • Sonar
  • Subversion
  • Maven 3
  • Java 6

Lessons learned

  • Don't only trust SoapUI of being able to validate your WSDL. Also try to generate stubs with Axis2 and JAXWS generators. *AND* actually make sure you can make a call to the webservice, because on our project it did work perfectly fine in SoapUI, but not in Axis nor JAXWS. Example: soap fault in operation but not in porttype defined. It required the project to defining one or more xyz.jaxb files for JAX-WS  (using .episodes dit not work for us). Then use these in the wsimport etc. Related links: Compiling multiple WSDLs that share a common schema and Customizing Java Packages.
  • If sources not found of e.g junit-4.11 (junit.org is also giving a lot of 404s), then run mvn clean dependency:sources, that will download the sources too into the .m2 repo.
  • Try to keep the WSDL and XSD as semantic as possible, so use Strings instead of IDs for for example lookup /reference values like: started, finished. Makes the interface much more readable and understandable by just looking at it.
  • count(case ...) is NOT supported by Hibernate criteria API, when using it it gives: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: case near line 1, column 92 [...  Use sum(case) since that is supported.

    So instead of:

    cb.count(cb.selectCase().when(cb.equal(workOrder.get(WorkOrder_.priority), 1), workOrder.get(WorkOrder_.priority)).otherwise(0)),
    Use:

    cb.sum(cb.selectCase().when(cb.equal(workOrder.get(WorkOrder_.priority), 1), 1).otherwise(0)) 

    SQL equivalent:

    Instead of:

    COUNT(CASE WHEN priority = 1 THEN priority ELSE NULL END) AS prio1,

    Use:

    SUM(CASE WHEN priority = 1 THEN 1 ELSE 0 END) AS prio1,

    Links about this:

    https://forum.hibernate.org/viewtopic.php?f=1&t=992497
    https://forum.hibernate.org/viewtopic.php?p=2393060
    http://stackoverflow.com/questions/11011151/jpa-criteria-query-order-by-enum-values
    Sums replacement for count
    JPA 2.0 spec including 'case expressions' and this one and this one.
    http://stackoverflow.com/questions/775787/plsql-get-sum-for-each-day-of-week-and-total-sum-for-week-in-a-single-query
  • When trying to upgrade from Vaadin from version 7.0.1 to 7.0.4 by updating the version number in the pom.xml, a serial UID problem occurred when generating the widgetset for this new version:

    [INFO]  at com.google.gwt.dev.Compiler.main(Compiler.java:177)
    [INFO] Caused by: java.io.InvalidClassException: com.google.gwt.dev.jjs.ast.JMethod; local class incompatible: stream classdesc serialVersionUID = 5017484276333252513, local class serialVersionUID = 9103713597467037978

    Tried it then with 7.0.2, that one worked fine! 7.0.3 gave the same error. This post talks about maybe the GWT cache being the problem. So I deleted the directory (even though the timestamp on that directory was recent!) and that worked. In my case the directory to delete was:

    D:\workspace\xyz\frontend\app-web\src\main\webapp\VAADIN\gwt-unitCache 

The application

Below you can find a bunch of screenshots of the resulting application Planning Optimizer or ePOp.



The login screen, authentication via Shiro with a custom Realm that does a SOAP call to the backend:


The dashboard so the planner can immediately see the status + what needs attention first:

The Vaadin Charts 90 days look ahead graph shows the status for the coming 90 days. Clicking on a bar shows the orders at the bottom table for that day. A similar 12 weeks graph is available on another tab:



Different ways of looking at the status exist, for example these week-based graphs, the first one based on craft, the second one on priority:
Notice in the above graph the multiple y-axis: the bars are for the left y-axis, the lines for the right y-axis.

And other filters:




When clicking on a row in the bottom table, details for that order can be filled in:

Links (from a whitelist) and documents can be attached too (including drag 'n drop), and in the end a PDF can be generated with all the info (including the attachments + where the links are pointing to!) included:

Wednesday, June 18, 2014

Android and iOS app discovery and search engines overview

Introduction

Recently a friend of mine asked how to check if an app or type of app with certain functionality already exists. He had a great idea for an app (he thinks :) so wanted to figure out: does such an app already exist?
Entering the name of an app is not sufficient of course, you want to search on offered functionality too, since the name of the app might not match the functionality. E.g Tinder is a dating app, but the name Tinder doesn't show that (at least not in its early days!).

I knew there are a couple of websites and apps that provide that, but had a hard time coming up with more than one. This list is pretty ok, but already partly out of date.
So I decided to create this blogpost with a list of the current recent websites and their apps and some(!) app-only search apps that provide app discovery.

Main focus of this post will be on app search engine websites, not apps! Mainly because the research for an existing app you'd probably like to do behind a computer (laptop or PC), not a phone or tablet, since it requires quite some typing. E.g all types of ways of describing the functionality.
Also most focus will be on Android, but also some iOS search engines will be mentioned.

Below is a list of app search engines I found, including a screenshot and my short take on it. If any search engine is missing, please leave a comment and I'll check it out. If appropriate I'll add it to this page!

App discovery and search engines

1 Standard stores

Of course the standard app stores have their own search engine, either online and/or on the platform itself, e.g:


There are quite some more 3rd party app stores like SlideMe, but usually these are considered less important than the "big ones", so chances are minimal that there's an app in those stores which is not in the big app stores. But for adult content you mighthave to check those.

2 AppBrain

URL: http://www.appbrain.com/
Platforms: Android
Has app: yes


3 Quixey

URL: https://www.quixey.com/
Platforms: Android, iOS, Windows, Blackberry
Has app: yes


4 App Annie

URL: http://www.appannie.com/
Platforms: Android, iOS, Amazon, Mac
Has app: yes but can't tell from the screenshots if it includes searching etc



This is more intended for app analytics and ASO (app store optimization) and SEO but still usuable for checking what type of apps exist, e.g by keyword.
App Annie recently purchased Distimo, another well known app statistics/analytics platform.

Most parts are for free, "enterprise" is not.

5 AppGravity

URL: http://appgravity.com/
Platforms: Android, iOS
Has app: yes



6 AndroLib

URL: http://www.androlib.com/
Platforms: Android
Has app: no


Still refers to "Android Market" instead of Google Play.

7 AppsZoom

URL: http://www.appszoom.com/
Platforms: Android, iOS
Has app: yes


8 MobileDevHQ (formerly known as AppStoreHQ)

URL: http://www.mobiledevhq.com/
Platforms: Android, iOS
Has app: no


Similar to AppAnnie more intended for ASO and analytics and keywords optimilization, but can still come in handy. 

9 Regular search engines

More and more regular search engines are optimizing for finding apps. For for example Google, Apple and Amazon it's of course in their own interest to help people find apps for their platform.

10 App only

There are also many apps out there trying to help you find apps. I did not investigate those, but a query you could run to find a list is this one

11 DIY

If none of the above work for you, you could consider writing your own search engine/crawling engine. Here's a script for the Google Play store.


Saturday, February 8, 2014

Fairphone is in!

Yes it's in (well already for over a month), the Fairphone! Since I was one of the first 10.185 backers, a special edition with an extra message: