As Eclipse RCP developer, you have different options to create prototypes for your customers quickly.
In this talk, I will share my experience in building RCP applications by using a simple, efficient and extensible technology stack based on:
POJO data model
JAXB and JPA annotations for XML and DB persistence
Eclipse E4 as Application Platform
WindowBuilder as a visual designer to build UIs and manage data bindings.
With the help of a case study from the banking domain, you will see all the steps needed to create a complete prototype that you can easily re-use and transform into a real world application.
During the presentation, we'll examine the key points for the creation of the prototype, and you will see few demos on how to use the E4 Editor and Window Builder efficiently.
At the end of the talk, you will be able to repeat the process and understand and adapt the provided source code to develop your applications quickly.
If you want to prototype Eclipse RCP applications with XML/DB persistence and a relatively complex UI, you should attend this talk.
2. About us
• Speaker
• Patrik Suzzi, www.itemis.ch
Software Engineer
Eclipse Platform Committer
• Audience
• Are you familiar with JAXB, JPA?
• Eclipse E4 and WindowBuilder?
3. IDE and Tools
• Eclipse IDE for RCP and RAP development (Oxygen.1a)
+ Nebula Widgets (to use XY Graph)
http://download.eclipse.org/nebula/releases/latest
+ WindowBuilder (if not already installed in Eclipse IDE for RCP..)
http://download.eclipse.org/windowbuilder/WB/integration/4.8/
• Libraries
+ EclipseLink (JPA and JAXB)
https://www.eclipse.org/eclipselink/downloads/
+ Database (Derby)
https://db.apache.org/derby/
4. Getting started – build a RCP prototype
• Build your Data Model
• Add Xml/DB persistence
• Test the datamodel
• Build your E4 Application
• Start with a Simple UI
• Evolve it in a Complex UI
• Run your prototype
5. Data Model
• Bank
• Customer
• Account
• Transaction
• Subtypes
• Use property change
listeners!
6. Test Data Model
Bank bank = new Bank();
// create customers
Customer c1 = new Customer("Tom", "Jones", "Garden Street 8");
Customer c2 = new Customer("Diana", "Jones", "Garden Street 8");
Customer c3 = new Customer("Mark", "Reuters", "Maple Street 122");
Customer c4 = new Customer("Spencer", "White", "Avenue Pontida 1");
Customer c5 = new Customer("Alex", "Michaelson", "Red Square 14b");
Customer c6 = new Customer("Francois", "Berger", "Frederickstrasse 87");
bank.addCustomers(c1,c2,c3,c4,c5,c6);
// add accounts and link to customers
Account a1 = new Account().link(c1);
Account a2 = new Account().link(c1, c2);
Account a3 = new Account().link(c3);
Account a4 = new Account().link(c4);
Account a5 = new Account().link(c5);
Account a6 = new Account().link(c6);
Account a7 = new Account().link(c6);
bank.addAccounts(a1,a2,a3,a4,a5,a6,a7);
// add transactions
Transaction t1 = new Deposit().create(5000, a1).confirm("2016-02-20").process();
Transaction t2 = new Charge().create(250, a1).confirm("2016-03-10").process();
Transaction t3 = new Transfer().create(1000, a1, a2).confirm("2016-04-05").process();
Transaction t4 = new Deposit().create(10000, a3).confirm("2016-04-06").process();
Transaction t5 = new Deposit().create(5000, a3).confirm("2016-04-10").process();
Transaction t6 = new Deposit().create(5000, a3).confirm("2016-06-21").process();
Transaction t7 = new Deposit().create(10000, a3).confirm("2016-06-23").process();
Transaction t8 = new Withdrawal().create(2500, a3).confirm("2016-07-01").process();
Transaction t9 = new Charge().create(1500, a3).confirm("2016-07-03").process();
Transaction t10 = new Transfer().create(1000, a3, a2).confirm("2016-07-05").process();
bank.addTransactions(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10);
// test mock data
assertEquals("Nr. of Customers", 6, bank.getCustomers().size());
assertEquals("Nr. of Accounts", 7, bank.getAccounts().size());
assertEquals("Nr. of Transactions", 10, bank.getTransactions().size());
// test containment
assertThat("Account's customer", a1.getCustomers().contains(c1));
assertThat("Customer's account", c1.getAccounts().contains(a1));
assertThat("Transaction's account", t1.getSourceAccount().equals(a1));
• Test the validity of your data!
7. Add JAXB Annotations
@XmlRootElement
public class Bank {...}
@XmlAttribute
@XmlID
public String getId() {...}
@XmlList
@XmlIDREF
public List<Account> getAccounts() { ... }
• XML tags
• Attribute representing ID
• XML Aggregation, as list of IDs
referencing entities
• Subclasses implementing abstract
superclass
@XmlSeeAlso({Deposit.class, Charge.class, Withdrawal.class,
Transfer.class})
@XmlRootElement
public abstract class Transaction {...}
8. XML Persistence Test
• Save and Load with JAXB
public static void persistXml(File xmlFile, Bank bank) {
JAXBContext jaxbContext = JAXBContext.newInstance(Bank.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(bank, xmlFile);
}
public static Bank loadXml(File xmlFile) {
JAXBContext jaxbContext = JAXBContext.newInstance(Bank.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Bank bank = (Bank) unmarshaller.unmarshal(xmlFile);
return bank;
}
Usage: TestPersistence.java
<bank id="59340">
<customers id="2711">
<accounts>143365 170217</accounts>
<address>Garden Street 8</address>
<firstName>Tom</firstName>
<lastName>Jones</lastName>
</customers>
<accounts id="143365">
<balance>3750.0</balance>
<creationDate>2016-02-01T00:00:00+01:00</creationDate>
<customers>2711</customers>
<transactions>110290 79075 91111</transactions>
</accounts>
<transactions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="deposit" id="110290">
<amount>5000.0</amount>
<confirmed>true</confirmed>
<confirmedDate>2016-02-20T00:00:00+01:00</confirmedDate>
<processed>true</processed>
<processedDate>2016-02-20T00:00:00+01:00</processedDate>
<sourceAccount>143365</sourceAccount>
</transactions>
</bank>
Aggregation ID list
ID attribute
Subclass
9. Add JPA2 Annotations
• Superclass with no table defined for it
• Entity with a table defined for it
• One way association with reference
• Single table inheritance, by
discriminating column
• Subclass with given discriminator
@MappedSuperclass
public class BaseModel {...}
@Entity
public class Bank extends BaseModel{...}
@OneToMany
@JoinColumn(name="BANK_ID")
public List<Customer> getCustomers() {...}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Table(name="T_TRANSACTION")
@DiscriminatorColumn(name="T_TYPE")
public abstract class Transaction {...}
@Entity
@DiscriminatorValue("D")
public class Deposit extends Transaction {...}
10. DB Persistence Test
• Persist and Load with JPA
public static void persistDB(Bank bank){
EntityManager em = instance().getEntityManager();
em.getTransaction().begin();
em.merge(bank);
em.flush();
em.getTransaction().commit();
}
public static Bank loadDB() throws JAXBException {
EntityManager em = instance().getEntityManager();
em.getTransaction().begin();
TypedQuery<Bank> query = em.createQuery(SELECT_BANK, Bank.class);
Bank bank = query.getSingleResult();
return bank;
}
Usage: TestPersistence.java
24. Demo – Working application
• Search
• Edit
• Select
• Chart
• Tables
• Create
• XML save/load
• DB save/load
25. Concluding
• Rapid prototype, fully customizable, persist your data
• Source:
• https://github.com/psuzzi/eclipsecon/tree/ece2017/democode Project:
ece2017/com.itemis.e4.banking
• Please, get in touch if you need more information.
• www.itemis.com
26. Thank you for your attention!
itemis AG | Am Brambusch 15-24 | D-44536 Lünen | www.itemis.de