Posts Tagged ‘GWT’
Useful DTD
DTDs are useful when your XML editor take them in account: detecting errors, suggestions, complete statements… For instance, I save much time with IntelliJ IDEA automatic completion ; unlike, Eclipse amazingly does not implement this feature.
Here is a list of some widely used DTDs:
File | DTD |
---|---|
weblogic-application.xml |
<!DOCTYPE weblogic-application PUBLIC "-//BEA Systems, Inc.//DTD WebLogic Application 7.0.0//EN" "http://www.oracle.com/technology/weblogic/weblogic-application/1.1/weblogic-application.xsd"> |
weblogic-application.xml |
<!DOCTYPE weblogic-application PUBLIC "-//BEA Systems, Inc.//DTD WebLogic Application 7.0.0//EN" "http://www.oracle.com/technology/weblogic/weblogic-application/1.1/weblogic-application.xsd"> |
web.xml |
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > |
*.hbm.xml |
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> |
GWT modules |
<!DOCTYPE module SYSTEM "http://google-web-toolkit.googlecode.com/svn/trunk/distro-source/core/src/gwt-module.dtd"> |
GWT UI |
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> |
Tangosol / Oracle Coherence |
<!DOCTYPE coherence SYSTEM "coherence.dtd"> |
Log4J |
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> |
Tangosol and Log4J DTDs are included within their distribution JARs: you have to extract them or to give their path to IntelliJ IDEA.
GWT / Sonar / Cannot invoke clone() on the array type… / The user-supplied array … is stored directly
I have to fix all critical “Violations” owing to Sonar.
Let’s consider a basic block:
public void setSushis(float[] sushis) { this.sushis = sushis; }
This piece of code raises this error in Sonar:
Security - Array is stored directly : The user-supplied array 'sushis' is stored directly.
In a naive step, I modified the code as this:
public void setSushis(float[] sushis) { this.sushis = sushis.clone(); }
This may have been OK… but, now, I get the following error within GWT compilation:
Cannot invoke clone() on the array type float[]
To fix the issue, I amended the code as follows:
public void setSushis(float[] theSushis) { this.sushis= new float[theSushis.length]; System.arraycopy(theSushis, 0, this.sushis, 0, theSushis.length); }
Disclaimer: even though I followed Sonar’s advice and requirements, I am a little skeptic about this kind of “violation”. 😐
Tutorial: an Event Bus Handler for GWT / GXT
Overview
Introduction
Let’s consider a application, JonathanGwtApplication, divided in three main panels
- a panel to select animal name name
- a panel to display, expand and collapse trees of the animal ancestors
- a panel of information to display many indicators (colors, ages, etc.).
An issue we encounter is: how to make the different panels communicate? In more technical terms, how to fire events from a panel to another one?
A first solution would be to declare each panel as listener to the other panels. Indeed, this principle may go further, and declare each component as listener to a list of other components…
Main drawbacks:
- the code becomes hard to read
- adding or removing a component requires to modify many parts of the code
- we don’t follow GWT 2’s “philosophy”, which is to use
Handlers
rather thanListeners
.
Hence, these reasons incited us to provide a global EventBusHandler
.
The EventBusHandler
concept
The EventBusHandler
is a global bus which is aware of all events that should be shared between different panels, and fires them to the right components.
The EventBusHandler
is a field of JonathanGwtApplicationContext
.
Intrastructure
lalou.jonathan.application.web.gwt.animal.events.HandledEvent
: generic interface for a event. Abstract method:EventTypeEnum getEventEnum();
lalou.jonathan.application.web.gwt.animal.handler.EventHandler
: generic interface for a component able to handle an event. Abstract method:void handleEvent(HandledEvent handledEvent);
lalou.jonathan.application.web.gwt.animal.handler.EventHandlerBus
: the actual bus. As a concrete class, it has two methods:/** * Fires an event to all components declared as listening to this event * event type. * * @param baseEvent */ public void fireEvent(HandledEvent baseEvent) { // ... } /** * Adds an listener/handler for the event type given as parameter * * @param eventTypeEnum * @param eventHandler * @return The List of handlers for the key given as parameter. This list * contains the eventHandler that was given as second parameter */ public List<EventHandler> put(EventTypeEnum eventTypeEnum, EventHandler eventHandler) { // ... }
How to use the bus?
- Define an event: in JonathanGwtApplication, an event is decribed by two elements:
- a functionnal entity: eg: “animal”, “food”, “tree node”. The functionnal entity must be isomorph to a technical DTO, eg:
AnimalDTO
for an entity Animal.(in the scope of this turoriel we assume to have DTOs, even though the entities may ne sufficient) - a technical description of the event: “selection changed”, “is expanded”
- a functionnal entity: eg: “animal”, “food”, “tree node”. The functionnal entity must be isomorph to a technical DTO, eg:
- Add an entry in the enum
EventTypeEnum
. Eg: “ANIMAL_SELECTION_CHANGED
“ - in
lalou.jonathan.application.web.gwt.animal.events
, create an event, implementingHandledEvent
and its methodgetEventEnum()
. The match betweenEventTypeEnum
and DTO is achieved here. Eg:public class AnimalSelectionChangedEvent extends SelectionChangedEvent<AnimalDTO> implements HandledEvent { public AnimalSelectionChangedEvent( SelectionProvider<AnimalDTO> provider, List<AnimalDTO> selection) { super(provider, selection); } public EventTypeEnum getEventEnum() { return EventTypeEnum.ANIMAL_SELECTION_CHANGED; } }
animalComboBox.addSelectionChangedListener(new SelectionChangedListener<AnimalDTO>() { @Override public void selectionChanged(SelectionChangedEvent<AnimalDTO> se) { final AnimalDTO selectedAnimalVersion; selectedAnimalVersion= se.getSelectedItem(); JonathanGwtApplicationContext.setSelectedAnimal(selectedAnimal); final AnimalSelectionChangedEvent baseEvent = new AnimalSelectionChangedEvent( se.getSelectionProvider(), se.getSelection()); JonathanGwtApplicationContext.getEventHandlerBus() .fireEvent(baseEvent); } });
- easy case: the component handles only one type of event: this handler must implement the right interface (eg:
AnimalSelectionChangedEventHandler
) and its method, eg:protected void handleAnimalSelectionChangedEvent(HandledEvent handledEvent) { return; }
- frequent case: the component handles two or more event types. No matter, make the component implement all the needed interfaces (eg:
AnimalSelectionChangedEventHandler
,FoodSelectionChangedEventHandler
). Provide a unique entry point for the method to implement, which is common to both interfaces. Retrieve the event type, and handle it with ad hoc methods. Eg:public void handleEvent(HandledEvent handledEvent) { final EventTypeEnum eventTypeEnum; eventTypeEnum = handledEvent.getEventEnum(); switch (eventTypeEnum) { case ANIMAL_SELECTION_CHANGED: handleAnimalSelectionChangedEvent(handledEvent); return; case FOOD_SELECTION_CHANGED: handleFoodSelectionChangedEvent(handledEvent); return; default: break; } } protected void handleAnimalSelectionChangedEvent(HandledEvent handledEvent) { // do something } protected void handleFoodSelectionChangedEvent(HandledEvent handledEvent) { // do something else }