Till version 5.2 NextReports allowed only cell formatting conditions. But the new version will also bring the possibility to add row formatting conditions.
User can select now a row
and row properties will be seen:
Clicking on formatting conditions, user can add, edit or remove them:
In this example we just alternate background color for rows:
We can go further and alternate not rows, but records data. Consider the following report:
We will modify row formatting conditions for all rows like following:
We will obtain:
We can modify more properties for a row formatting condition. For next report:
we will select background and border properties:
Result is:
We can have any expression used for row formatting. Next shows a row formatting simulation if productivity is less than 50%:
If you want to combine cell and row formatting conditions, keep in mind that cell formatting conditions will overwrite row formatting conditions.
Wednesday, April 18, 2012
Thursday, March 22, 2012
NextReports : Text Rotation
In version 5.2 of NextReports a new property for cells is added: text rotation. This property has meaning only for PDF or EXCEL exporter formats. It can have only three degrees values :
And for -90 degrees value:
- 0 : no rotation
- 90 : text is rotated to the left with 90 degrees
- -90 : text is rotated to the right with 90 degrees
And for -90 degrees value:
Monday, March 19, 2012
NextReports Engine : Report Conversion
Version 5.1 of NextReports was already released, but there is the time to look into next version.
One of the biggest feature, NextReports will resolve in version 5.2 is report conversion. This is not a 'visible' feature to the end user, but a back-end functionality.
NextReports supported from start back-end compatibility with older type of reports. Any new functionality was brought to life without breaking compatibility. For NextReports Engine users (developers) this means that anytime when a ReportUtil.loadReport(String xml) or a ReportUtil.loadReport(InputStream is) was done, no xml exception was raised.
To be more flexible in NextReports evolution, an entirely new convert process was integrated. Using a chain of xml converters, a Next report can be modified to a new structure. Practically if a report with version X is loaded by an Y version of engine, where Y > X, the load method will do the following:
The only differences to NextReports Engine are the signatures of the load methods from ReportUtil class which now throw a LoadReportException:
One of the biggest feature, NextReports will resolve in version 5.2 is report conversion. This is not a 'visible' feature to the end user, but a back-end functionality.
NextReports supported from start back-end compatibility with older type of reports. Any new functionality was brought to life without breaking compatibility. For NextReports Engine users (developers) this means that anytime when a ReportUtil.loadReport(String xml) or a ReportUtil.loadReport(InputStream is) was done, no xml exception was raised.
To be more flexible in NextReports evolution, an entirely new convert process was integrated. Using a chain of xml converters, a Next report can be modified to a new structure. Practically if a report with version X is loaded by an Y version of engine, where Y > X, the load method will do the following:
- get report version (X in this case)
- apply a converter chain process if needed
- load the resulted xml
The only differences to NextReports Engine are the signatures of the load methods from ReportUtil class which now throw a LoadReportException:
public static Report loadReport(String xml) throws LoadReportException { ... }
public static Report loadReport(InputStream is) throws LoadReportException { ... }
Friday, March 09, 2012
NextReports : Notifications with Wicket Push
With version 5.1, NextReports Server implements a much-desired feature: message notification.
In previous versions, when a report was manually set to run, user was redirected to Monitor section. Here running processes can be seen and with an auto-refresh at some time the result will appear in history table, containing the link to the document.
In current version, after a manually run, a message in the top right corner will notify that the process started and that a new message will be issued after finish. This first message has a short life of 5 sec and it will disappear after time elapsed. When process is finished, a new message will be shown containing the link to resulted document. This message will live until the user will close it.
If an error occurred during export process, an error message will be shown.
To see the actual error user has to go to Monitor section and look in history table to "Success" column.
If you schedule a report, you will only be notified about it. No messages when the process is finished will be issued.
To implement this notification feature, NextReports uses wicket-stuff push and jQuery jGrowl.
Using a general Observer pattern, first we need an event ReportResultEvent and a listener interface:
Finally our wicket page will contain a message label:
In previous versions, when a report was manually set to run, user was redirected to Monitor section. Here running processes can be seen and with an auto-refresh at some time the result will appear in history table, containing the link to the document.
In current version, after a manually run, a message in the top right corner will notify that the process started and that a new message will be issued after finish. This first message has a short life of 5 sec and it will disappear after time elapsed. When process is finished, a new message will be shown containing the link to resulted document. This message will live until the user will close it.
If an error occurred during export process, an error message will be shown.
To see the actual error user has to go to Monitor section and look in history table to "Success" column.
If you schedule a report, you will only be notified about it. No messages when the process is finished will be issued.
To implement this notification feature, NextReports uses wicket-stuff push and jQuery jGrowl.
Using a general Observer pattern, first we need an event ReportResultEvent and a listener interface:
public interface ReportListener {
public void onFinishRun(ReportResultEvent result);
}
Our ReportService will manage report listeners for current logged user:public void addReportListener(ReportListener reportListener) {
reportListeners.put(SecurityUtil.getLoggedUsername(), reportListener);
}
public void removeReportListener() {
reportListeners.remove(SecurityUtil.getLoggedUsername());
}
public void notifyReportListener(ReportResultEvent event) {
ReportListener reportListener = reportListeners.get(event.getCreator());
if (reportListener != null) {
reportListener.onFinishRun(event);
}
}
When the process is finished we will create the event and we will notify all listeners:ReportResultEvent event = new ReportResultEvent(...); reportService.notifyReportListener(event);To use jGrowl in Wicket it's easy with an AjaxBehavior. Messages will be kept in Session FeedbakMessages list.
public class MessageAjaxBehavior extends AbstractDefaultAjaxBehavior {
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.renderJavascriptReference(
new JavascriptResourceReference(MessageAjaxBehavior.class, "jquery.jgrowl.js"));
response.renderCSSReference(
new CompressedResourceReference(JGrowlAjaxBehavior.class, "jquery.jgrowl.css"));
response.renderCSSReference(
new CompressedResourceReference(JGrowlAjaxBehavior.class, "jgrowl.css"));
String feedback = renderFeedback();
if (!StringUtils.isEmpty(feedback)) {
response.renderOnDomReadyJavascript(feedback);
}
}
protected void respond(AjaxRequestTarget target) {
String feedback = renderFeedback();
if (!StringUtils.isEmpty(feedback)) {
target.appendJavascript(feedback);
}
}
.......
}
Rendered feedback message contains the jgrowl javascript text. Message can be sticky to live until user close it, or it can have a time-elapsed life using life with a millisecond value.$.jGrowl("message",
{
theme: 'css-class',
sticky: true // life: 5000
}
)
All options of jGrowl can be found here. Finally our wicket page will contain a message label:
Label messageLabel = new Label("message", "");
messageLabel .setOutputMarkupId(true);
messageLabel .add(new MessageAjaxBehavior());
And we will initialize push service:
protected void onInitialize() {
super.onInitialize();
initPush();
reportService.addReportListener(new ReportListener() {
public void onFinishRun(ReportResultEvent result) {
if (pushService.isConnected(pushNode)) {
// forward the Message event via the push service
// to the push event handler
Message message = createMessage(result);
pushService.publish(pushNode, message);
}
}
});
}
private void initPush() {
// instantiate push event handler
IPushEventHandler handler = new AbstractPushEventHandler() {
public void onEvent(AjaxRequestTarget target, Message event,
IPushNode node, IPushEventContext context) {
getSession().getFeedbackMessages().add(
new FeedbackMessage(null, event.getText(), messageType));
target.addComponent(messageLabel);
}
};
// obtain a reference to a Push service implementation
pushService = TimerPushService.get();
// install push node into this panel
pushNode = pushService.installNode(this, handler);
}
Wednesday, February 29, 2012
NextReports: Some Internal Tips
From version 5.1, NextReports Designer allows to instantly open some report or chart when it starts.
There are some system properties which can be used to achieve this:
next.datasource
This property is similar to singleSourceAutoConnect, but when we have more than one data source. NextReports Designer will start and it will connect to this datasource.
next.report
If there is a connected data source (specified by next.datasource system property) this report will be auto-loaded.
next.chart
If there is a connected data source (specified by next.datasource system property) this chart will be auto-loaded.
next.path
If the report or chart is not found in the root node, but inside some folder, this property will specify the relative path. Slashes or back-slashes can be used in any combination.
If both next.report and next.chart system properties are specified, chart property is ignored.
For your installed designer, you can specify system properties inside nextreports.vmoptions file.
For example adding these lines at the end of the file
If your report is found inside /Test/Test1 folder path
There are some system properties which can be used to achieve this:
next.datasource
This property is similar to singleSourceAutoConnect, but when we have more than one data source. NextReports Designer will start and it will connect to this datasource.
next.report
If there is a connected data source (specified by next.datasource system property) this report will be auto-loaded.
next.chart
If there is a connected data source (specified by next.datasource system property) this chart will be auto-loaded.
next.path
If the report or chart is not found in the root node, but inside some folder, this property will specify the relative path. Slashes or back-slashes can be used in any combination.
If both next.report and next.chart system properties are specified, chart property is ignored.
For your installed designer, you can specify system properties inside nextreports.vmoptions file.
For example adding these lines at the end of the file
-Dnext.datasource=Demo -Dnext.report=Timesheetit will make your designer on start to auto-connect to Demo data source and to automatically open Timesheet report.
If your report is found inside /Test/Test1 folder path
-Dnext.datasource=Demo -Dnext.report=Timesheet -Dnext.path=/Test/Test1Path is converted to use specific file system separator, so you can enter it as you wish (/Test/Test1, Test/Test1, Test//Test1, \\Test\\Test1, Test\\Test1, \Test\Test1).
Thursday, February 16, 2012
NextReports: URL Custom Protocol & Version Dispatcher
When NextReports Server started its existence, users were able to upload reports and charts using server actions. This means:
After authentication, a data source is locally created (if not found) with following name convention:
After downloading, the report/chart is automatically opened and user can start to edit it. When user saves it, a confirmation is needed to publish it also on the server:
Server 'Edit' action will launch an url request like:
Specified version is used to open the needed designer which has the same version as the server avoiding following situations:
If the designer with that version is not installed, user is informed and he can download the correct version from the links shown with the message:
If you are a Linux user, you do not have a dispatcher to start your needed version of NextReports, but you can register your nextreports url protocol with following commands:
- a data source was already created
- user selects the report from current location
- user selects the existing data source
- user selects the images used (if any) from current location
- report/chart is uploaded in the current server path
- user selects server path
- user selects a server data source; if there isn't created, he can publish it with a single click
- when publish, used images are also published by default
- no browsing needed
After authentication, a data source is locally created (if not found) with following name convention:
<server_data_source_name>@<server_ip>Designer will auto-connect to this data source and the report/chart is downloaded. If a report/chart with the same name exists, user is notified:
After downloading, the report/chart is automatically opened and user can start to edit it. When user saves it, a confirmation is needed to publish it also on the server:
Server 'Edit' action will launch an url request like:
nextreports://<server>?user=<loggeduser>&ver=<serverversion>&ref=<serverpathtoentity>This can also be a simple method to pass to someone a report to edit. If that person can access the report (has the needed rights) you do not need to tell him the server, location and let him download the report, modify it and publish it back. You just give him an url.
Specified version is used to open the needed designer which has the same version as the server avoiding following situations:
- server version is older than designer version: you can download the report and edit it, but you cannot publish it to server
- server version is newer than designer version: you cannot download the report
If the designer with that version is not installed, user is informed and he can download the correct version from the links shown with the message:
If you are a Linux user, you do not have a dispatcher to start your needed version of NextReports, but you can register your nextreports url protocol with following commands:
gconftool-2 -t string -s /desktop/gnome/url-handlers/nextreports/command
'<installed_dir>/nextreports "%s"'
gconftool-2 -s /desktop/gnome/url-handlers/nextreports/needs_terminal false -t bool
gconftool-2 -s /desktop/gnome/url-handlers/nextreports/enabled true -t bool
Monday, February 06, 2012
NextReports: Variables, Functions & Expressions
NextReports has a simpler way of working with data, than other reporting solutions.
For example, inside iReport for JasperReports you can define a so-called variable just to use it in another fields. The problem with this approach is that the user must specify when this variable must be evaluated and when to be reset. (like page, report, group, column types). This is no easy task for non-business users who want to create some reports. This also can bring some invalid calculations if the user does not understand what he is doing.
NextReports does not have user-defined variables. In NextReports Variables are just application-defined like ROW, GROUP_ROW, PAGE_NO and so on.
Instead, users can create Expressions and Functions. Expressions can contain text, variables, parameters, columns and functions (from version 5.1). Functions can be any of SUM, AVERAGE, MIN, MAX, COUNT, COUNT DISTINCT and can be done on sql column or on expression.
For NextReports a field is evaluated if it is found inside layout. So, users do not need to ask themselves when to evaluate something. If you need an expression just to compute something without showing the result, you can make it hidden. But, you will always know when the expression is evaluated without asking yourself.
If we have two functions inside a group footer band
$F{SUM(HOURS)} : computes the sum of hours for a project (work, travel, administration, meeting)
$F{SUM(WORKHOURS)} : computes the sum of implementation hours
and we want also to see how much implementation represents in percentage, it is very easy to create an expression. From version 5.1 the user can select the functions found in the current band, in this case $F{SUM(HOURS)} and $F{SUM(WORKHOURS)}.
Report layout will show the defined expression:
Because functions are interpreted as double values the division will create a double. If you have an integer column $C_HOURS for example and you want to use div operations, be sure to convert it to double like $C_Hours.doubleValue(), otherwise the result will be an integer.
Result can be formatted with pattern property like in following exported pdf:
For example, inside iReport for JasperReports you can define a so-called variable just to use it in another fields. The problem with this approach is that the user must specify when this variable must be evaluated and when to be reset. (like page, report, group, column types). This is no easy task for non-business users who want to create some reports. This also can bring some invalid calculations if the user does not understand what he is doing.
NextReports does not have user-defined variables. In NextReports Variables are just application-defined like ROW, GROUP_ROW, PAGE_NO and so on.
Instead, users can create Expressions and Functions. Expressions can contain text, variables, parameters, columns and functions (from version 5.1). Functions can be any of SUM, AVERAGE, MIN, MAX, COUNT, COUNT DISTINCT and can be done on sql column or on expression.
For NextReports a field is evaluated if it is found inside layout. So, users do not need to ask themselves when to evaluate something. If you need an expression just to compute something without showing the result, you can make it hidden. But, you will always know when the expression is evaluated without asking yourself.
If we have two functions inside a group footer band
$F{SUM(HOURS)} : computes the sum of hours for a project (work, travel, administration, meeting)
$F{SUM(WORKHOURS)} : computes the sum of implementation hours
and we want also to see how much implementation represents in percentage, it is very easy to create an expression. From version 5.1 the user can select the functions found in the current band, in this case $F{SUM(HOURS)} and $F{SUM(WORKHOURS)}.
Report layout will show the defined expression:
Because functions are interpreted as double values the division will create a double. If you have an integer column $C_HOURS for example and you want to use div operations, be sure to convert it to double like $C_Hours.doubleValue(), otherwise the result will be an integer.
Result can be formatted with pattern property like in following exported pdf:
Wednesday, January 25, 2012
Page Header & Page Footer
A new feature will be included in NextReports 5.1 release: Page Header & Page Footer.
For document file exports like PDF and RTF, NextReports created page number in page header and current date in page footer. There was no way to define your header and footer data.
In 5.1 release, user will be able to define page header and page footer. Two new bands will be added to layout and they can contain any number of rows.
A new type of variable for page number can be inserted $V{PAGE_NO}. There is also the possibility to format page number as roman value:
For document file exports like PDF and RTF, NextReports created page number in page header and current date in page footer. There was no way to define your header and footer data.
In 5.1 release, user will be able to define page header and page footer. Two new bands will be added to layout and they can contain any number of rows.
A new type of variable for page number can be inserted $V{PAGE_NO}. There is also the possibility to format page number as roman value:
Page number variable can also be inserted inside expressions like:
resulting in the following output:
Tuesday, January 17, 2012
Keep Settings inside Storage
Every application needs configuration. If configuration must be accessible by users of the application, then you have to persist all your properties.
NextReports Server kept its properties inside a property file. Some problems with a file approach are:
Starting with 5.0 version, server has a new Settings section visible by administrators. All settings are now kept inside JCR storage and the problems with the file approach were removed:
Settings are arranged by categories : general, thread pool, application look, jasper, synchronizer. Information or attention about properties are offered through tool-tips. Only three properties require a restart of the server because you also have to modify something in your web server configuration files. These are:
Inside reports.xml file found here, there are two properties:
NextReports Server kept its properties inside a property file. Some problems with a file approach are:
- you must know where the file is located
- after any modification it may be needed to restart the application
- after any new version installation you need to copy your old property file
Starting with 5.0 version, server has a new Settings section visible by administrators. All settings are now kept inside JCR storage and the problems with the file approach were removed:
- we know where the place to modify application settings is
- after properties modification there is no need to restart the server (except for some that must be defined also in your web server configuration)
- when a new installation (update) is done, by specifying the old storage path, you have by default all your previously settings
Settings are arranged by categories : general, thread pool, application look, jasper, synchronizer. Information or attention about properties are offered through tool-tips. Only three properties require a restart of the server because you also have to modify something in your web server configuration files. These are:
- Base Url: if you change this you maybe have to talk to your network administrator
- Reports Home: “reports” folder must be in web server class path. For default Jetty server used, inside the installation folder you can find a start-nextserver.vmoptions file. In this file, the jetty class path is specified like this:
-Djetty.class.path=C:/Users/user.name/.nextserver/reports
- Reports Url: “reports” folder must be mapped to a web context. This is needed because all generated reports have to be accessed through http URL links that look like the following:
http://<ip>:<port>/reports/<report_file>For Jetty server used by default, there is a contexts folder where you installed the server.
Inside reports.xml file found here, there are two properties:
which tell us that reports found at “resourceBase” on the hard disk can be served by the web server’s “contextPath”./reports C:/Users/user.name/.nextserver/reports/
Monday, January 09, 2012
Know your date format
When it comes to date formatting, java makes use of SimpleDateFormat class:
"Date and time formats are specified by date and time pattern strings. Within date and time pattern strings, unquoted letters from
When it comes to Jackrabbit internal, dates as saved to a specific format like the following string:
Jackrabbit has a xs:dateTime function which has a formatted date as parameter. Obviously this date must have the same format used to store dates in Jackrabbit.
The problem with previously date format is the time zone, because there is no delimiter between the hours and the minutes, so the resulting string with SimpleDateFormat will be :
"Date and time formats are specified by date and time pattern strings. Within date and time pattern strings, unquoted letters from
'A' to 'Z' and from 'a' to
'z' are interpreted as pattern letters representing the
components of a date or time string.
Text can be quoted using single quotes (') to avoid
interpretation.
"''" represents a single quote.
All other characters are not interpreted; they're simply copied into the
output string during formatting or matched against the input string
during parsing."When it comes to Jackrabbit internal, dates as saved to a specific format like the following string:
2012-01-04T23:59:59.999+02:00Taking forward to create the pattern for such a String results in:
yyyy-MM-dd'T'HH:mm:ss.SSSZNote that we need T not to be a pattern letter, so we unquoted it. We may think everything it's ok. If we need just to show a nice formatted date, we may not even see the difference. But if we want to use date formatted strings for some business, for example to do a Jackrabbit search of entities between two dates, we will found out (not easily) that the pattern is wrong.
Jackrabbit has a xs:dateTime function which has a formatted date as parameter. Obviously this date must have the same format used to store dates in Jackrabbit.
The problem with previously date format is the time zone, because there is no delimiter between the hours and the minutes, so the resulting string with SimpleDateFormat will be :
2012-01-04T23:59:59.999+0200Because we cannot use a SimpleDateFormat string, we must use Jackrabbit api to format dates:
Calendar cal = Calendar.getInstance(); cal.setTime(date); String formattedDate = ValueFactoryImpl.getInstance().createValue(cal).getString();
Thursday, December 22, 2011
A new look
The new look for NextReports site is finally done. It is easier to give feedback and it is easier to see what NextReports is about through the images carousel at the top. Perhaps new images will be added later. But for now, the general information is at the right place.
Wednesday, December 21, 2011
How to visually represent your actions in web applications
Inside any web application, sometimes you have to deal with a set of actions. There are many differences between how you represent your actions inside a web application and a desktop application.
For example, if we have a table with a set of actions which can be done for every entity shown in a row. In desktop applications, we may have a set of buttons near the table. In web applications this in not the case. We can represent actions like links inside table columns:
But this approach will soon become obsolete if the number of actions can rise in the following versions. To be scalable, we should use a menu of actions. This will allow us to have more and more actions as the application business grows:
If you have only a couple of actions, you can be easily convinced to represent them as simple links. For example, the widget panel from NextReports:
But in time, after application grows, not only this will be unaesthetic, but it can also break the view (see how the necessary space is not enough and the row of actions falls down):
A menu of actions will help us again and this will be the adopted solution in following version:
Summarizing, this will help us :
Some other ways can be possible. Google, for example has a left-oriented menu, which ensures no collision with the scroll bar :
This can be done if you have a single actions link. But inside a table with such links on every row, this will be problematic because the menu will fall over the following links which must react on mouse-over events.
For example, if we have a table with a set of actions which can be done for every entity shown in a row. In desktop applications, we may have a set of buttons near the table. In web applications this in not the case. We can represent actions like links inside table columns:
But this approach will soon become obsolete if the number of actions can rise in the following versions. To be scalable, we should use a menu of actions. This will allow us to have more and more actions as the application business grows:
If you have only a couple of actions, you can be easily convinced to represent them as simple links. For example, the widget panel from NextReports:
But in time, after application grows, not only this will be unaesthetic, but it can also break the view (see how the necessary space is not enough and the row of actions falls down):
A menu of actions will help us again and this will be the adopted solution in following version:
Summarizing, this will help us :
- - not break the view
- - make the interface more intuitive
- - see what every action is about from start (not just on some tooltips)
- - scale easily the number of actions
Some other ways can be possible. Google, for example has a left-oriented menu, which ensures no collision with the scroll bar :
This can be done if you have a single actions link. But inside a table with such links on every row, this will be problematic because the menu will fall over the following links which must react on mouse-over events.
Tuesday, December 13, 2011
Spring 3 to the rescue
If you use Spring in your applications, you may need to pass some settings to a spring bean. Your settings can be defined in properties files, in system properties or inside an internal storage.
Let's say we want to use a property inside a spring bean like the following:
If propertyValue is defined inside a properties file we should define a propertyConfigurer bean:
If we want propertyValue to be overridden by system properties we can specify systemPropertiesModeName :
If our settings are defined inside a storage system (database, content repository), spring 3 will help us a lot with its new expression language SpEL. This allows for calling methods from a defined spring bean.
Lets say we have a settings bean like the following, were storageService can be any storage you need:
SettingBean will offer us the propertyValue we need :
With SpEL we can use the propertyValue in our bean like this:
If the bean, which needs some settings from a storage, is a bean from the spring api, then it's very easy to set the properties using SpEL . Otherwise we would have had to extend that class to inject our storage. For example a Spring ThreadPoolTaskExecutor can be defined like this :
Let's say we want to use a property inside a spring bean like the following:
<bean id="myBean" class="com.mypackage.MyClass">
<property name="myProperty">
<value>${propertyValue}</value>
</property>
</bean>
If propertyValue is defined inside a properties file we should define a propertyConfigurer bean:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:myfile.properties</value> </property> </bean>
If we want propertyValue to be overridden by system properties we can specify systemPropertiesModeName :
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:myfile.properties</value> </property> <property name="systemPropertiesModeName"> <value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value> </property> </bean>
If our settings are defined inside a storage system (database, content repository), spring 3 will help us a lot with its new expression language SpEL. This allows for calling methods from a defined spring bean.
Lets say we have a settings bean like the following, were storageService can be any storage you need:
<bean id="settings" class="com.mypackage.SettingsBean"> <property name="storageService" ref="storageService"></property> </bean>
SettingBean will offer us the propertyValue we need :
public class SettingsBean {
private StorageService storageService;
public Settings getSettings() {
return storageService.getSettings();
}
@Required
public void setStorageService(StorageService storageService) {
this.storageService = storageService;
}
// helper methods used in Spring with SpEL
public String getPropertyValue() {
Settings settings = getSettings();
return settings.getPropertyValue();
}
}
With SpEL we can use the propertyValue in our bean like this:
<bean id="myBean" class="com.mypackage.MyClass">
<property name="myProperty" value="#{settings.getPropertyValue()}"/>
</bean>
If the bean, which needs some settings from a storage, is a bean from the spring api, then it's very easy to set the properties using SpEL . Otherwise we would have had to extend that class to inject our storage. For example a Spring ThreadPoolTaskExecutor can be defined like this :
<bean id="schedulingTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="threadNamePrefix" value="Scheduler-"/>
<property name="corePoolSize" value="#{settings.getSchedulerCorePoolSize()}"/>
<property name="maxPoolSize" value="#{settings.getSchedulerMaxPoolSize()}"/>
<property name="queueCapacity" value="#{settings.getSchedulerQueueCapacity()}"/>
</bean>
Monday, November 21, 2011
NextReports Server - Dashboard Global Settings
Next version of NextReports Server will allow to select a 'Global Settings' action for dashboards.
This means we will be able to select some properties to all widgets from a dashboard. Two properties are always the same for any widgets: timeout and refresh time. Besides these two, if there are some common parameters used by all widgets, then those parameters can be also set .
Two parameters are considered the same if they have the same name, type, selection, manual source (if any), default source (if any), and some properties like hidden property, procedure parameter, preview value. Some properties may be different, like runtime name, description or mandatory setting.
This 'Global Settings' can be used for those dashboards which have a business of themselves, meaning that some common parameters for more widgets are present.
This means we will be able to select some properties to all widgets from a dashboard. Two properties are always the same for any widgets: timeout and refresh time. Besides these two, if there are some common parameters used by all widgets, then those parameters can be also set .
Two parameters are considered the same if they have the same name, type, selection, manual source (if any), default source (if any), and some properties like hidden property, procedure parameter, preview value. Some properties may be different, like runtime name, description or mandatory setting.
This 'Global Settings' can be used for those dashboards which have a business of themselves, meaning that some common parameters for more widgets are present.
Tuesday, November 01, 2011
NextReports Server : Drill Down Generalization
Previous versions of NextReports Server allowed to define a unitary drill down process. Charts could be drilled only to charts, tables could be drilled only to tables.
Version 4.2 makes a general approach to drill down. To link two widgets we have to specify :
In this example we have a chart with two levels of drill down, first level is a table and second level is a chart. This will be seen inside dashboard as passing through following widgets :
Version 4.2 makes a general approach to drill down. To link two widgets we have to specify :
- type of child widget (chart / table)
- link parameter
- column position whose value will be pass to the next report in the drill process (this will be shown only if the current widget in drill-down process is a table report)
In this example we have a chart with two levels of drill down, first level is a table and second level is a chart. This will be seen inside dashboard as passing through following widgets :
Friday, October 28, 2011
Tuesday, October 25, 2011
Wicket and AjaxFormComponentUpdatingBehavior
If you have a form component in wicket with some components and you want to change using ajax some things in that form before submit (when you click or edit on one of the components), then you have to use AjaxFormComponentUpdatingBehavior.
This is a behavior that updates the hosting FormComponent via ajax when an event it is attached to is triggered.
private AjaxFormComponentUpdatingBehavior createAjax( ) {
return new AjaxFormComponentUpdatingBehavior("onchange") {
@Override
protected void onUpdate(AjaxRequestTarget target) {
// do your task
}
};
}
The key is that your component must be a FormComponent, otherwise the event won't be triggered. Simple components like CheckBox, TextField, DropDownChoice are all FormComponents. But if you have a custom component create by yourself from more components or even one like DateField, DateTextField , you will have to add a behavior to every sub-component to make your form update through ajax.For example, a DateTimeField must respond if we change something inside its text field or if we change hours or minutes through its internal text fields, or AM/PM through its internal drop down choice. To access internal components from a wicket component we can use a get method with the markup-id as parameter if no methods are offered by that class. Inside DateTimeField we can override a newDateTextField method to add our behavior. But for the other elements we do not have similar methods, so we must look for the name of the markups in the html or java source code:
DateTimeField txtTime = new DateTimeField("txtTime", generalModel) {
@Override
protected DateTextField newDateTextField(String id, PropertyModel dateFieldModel) {
DateTextField f = super.newDateTextField(id, dateFieldModel);
f.add(createAjax());
return f;
}
};
// add ajax update behavior on hours and minutes textfields
txtTime.get("hours").add(createAjax());
txtTime.get("minutes").add(createAjax());
Friday, October 21, 2011
Java Enterprise in the Real World
Yesterday NextReports Team was a speaker at Oracle Java Developer Day in Bucharest.
Our presentation "Java Enterprise in the Real World" can be seen here:
Friday, October 07, 2011
NextReports Server - New Dashboard Navigation
A new dashboard navigation was created for NextReports Server. The previously list of dashboards was replaced with a simple table which is more robust allowing for a better management
To allow scalability for more-to-come actions on dashboards, the list of actions for every dashboard was replaced with a popup menu accessible from right-arrow icon:
Default or selected dashboard has a special background color to see more clear were we are.
Regarding widgets, new animations with different effects are used for bars, lines and areas.
Subscribe to:
Posts (Atom)













































