Axis2 is a Web Services, SOAP, WSDL engine which current release, 1.5.1, comes with many interesting features among which there is the Spring Framework support.
Axis2 documentation offers some good example of Spring integration, such as the How to create a Spring-based POJO Web Service guide or the Axis2 Integration with the Spring Framework, but there's no mention of the use of Spring annotations.
Spring annotations work like a charm in Axis2 if you follow exactly the steps of the previous guide, but my tip is to build your service structure without using annotations in a first stage (unless you are already skilled in this field), then incrementally simplify your code adding Spring annotations.
Here is an example of a simplified application-config.xml when using Spring annotations with Axis:
<beans>
Now all your beans inside the packages 'service' and 'bean' will be deployed on Spring application context start or refresh. To annotate a class as Spring bean just use the @Component annotation on your class.
If you want to initialize your service on deployment time, add the @PostConstruct annotation on your initialization method. If your bean needs to access another bean, just use the @Autowired annotation on your class field.
Here a simple example:
@Component
public class MyService{
Don't forget to add the SpringBeanName parameter in your services.xml:
<parameter name="SpringBeanName" >myService</parameter>
Annotations simplify your life reducing time spent configuring every bean you need in your application and using them in Axis allows you to build complex WebServices with less code.
Have fun.
One of the most important problem in the creation of Dynamical Pdf is the validation of data inserted by user. We know that LiveCycle Designer support us in validating with the following events:
prePrint: dispatched when the user starts to Print the document
preSave: dispatched when the user starts to Save the Document
preSubmit: dispatched when the user starts to Submit the Document
preExecute: dispatched when the user starts a data connection inside the Document
and we have also the possibility to change the status of a field to 'Required' (the default status of a designer object is 'Optional').
But if we put a control inside one of the events above, we can't stop the user action (view the Adobe Documentation for more!) if validation fails. For this reason we have the possibility to add to our XFA Application (version 2.5) an object called Validation Object.
Unfortunately we can't add it into the Design Model but we have to insert this object into the XML Source of our Application, so we have to find the following tags:
<config xmlns="http://www.xfa.org/schema/xci/1.0/">
<agent name="designer">
...
</agent>
<present>
<!-- [0..n] -->
...
and put the <validate> element into the <present> element:
<config xmlns="http://www.xfa.org/schema/xci/1.0/">
<agent name="designer">
...
</agent>
<present>
<!-- [0..n] -->
<validate>prePrint preSubmit </validate>
...
When you are done making the change, click on the Design View tab and make sure you say “yes” to have your changes applied.
With the release of XFA 2.8 and Acrobat/Reader 9.0, the <validate> element is now located under the <acrobat> element in the Source XML:
<config>
...
<acrobat>
...
<validate>prePrint </validate>
...
</acrobat>
...
</config>
With this Validation Object we can stop only Print, Submit and Execute actions. The Save action can not be stopped by the Validation Object (I think because an user would like to save a Pdf without filling all the fields and complete them in a second time).
Here are two examples: the first does not have the validation object in XML Source (here) while the second has this object built for the prePrint and preSubmit events (here).
The agenda will see two different sessions presented by SpringSource and Comtaste:
Session 1 (english) - Spring 3.0 and the new REST support, Speaker: Rossen Stoyanchev (SpringSource)
One of the major new themes of Spring 3.0 is the support for REST in Spring MVC. This talk will investigate these features from the perspective of a web application developer and discuss them in the context of JAX-RS, the Java Standard for RESTfulWeb Services. If you're familiar with JAX-RS you can relate your knowledge to Spring MVC. If you're an existing Spring MVC user can learn about major developments in the areas of data binding, validation, and type conversion as well as how Spring MVC compares to JAX-RS, a topic that's likely to come up in your organization.
Session 2 (in lingua italiana) - Integrare Spring con Flex 3, Speaker: Marco Casario (Comtaste)
SpringSource announced Spring BlazeDS Integration, a new open source project to provide tight integration between Spring and Adobe BlazeDS, Adobe’s open source server-based Java remoting and Web messaging technology.
This open source project will make it easy for Java and Spring developers to create enterprise-class rich Internet applications (RIAs) using Adobe Flex software, a cornerstone of the Adobe Flash Platform, and Spring, the de facto standard for enterprise Java.
According to the Adobe's definition, LiveCycle Data Services ES2 module is a scalable and optimized framework that abstracts the complexity of creating easy-to-use, personalized, and interactive applications. It includes a rich set of features that streamline the development, integration, and deployment of rich Internet applications (RIAs).
- Support for model-driven development of Flash applications, which make application development better, faster, and easier
- Secure and scalable connectivity across the DMZ with the Edge Server.
- New capabilities for developers to control and measure the quality of service of enterprise applications.
Last week I've presented an eSeminar via Connect about Flash Catalyst.
Flash Catalyst will change the way designers and developers will work together to create Rich Interactive applications.
In this eSeminar you'll learn key features of the latest version of Flash Catalyst as well as the technologies behind the tool such as the FXG format and the Flex SDK 4.
You'll discover how to work with products such as Photoshop and Illustrator to create the look and feel and the user experience of a RIA, while automatically generating the necessary code in the background.
It’s also possible to manual control panels on a container, like tile or cascade all panels. To do this we need to use the DashLayoutManager, a multiTon class that maps containers trough container id’s.
To use the DashLayoutManager of a specific container you have to reference to it trough the id:
Manual control panels ( minimize, maximize, restore )
Now let’s see how to control every panel programmatically, to maximize, minimize and restore its. To do this we have to use the DashPanelEvent class. So we don’t have any api to control, but we must use events.
First define the event:
Maximize:
var minimizeEvent:DashPanelEvent = newDashPanelEvent( DashPanelEvent.MINIMIZE, myPanel );
Minimize:
var maximizeEvent:DashPanelEvent = newDashPanelEvent( DashPanelEvent.MAXIMIZE, myPanel );
Restore:
var restoreEvent:DashPanelEvent = newDashPanelEvent( DashPanelEvent.RESTORE, myPanel );
<mx:Label text="Minimize, maximize and restore me!" />
</mx:VBox>
</components:DashPanel>
</components:DashPanelContainer>
</mx:Application>
Listen containers change
The Pantaste dash container ( DashPanelContainer class ), propagate an event to inform you that something happened. Information that you can obtain is about panels and this is the type:
Added to the container
Removed from the container
Maximized
Minimized
Restored
Moved
All we have to do is listening on the “pantasteChanged” event defined by the DashPanelContainerEvent class. This class will provide to us the changedTypeEvent, the panel caused the change and the container were is placed.
In Adobe Flash Catalyst the states concept is really important but a little bit hard to understand immediately, let’s try to catch the sense of it together.
With this new Adobe tool for designer, working on Rich Interactive Applications will be a lot easier and the cooperation with developers will be as close as it has never been before. The software interface is not the final one, the version available now is a beta, but still we can use many functionalities. Flash Catalyst is different from other Adobe design tools, maybe who use Flash will be familiar with the general approach.
The states in Flash Catalyst are referred to Pages and to elements inside a page and they represent different views of the application. We navigate between different states but in the same way they can be referred also to a component, for instance a button has state such as Up, Over, Down, and Disabled.
In the interface the right side is dedicated to tools and panels as Libraries, Layers and Properties, up to the stage there are indications about pages, components and states.
I created a very simple application as an example that has two pages Start and End, where you can click on a button “click here” to switch to different states/pages.
In Flash Catalyst interface you can find the states also on the left side of the Timeline. Here you find the States transitions panel, remember that in this tools transitions are taken as separate parts of the entire navigation, this means that you must put properties thinking of a "round trip".
When you double click on components their states are displayed on the same part where the pages/elements are and this can be a little bit tricky, maybe the component state should be represented in a different way, graphically speaking. Anyway as in Flash, we can always go back to the previous element using the menu up on the left side of the stage.
We can say that the states represent the condition/status of pages and components, more generally the concept indicate what an element is doing before and when users interact with it.
When you want to assign a tooltip to a UIComponent, you simply set the variable "tooltip" to a custom String. You don't have many chances to customize it, except from the string itself. On the contrary you can use the ToolTipManager to customize tooltips for your entire application; this class has properties such as hideDelay/showDelay, hideEffect/showEffect and toolTipClass, with which you can change the UI for all your tooltips; the ToolTipManager lets you create and destroy tooltips progamatically also with the two methods createToolTip and destroyToolTip.
In this post I want to show you how to customize a tooltip in a specified view only, without interfere with the rest of your application. You can use two strategies:
- manage the popup by yourself, creating/destroying it and let it interact with the mouse events
- use the tooltip manager
We are going to explore the latter.
The UIComponent class dispatches some tooltip related events:
- toolTipCreate Dispatched by the component when it is time to create a ToolTip. UIComponent
- toolTipEnd Dispatched by the component when its ToolTip has been hidden and will be discarded soon. UIComponent
- toolTipHide Dispatched by the component when its ToolTip is about to be hidden. UIComponent
- toolTipShow Dispatched by the component when its ToolTip is about to be shown. UIComponent
- toolTipShown Dispatched by the component when its ToolTip has been shown. UIComponent
- toolTipStart Dispatched by a component whose toolTip property is set, as soon as the user moves the mouse over it.
The first one is dispatched before the effective creation of the tooltip. This event has a writable property called toolTip that can be used to specify a custom class to be created in place of the standard one (that is the class specified in ToolTipManager.toolTipClass).
You have to implements the IToolTip interface that has two properties:
- screen : Rectangle
- text : String
You get the screen property extending the UIComponent class, so you have to implement only a setter/getter for text.
Actually using this property is not necessary, let's see an example:
and the tooltip class
package
{
import mx.containers.Canvas;
import mx.controls.Label;
import mx.core.IToolTip;
public class CustomToolTip extends Canvas implements IToolTip
{
private var helloWorld:Label;
public function CustomToolTip()
{
setStyle("backgroundColor", 0xffffff);
}
override protected function createChildren():void
{
if(!helloWorld)
{
helloWorld = new Label();
helloWorld.text = "Hello world";
addChild(helloWorld);
}
}
public function get text():String
{
return null;
}
public function set text(value:String):void
{
}
}
}
As you can see we are not using the text property of the ITooltip interface, but it's important to note that we have to set tooltip to something different than null or empty string otherwise the TooltipManager will not be activated.
In my last post I showed you how to install Weborb .Net connector, now I'd like to build a little example using this technology: we will create an object from the server side and send it to the client. It's a very simple example but I think it is the better way to understand the most important functionality of Weborb.
For this example we will use IIS 6.0 and .NET 2.0 for the server side, while for the client we use a simple Flex 3 application.
The server side classes that we build for this project are:
Person.vb
DBManage.vb
DBDelegate.vb
Person class is made by three attributes: idPerson (numeric), name (String) and surname (String). This class is the VO (value object) that we want to manage both in the server and in the client side, so we have to build an ActionScript Class which references the service side class from the client.
The DBManage class has the methods to manage the persistence of data and it will be the remote object called by our flex client, through a Remote Object.
Here is the code of the class:
<Serializable()> Public Class Person
Public idPerson As Integer
Public name As String
Public surname As String
End Class
Public Class DBManage
Function tryPerson() As Person
Dim p As Person
p = New Person()
p.idPerson = 1
p.name = "Mario"
p.surname = "Rossi"
Return p
End Function
End Class
Public Class DBDelegate
Public Function tryPersonWebOrb() As Person
Dim db As DBManage
db = New DBManage()
Return db.tryPerson()
End Function
End Class
with these classes we can create a small DLL file, called weborbTrial.dll.
Before building the client we have to configure the Virtual Directory in IIS in which we will install the Weborb classes and also the client application. So we have to create a virtual directory in our IIS with permission of write and read. For information on how to install Weborb in this Directory you can see my last post.
After the installation we can carry on building the client application. First of all we have to copy into the subdirectory “bin” of our Weborb directory the weborbTrial.dll file. After we can start to create a new Flex Project. Open your Flex Builder and create a new Project. In the first screen insert the name of the Project, select the Flex Checkbox and choose the ASP.NET server configuration and click Next.
In the second screen in the web application Run field insert the URL of our virtual directory and the field below insert the locale directory of the application; then in the last field insert the bin-debug directory of the application. Click finish and the project is created.
Before starting to write the client application, open the properties of our project and in the compiler section add this line: -services [ourDirectory]\WEB-INF\services-config.xml.
First of all we have to create the VO ActionScript class, corresponding to Person.java:
package vo
{
import mx.collections.ArrayCollection;
[Bindable]
[RemoteClass(alias="weborbTrial.Person")]
public class Person
{
public function Person(){}
public var idPerson:Number;
public var name:String;
public var surname:String;
}
}
Now we can create our client. For this example we use a simple button for call the method of the remote object defined in the Application. If the connection with the server works in the right way, we should see in the Panel the object created by the server class.
<?xml version="1.0" encoding="utf-8"?>
It is important to focus our attention on the definition of the remote object. This object is connecting to server by a default destination and channel defined in the remote-config.xml file, but it is possible to create our destination and channel and we can also define the source in the destination's property in the remote-config.xml file.
It's no hard to see that the our client application could work well also with a different server backend, with only minor changes to the configuration parameters.
The flex class ActionScript has a very useful method, filterFunction, that allows to pass as a parameter another function, to be applied as a filter for the data. The filter is effectively applied only after we invoke refresh() on the ArrayCollection. The result is well known: the collection will only show those items that match the filter function, while all elements, filtered or not, can be accessed from the list or source properties of the collection.
Suppose we have a collection of objects with many properties, and we want to filter on a few properties at a time, not always the same. For example we could have the class AirplaneReservation, with a subset of the properties similar to:
public var firstName:String;
public var lastName:String;
public var gender:Number;
public var reservationDate:Date;
public var destination:String;
public var departure:String;
public var seat:String;
public var menuType:Number;
and we want to filter on whatever combination of properties, using a Form component to display them all to the user.
We could create as many filter functions as our use cases, which can be a lot to handle, or we could use different approaches, tweaking the flex framework to our needs. Rotundu made a post about multiple field filtering, that can be found here, by extending the ActionScript class and adding an array of filter functions, to be eventually applied as a single one.
The approach illustrated here is similar, in that it uses many filter functions, but different in that it does not extend ArrayCollection and associates a filter function with a field of our collection object.
We can create the Form component, with input fields for every filter (TextInput, NumericStepper and so on) and, on the change event, call a single function:
<mx:TextInput id="firstName" change="applyFilter('firstName', firstName.text)" />
In most of the cases we can use a single applyFilter() function, that receives in input the name of the property to be filtered and its value. This function will then create an ad hoc filter function and apply it to our collection. We will make use of a Dictionary to associate a field with its filter function:
private function applyFilter(field:String, value:*):void {
var f:Function;
if ((value == null) || (value.length == 0))
f = null;
else {
f = function(item:Object):Boolean {
if ((item == null) || !item.hasOwnProperty(field))
return false;
if (item[field] is Boolean)
return Boolean(item[field]) == value;
if (item[field] is Number)
return Number(item[field]) == value;
if (item[field] is String)
return String(item[field]).localeCompare(value) == 0;
if (item[field] is Date)
return Date(item[field]).time == Date(value).time;
// any other object:
return item[field] == value;
};
}
This will create a filter function for the field received in input, store it in the Dictionary so that it will be available for multipleFilter():
private function multipleFilter(item:Object):Boolean {
for (var key:Object in _filterFunctions) {
var f:Function = _filterFunctions[key];
if ((f != null) && !f(item))
return false;
}
return true;
}
We can now filter as many fields as we want, at the same time, using these two functions only. The applyFilter function can easily be adapted to custom business objects, by means of object polymorphism and interfaces (Java’s Comparable is a good example).