Main

Java Archives

August 13, 2007

JavaFX compiler source code released

Source code for the OpenJavaFX Compiler is now available. The compiler enables JavaFX Script code to be compiled into Java code. "What you really want to do is compile an entire program, get it all into Java to begin with and it compiles much faster," said Chet Haase, Sun Java chief client architect (via Javaworld)

September 28, 2007

Automating ActionScript 3 classes generation from Java Beans in a LiveCycle Data Services context

In a Flex application that uses LiveCycle Data Services or the previous Flex Data Services to manage data from a remote server there is the requirement that Flex domain model classes have to match Java domain model, in structure, properties and types. Usually it means that for each Java class that is supposed to be configured as a remote alias one should write down an ActionScript class with the same properties, just as described in the Adobe livedocs at Livedocs
The documentation provides a mapping for ActionScript data types and Java data types and specifies that Java classes are dealt with through the Java Beans specification, that can be downloaded here: Javabeans

The Java class is serialized and all of its public properties and the ones with getter and setter methods are serialized. All other properties are not, including the ones without a getter. There is one thing related to the Java beans that worths a bit of attention, and it is bean attribute names that start with a lower case character followed by a upper case character: their getter and setter methods will have get/set followed by at least two upper case characters, for example "aFoo" will have "getAFoo" and "setAFoo". When the Java introspection mechanism, described in the above specification, finds these kind of properties, it will infer that the property is called "AFoo". That implies that inside the ActionScript class that matches the Java bean the property has to be called "AFoo", otherwise it will not be recognized. This usually translates on the flash log in a "ReferenceError: Error #1056: Cannot create property AFoo on [...]".

Consider the case where all of the properties of a class are declared in Java with a lower case followed by an upper case, one could easily convert into an ActionScript class that follows the same naming convention and, at runtime, there will be an empty object, with the right type but no contents; the ReferenceErrors in the flashlog will point out the problem and the solution, in this case, is to call ActionScript properties starting with two upper case characters: "AFoo".

Iin an enterprise application there can be many Java bean classes to be converted to ActionScript counterparts, a simpler way of solving this and possibly other problems related to Java to ActionScript conversion would be the use of an automatic tool. At the time of writing this blog post I personally did not find a tool that performs the conversion, a tool that can be easily integrated into an IDE, like Eclipse, or used as an Ant task, thus I'm considering writing one myself. The backend of this tool would use java.beans.Introspector to get the java.beans.PropertyDescriptor for each property of the bean, map the Java types to the ActionScript ones and generate the required imports. I'll keep the blog updated with progress on the tool, as well as interesting parts of the source code.

February 9, 2008

The new BlazeDS JMSAdapter allows to pass connection-level credentials to JMS

I want to point out for the readers of this blog (mainly Java, Flex and Livecycle developers) an article I published on my personal blog :
Passing connection-level credentials to the JMSAdapter of BlazeDS
One of the limit if the Messaging Services of Livecycle Data Services is the inability to define a username and password in the configuration file to pass them to the JMS.
I discovered that in BlazeDS there is a new JMSAdapter that allows you to set the connection-level credentials passing the username and password.
The new connection-credentials XML node sets the the username and password used while creating the JMS connection.As the documentation said, use only if JMS connection level authentication is being used :



...

Topic
javax.jms.TextMessage
jms/flex/TopicConnectionFactory

jms/topic/flex/simpletopic

NON_PERSISTENT
DEFAULT_PRIORITY
"true"
AUTO_ACKNOWLEDGE

1

For many developers this new features supported by the JMSAdapter could be very appreciated and could solve problems in many different scenarios where the authentication is required in JMS.

Read the full Passing connection-level credentials to the JMSAdapter of BlazeDS article.

March 27, 2008

Comtaste launches new Adobe Flex 3 and Adobe AIR training courses in New York City, London and Milan

Comtaste has just launched its new training courses on Adobe Flex3 and AIR for late spring-early summer 2008.

First courses to be scheduled are:

"Flex 3 and Flex Builder 3: Developing Rich Internet Applications with the new Flex 3 SDKs" (Milan and London 26-29 May, NYC-Manhattan 2-5 June)

"Developing desktop applications with Adobe AIR, Ajax and Flex" (Milan 14-17 April, NYC-Manhattan 9-12 June, London 23-26 June).

Our educational proposal, designed and set up by Flex expert Marco Casario, is mainly the result of our strong experience in real world enterprise projects.

Our courses reflect our clients' training needs that our consultants have encountered in the day by day running of enterprise-class projects, where Flex and AIR are also connected to backend applications under robust and rigid JEE architectures or other server side technologies.

Training programs and other details on company's website www.comtaste.com/en/training.htm

September 4, 2008

How to build your own geographical based search engine

Our goal: provide to our website users the possibility to find all items (cinemas, restaurants, hotels...) within a defined range of their current locations, sorting results upon distance from them.

What we need: a database containing the latitude and longitude of the items, an interface to allow users to enter their current location (it can be a raw form or an interactive map, as you prefer), various software depending on your next choice.

Now we have at least 2 ways to reach our goal:

- Sql query:
it's the easier method, we already have data in our DB, we need only to execute a relatively simple query with a sub-query. Let's see an example in detail:

SELECT item_name, SQRT(POW((@user_lat - lat) * 111319.5 * COS(RADIANS(@user_lng)),2) + POW((@user_lng - lng)*110946.3,2)) as distance
from ( select item_name, lat, lng
     from items
     where lat >= (@user_lat - @range_degrees/2)
     and lat <= (@user_lat + @range_degrees/2)
     and lng >= (@user_lng - @range_degrees/2)
     and lng <= (@user_lng + @range_degrees/2)
) as boundary
WHERE distance < @range_meters
ORDER by distance;

Using this formula distance is given in meters, and you need to convert user choosen range in meters and degrees. Values 111319.5 and 110946.3 are based on this information.

Patrick O'Leary in his article on GIS based search use an Euclidian formula,I don't know if it's similar or it returns distance in miles etc., I haven't tried it so pay attention when you use his or my formula, do some testing!

- Lucene:
Apache Lucene is a high-performance, full-featured text search engine library written entirely in Java.
Local Lucene is an extension of Lucene providing an implementation of geographical searching. Another similar implementation is GeoLucene but it's still an earlier alpha and his developer is unable to work on this project. Both these software are faster on geographic queries than the unmodified Lucene and for sure faster than Zend_Search_Lucene too.
If you can use Java I recommend to choose Local Lucene, in his whitepaper pjaol shows a comparison beetween Mysql, Lucene and LocalLucene. Instead if you want to use the search capabilities of Lucene in PHP, you can use Solr and, in example, a client like this SolPHP or obtain a JSON response from the server. In this case you can use LocalSolr that is a porting of the LocalLucene library onto the Solr search server.
On GISSearch you can find all information needed to easily build your fast, scalable and reliable geographical search engine.

I hope it will be helpful to you and to your users.

January 17, 2009

How to enable communication between AIR and Skype through Merapi

Merapi is an interesting project that wants to create a bridge between Air and Java on the desktop, something that already exists between Flex and Java on the web thanks to BlazeDS/LCDS and other similar projects.
It's made up of an actionscript part and a java part, together they build a messaging bridge based on AMF so that you can send messages from java to Air and viceversa.
Merapi is currently in a private alpha state, though a first beta has just been released on their site. If you want to get involved and download the package you have to create an account on http://www.merapiproject.net/ and wait for their approval (usually doesn't take longer than a few days).
The APIs are very simple, you can see an example of their usage on: http://www.merapiproject.net/index.php?option=com_content&view=article&id=47&Itemid=64&limitstart=3.

The idea is simple and is based on sending messages from one endpoint to the other. Sending a message from ActionScript:

var message : Message = new Message();
message.data = "Hello from Merapi Flex.";
message.type = "Reply";
Bridge.instance.sendMessage( message );


Sending a message from Java:

Bridge bridge = Bridge.getInstance();
Message message = new Message();
message.setData("Hello from Merapi Java.");
bridge.sendMessage(message);

Receiving a message in Flex:

<merapi:BridgeInstance
id="bridge" result="handleResult(event)" />
<mx:Script>
<![CDATA[
private function handleResult( event : ResultEvent ) : void
{
var message : IMessage = event.result as IMessage;

Receiving a message in Java:

Bridge.getInstance().registerMessageHandler("Reply", messageHandlerInstance );
public void handleMessage( IMessage message )
{
System.out.println( message.getData() );
}

There is a forum: http://www.merapiproject.net/index.php?option=com_fireboard and some interesting video of application examples: http://www.merapiproject.net/index.php?option=com_content&view=article&id=51&Itemid=84.

I decided to start playing with Merapi creating a AIR client for the Skype chat; first of all I started searching for a Java implementation of the Skype communication API. I found this project "http://skype.sourceforge.jp/index.php?Skype%20API%20For%20Java%20(English)", officially supported by Skype https://developer.skype.com/wiki/Java_API
It's a well written and powerful library so it was very easy to understand.

In my application I used two message types:
- "skype" - for generic API commands
- "skypeChat" - for chat messages

then I created two specific payloads for the Merapi message dependent on its type:

SkypeCommand in ActionScript

package
{
import mx.collections.ArrayCollection;

[RemoteClass(alias="SkypeCommand")]
public class SkypeCommand
{
public static const GET_VERSION:String = "getVersion";
public static const GET_FRIENDS:String = "getFriends";

public var name:String;
public var data:Object;
}
}

SkypeCommand in Java

public class SkypeCommand {
public static final String GET_VERSION = "getVersion";
public static final String GET_FRIENDS = "getFriends";

private String name;
private Object data;

public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

SkypeChatMessage in ActionScript:

package
{
[RemoteClass(alias="SkypeChatMessage")]
public class SkypeChatMessage
{
public var skypeId:String;
public var message:String;
}
}

SkypeChatMessage in Java:

public class SkypeChatMessage {
private String skypeId;
private String message;

public String getSkypeId() {
return skypeId;
}
public void setSkypeId(String skypeId) {
this.skypeId = skypeId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

As you can see, class mapping works exactly the same way it works in BlazeDS.
You have to initialize the bridge on ActionScript:

<merapi:BridgeInstance id="bridge"
  result="bridgeMessageHandler()" />

and on Java you have to register message type handlers:

Bridge.getInstance().registerMessageHandler( "skype", new SkypeMessageHandler() );
Bridge.getInstance().registerMessageHandler( "skypeChat", new SkypeMessageHandler() );

and a Chat message listener

Skype.addChatMessageListener(new SkypeChatListener());

On AIR creationComplete I send two skype commands to get version and friends list:

private function init():void {
var versionCmd:SkypeCommand = new SkypeCommand();
versionCmd.name = SkypeCommand.GET_VERSION;

var listCmd:SkypeCommand = new SkypeCommand();
listCmd.name = SkypeCommand.GET_FRIENDS;

bridge.send("skype", versionCmd);
bridge.send("skype", listCmd);
}

On Java side, in the SkypeMessageHandler, for "skype" type:

SkypeCommand cmd = (SkypeCommand)((Message) message).getData();
Message response = new Message();
response.setType("skype");
SkypeCommand respCmd = new SkypeCommand();

String commandName = cmd.getName();

if(commandName.equals(SkypeCommand.GET_VERSION)) {
respCmd.setName(SkypeCommand.GET_VERSION);
respCmd.setData(Skype.getVersion());
} else if(commandName.equals(SkypeCommand.GET_FRIENDS)) {
ContactList list = Skype.getContactList();
Friend[] friends = list.getAllFriends();
String[] friendIds = new String[friends.length];

for (int i = 0; i < friends.length; i++) {
friendIds[i] = friends[i].getId();
}

respCmd.setName(SkypeCommand.GET_FRIENDS);
respCmd.setData(friendIds);

}

response.setData(respCmd);

Bridge.getInstance().sendMessage(response);

I resend back a SkypeCommand of the same type so that in the AIR app I can recognize the response:

private function bridgeMessageHandler():void
{
if(bridge.lastMessage.type == "skype")
switch(bridge.lastMessage.data.name) {
case SkypeCommand.GET_VERSION:
versionLabel.text = "Skype version: "+bridge.lastMessage.data.data as String;
break;
case SkypeCommand.GET_FRIENDS:
var friendsArray:Array = bridge.lastMessage.data.data as Array;
friendsList.dataProvider = friendsArray;
break;
}

For chat messages sent by AIR, I only forward them to the Skype API:

SkypeChatMessage chatMsg = (SkypeChatMessage)((Message) message).getData();
Chat c = Skype.chat(chatMsg.getSkypeId());
c.send(chatMsg.getMessage());

For chat messages sent by a friend, in the SkypeChatListener I forward the message to the bridge:

public void chatMessageReceived(ChatMessage arg0) throws SkypeException {
SkypeClient.hideSkypeWindow();
Message response = new Message();
response.setType("skypeChat");

SkypeChatMessage msg = new SkypeChatMessage();
msg.setSkypeId(arg0.getSenderId());
msg.setMessage(arg0.getContent());

response.setData(msg);

try{
Bridge.getInstance().sendMessage(response);
} catch(Exception e) {
e.printStackTrace();
}
}

You have to start the java application first, then the AIR, otherwise you will get IOErrors on the bridge. And here is the AIR app in action:
AIRSkype.png

This is the AIR installer: Download file
and the runnable jar file: Download file

Waiting for the next version of AIR, that will let you call executable files, Merapi could be a good starting point to make your apps interoperate with AIR; there is a java implementation for nearly everything you will need, thus Merapi exponentially expands the AIR potential on desktop.

February 9, 2009

Securing your Solr server on Tomcat

Apache Solr does not have any security feature by its own, either at the document level or the communication level.
The simplest solution is the use of a firewall but this is not possible if you are using Solr as a Tomcat application. In this case you could want to require authentication only when accessing the entire Solr application or only some part of it, such as admin or update.

Let's see how to implement a basic authentication mechanism. We have to modify only two files: conf/tomcat-users.xml, inside the main folder of your Tomcat server, and WEB-INF/web.xml in your solr war file.

In tomcat-users.xml add:

<role rolename="yourRole"/>
<user username="yourUser" password="yourPassword" roles="yourRole"/>

In web.xml you have to specify the security restriction for your application:

  <security-constraint>
    <web-resource-collection>
      <web-resource-name> 
        Solr authenticated application
      </web-resource-name>
      <url-pattern>/*</url-pattern>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
      <role-name>yourRole</role-name>
    </auth-constraint>
  </security-constraint>
   <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>Basic Authentication</realm-name>
  </login-config>
  <security-role>
    <description>My role</description>
    <role-name>yourRole</role-name>
  </security-role>

In this example we protect the entire Solr application, but you can change the url-pattern node to protect only a part of Solr.

You could need to modify your client or your crawler to send the authentication header.
For example if you use PHP you have to send authentication parameters:

file_get_contents('http://yourUser:yourPassword@www.yourdomain.com:8080/solr/select/?q='.$query);

February 27, 2009

Spring official courses in Italy: Comtaste offers discount code

Comtaste , Spring Official Training Partner , is glad to offer his readers a discount code to use for the upcoming course in Rome: Core Spring.

Use the following promotional code when registering: ROMA10

springsource-transparent-web.png
Core Spring is our four-day flagship Spring training course covering:

* The Spring Lightweight Container Architecture, including Inversion of Control
* Agile, domain-driven design techniques with Spring
* Effective JDBC and Hibernate data access
* Declarative transaction management
* Pragmatic AOP
* Unit testing in isolation
* Rapid system integration testing
* Introduction to "Spring Web"
* Remoting
* Web Services
* Spring Security
* JMS
* JMX

In this course, students build a Spring-powered JEE application that demonstrates the Spring Framework in an intensely productive, hands-on setting. Completion of this course entitles each student to waive the registration fee for the SpringSource Certified Professional Examination.

If you want to register you can use the following promotional code when registering to the Core Spring: ROMA10

Continue reading "Spring official courses in Italy: Comtaste offers discount code" »

March 13, 2009

Messaging from Java to Flex without JMS

With BlazeDS/LCDS you can send messages to and receive messages from a server side destination thanks to Messaging Services and their client-side API.

In your messaging configuration you can use a ActionScript Adapter:
<adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />

or a JMS Adapter:
<adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/>

that integrates Flex messaging with Java Message Service destinations.

If you don't have JMS or you don't want to use it in your web application you can send messages from Java to Flex in a very simple way.

First of all you should enable the ActionScript adapter and create your destination without additional parameters:


<destination id="actionscriptMessaging">

</destination>

In your Flex application you have your Consumer:


<mx:Consumer id="consumer"
destination="actionscriptMessaging"
message="messageHandler(event);"
fault="faultHandler(event);"/>

that is subscribed to the previous destination so that it can receive messages:


consumer.subscribe();

On the Java side, inside the context of the web application in which LCDS/BlazeDS runs, you can use these lines of codes to send messages to your Flex Consumer:


AsyncMessage msg = new AsyncMessage();
msg.setTimestamp(new Date().getTime());

msg.setClientId("JavaMessageProducer");
msg.setMessageId("JavaMessageId");

//destination configured in messaging-config.xml
msg.setDestination("actionscriptMessaging");

msg.setBody("Message from Java!");

//you can set custom message headers
msg.setHeader("headerParam1", "value1");
msg.setHeader("headerParam2", "value2");

//send message to destination
MessageBroker.getMessageBroker(null).routeMessageToService(msg, null);

This is a solution suitable for uni-directional messaging, if you want to use a bi-directional messaging system it's convenient to use JMS.

February 4, 2010

Axis2, Spring and Annotations

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>

  <bean id="applicationContext" class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
  <context:component-scan base-package="service"/>
  <context:component-scan base-package="bean"/>
</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{

@Autowired
private MyBean bean;

@PostConstruct
protected void init() {
//init operations
}

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.

March 4, 2010

Spring BlazeDS Integration

Hi to all, in this post I will explain how simple it is to configure an application that requires

- Front-end in Flex
- Back-end in Spring

with the Spring BlazeDS Integration.

To illustrate the integration support of Spring BlazeDS, I've built a sample application with:

Flex 4
Spring 2.5.6
Tomcat 6
MySql 5
Java 6

Data representation

We just represent information about Employee set. Specifically we represent the following fields:

- name
- surname
- address
- email
- category, to simplify we have supposed only 4 category : analyst – consultant – junior - manager

Architecture layers

Front-end

- Flex application that shows data on Employee set.

Back-end, ORM framework JPA

- Spring bean : EmployeeService
- DAO : EmployeeDAO
- Data : Employee

How to configurate Spring BlazeDS Integration

First of all we have to configure the MessageBroker component, core of the Spring BlazeDS Integration, because HTTP messages from the Flex client will be routed through the Spring DispatcherServlet to Spring managed MessageBroker.
Once this step is complete, we will be sure that remoting calls from the flex client reach their destination, so all we have to do is allow Spring to export its beans. To ensure this we must configure the BlazeDS Remoting service and all the necessary remote destinations.

MessageBroker's configuration

We have to configure MessageBroker into app-context.xml file

Add Flex namespace

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:flex="http://www.springframework.org/schema/flex"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/flex
http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">

...
<beans>

Spring provide an XML config namespace for MessageBroker's configuration inside app-context. To use the namespace support we must add the schema location into the Spring XML configuration files. This makes the Spring BlazeDS Integration configuration tags available under the flex namespace into ours configuration files. We have to be sure to refer to the spring-flex-1.0.xsd as every element and attribute is fully documented there.

To complete MessageBroker's configuration we have to add message-broker tag :

<flex:message-broker/>

How to configurate Flex client's mapping towards MessageBroker in three simple steps

1) Definition of the DispatcherServlet in web.xml

The simple request mapping scenario is when the front-end Flex is the only client type for the application. In this case we can just map /messagebroker as top-level path for requests.

<servlet>
<servlet-name>BlazeServlet</servlet-name>
<servletclass>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param>
<param-name>contextConfigLocation</param-name>
<param-value> /WEB-INF/spring/app-context.xml </param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>BlazeServlet</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>

2) HandlerMapping into Spring app-context.xml

We have to configure an HandlerMapping to allow the correct requests mapping towards MessageBroker, but in this case we have to do nothing, because when we use a message-broker tag, there is a bean automatically installed that allows the HandlerMapping. This bean is a SimpleUrlHandlerMapping that maps all the incoming requests from DispathcherServlet to MessageBroker through the MessageBrokerHandlerAdapter. In practice the default settings installed by <flex:message-broker/> tag regard how to include the following configuration:

<!-- Maps request paths at /* to the BlazeDS MessageBroker -->
<bean
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/*=_messageBroker
</value>
</property>
</bean>

<!-- Dispatches requests mapped to a MessageBroker -->
<bean class="org.springframework.flex.servlet.MessageBrokerHandlerAdapter"/>

So HandlerMapping configuration in the spring app-contex.xml is how to include the message-broker tag.

3) Channel definition in the BlazeDS services-config.xml

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/ {context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>

To complete the correct requests mapping towards MessageBroker we have to define a channel to secure communication from client to server. In this way flex client can send and receive data correctly. Channel definition is in the services-config.xml file and must correspond to the chosen mapping.

Exporting Spring beans for Flex Remoting

1) Remoting Service config

To configure the BlazeDS RemotingService we have to include remoting-config.xml file in the BlazeDS configuration, but with the Spring BlazeDS Integration this configuration file can be left out completely as the inclusion of the message-broker tag in the Spring configuration will cause the RemotingService to be configured with sensible defaults if none already exists at startup time. The end result is essentially equivalent to including the following minimal remoting-config.xml in the BlazeDS configuration.

<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service" class="flex.messaging.services.RemotingService">
<adapters>
<adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter"
default="true"/>
</adapters>
</service>

We have just set a default channel in the service-config.xml

<services>
<default-channels>
<channel ref="my-amf"/>
</default-channels>
</services>

2) Remoting destination tag

It allows to export existing Spring-managed services for direct remoting from a Flex client. Given the following Spring bean definition for a employeeService bean :

<!-- Bean employeeService -->
<bean id="employeeService" class="service.EmployeeService">
<constructor-arg ref="employeeDAO" />
</bean>

and assuming the existance of a Spring-managed MessageBroker configured via the message-broker tag, the following remoting-destination tag will expose the service for remoting to Flex client as a remote service destination called employeeService:

<!-- REMOTING DESTINATION TAG -->
<flex:remoting-destination ref="employeeService" />

We have seen that with few steps is possible to build an application that support a front-end in Flex and a back-end in Spring through the Spring BlazeDS Integration which focuses on a single main component : MessageBroker.

At this link you'll find the official Spring BlazeDS Integration reference.

June 11, 2010

UiBinder : a simple way to build Widget from XML markup

UiBinder helps developers to build GWT widgets in a few simple steps, exploiting the flexibility and maintainability of XML. This allows developer without a strong background in java to be competitive in the GWT code production.

Thus we see UiBinder in action : first of all we must create a web application that use Google Web Toolkit. To do this, I use the eclipse's plugin for GWT, so from the prompt do :
File --> New --> Other --> Google --> Web application project. Then fill the required fields, uncheck the "Use Google app engine" option and click "Finish".

Now we realize the following html page containing a simple widget :

simplewidget.png

Initially we have to modify the home page, an HTML page, in which we create a "div" element that permit us to inject content from a Java class, the entryPoint :


<!doctype html>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">

<link type="text/css" rel="stylesheet" href="PostBlogUiBinder.css">

<title>Simple widget project</title>

<script type="text/javascript" language="javascript" src="postbloguibinder/postbloguibinder.nocache.js"></script>
</head>

<body>

<!-- OPTIONAL: include this if you want history support -->
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>

<!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
<noscript>
<div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
Your web browser must have JavaScript enabled
in order for this application to display correctly.
</div>
</noscript>

<h1>Sample Widget</h1>

<h3 align="center">Fill the following fields</h3>

<div id="simpleWidget" align="center"></div>

</body>
</html>


as you can see we have create a div element with id called "simpleWidget" that we refer from the entrypoint java class.

Now we have to inject into this page the widget that we want to create. We do this into the entrypoint class, called SimpleWidgetEntrypoint :



import com.post.uibinder.ui.SimpleWidget;
import com.google.gwt.core.client.EntryPoint;

import com.google.gwt.user.client.ui.RootPanel;


/**
* Entry point classes define onModuleLoad().
*/
public class SimpleWidgetEntrypoint implements EntryPoint {
/**
* This is the entry point method.
*/
public void onModuleLoad() {
SimpleWidget simpleWidget = new SimpleWidget();
RootPanel.get("simpleWidget").add(simpleWidget);
}
}

Now we have to create our widget, we can do this with the wizard plugin doing the following actions :

from the eclipse's prompt do File --> New --> Other --> Google Web Toolkit --> UiBinder --> Next

then digit the name of the java class of the widget, in our case "SimpleWidget" and then click Finish.

We can see now that the wizard has created two files :

- SimpleWidget.java
- SimpleWidget.ui.xml

To obtain our result widget we have to modify both files :

- SimpleWidget.ui.xml


<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:style>
.important {
font-weight: bold;
}
</ui:style>
<g:HTMLPanel ui:field="mainPanel">
<g:VerticalPanel>
<g:Label ui:field="descriptionLabel" ui:text="Put a description of yourself"></g:Label>
<g:TextArea ui:field="textArea" ui:text="Put here your description"></g:TextArea>
<g:Label ui:field="banLabel" ui:text="Select which band you prefer among these"></g:Label>
<g:RadioButton ui:name="band" ui:text="U2" ></g:RadioButton>
<g:RadioButton ui:name="band" ui:text="Radiohead"></g:RadioButton>
<g:RadioButton ui:name="band" ui:text="Pearl Jam"></g:RadioButton>
<g:RadioButton ui:name="band" ui:text="Depeche mode"></g:RadioButton>
</g:VerticalPanel>
<g:Button styleName="{style.important}" ui:field="button" ui:text="Confirm" />
</g:HTMLPanel>
</ui:UiBinder>


- SimpleWidget.java


import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;

public class SimpleWidget extends Composite {

private static SimpleWidgetUiBinder uiBinder = GWT
.create(SimpleWidgetUiBinder.class);

interface SimpleWidgetUiBinder extends UiBinder {
}

@UiField
Button button;
@UiField
TextArea textArea;

public SimpleWidget() {
initWidget(uiBinder.createAndBindUi(this));
textArea.setSize("300px", "200px");
}

@UiHandler("button")
void onClick(ClickEvent e) {
Window.alert("OK");
}

}

To build the widget we need the following GWT elements :

- VerticalPanel
- Label
- RadioButton
- Button
- TextArea

if we don't use the UiBinder utilities we have to write the entire widget only with java code, but this time into the SimpleWidget java class we have only specified the size of the text area, all the other elements with their values are specified into the XML file.
This is why UiBinder simplifies the construction of GWT widget and simplifies also the collaboration between UI designers, which are more confortable with markup languages, and developers.

About Java

This page contains an archive of all entries posted to Comtaste Consulting | Enterprise RIA consulting and development in the Java category. They are listed from oldest to newest.

Google apps is the previous category.

Livecycle Data Services is the next category.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33