Difference between revisions of "Customizing opentaps 2: an OSGi Tutorial"
Line 1: | Line 1: | ||
In this tutorial, I will take you through the steps to customizing the [[opentaps 2 Notes]] application and show you how to work with the OSGi framework. | In this tutorial, I will take you through the steps to customizing the [[opentaps 2 Notes]] application and show you how to work with the OSGi framework. | ||
− | Right now our notes application is looking pretty good -- I can create notes from my html client application using the REST interface. I plan on using my notes application for comments from my different sites. To keep track of | + | Right now our notes application is looking pretty good -- I can create notes from my html client application using the REST interface. I plan on using my notes application for comments from my different sites. To keep track of which site the note came from, I'd like to add a new field to store where the notes are coming from. |
− | The first step is to add the field to my | + | The first step is to add the field to my data model. Our data model is part of the repository from the [[Domain Driven Architecture]], so there is an abstract representation of the data model in the repository interfaces and its concrete implementation with JPA for persistence with a database. We first need to add our new data field to the definition of notes, which is the <tt>Note.java</tt> class in <tt>org/opentaps/notes/domain/Note.java</tt> in <tt>modules/notes/api/services/src/main/java</tt>: |
+ | |||
+ | <pre> | ||
+ | private String clientDomain; | ||
+ | </pre> | ||
+ | |||
+ | Notice that's all I'm adding -- a field (plus getters and setters with Eclipse). It doesn't matter how the field is actually implemented here, since this <tt>Note.java</tt> class is just an object-oriented representation of my data model. | ||
+ | |||
+ | I don't need to modify the repository interface, because the repository interface simply defines methods that operate on the <tt>Note.java</tt> class, and none of them are affected by this new field. If I were to need a method that worked on this field, such as returning a list of notes from a particular domain, however, I would need to add it to <tt>NoteRepository.java</tt> in the <tt>modules/notes/api</tt> module. | ||
+ | |||
+ | Now I need to change my implementation of the repository so that this field shows up in my database table and will be persisted correctly. To add this field to the database, I need to modify the JPA definition for <tt>Note.java</tt>, which is the <tt>org/opentaps/notes/entity/NoteData.java</tt> class <tt>modules/notes/impl/repository/</tt>. Here I will add a new field (notice the JPA markup): | ||
<pre> | <pre> | ||
@Column(name = "CLIENT_DOMAIN") | @Column(name = "CLIENT_DOMAIN") | ||
Line 38: | Line 48: | ||
</pre> | </pre> | ||
− | Yay! My new field was added automatically when I accessed the notes application. | + | Yay! My new field was added automatically when I accessed the notes application again. |
+ | |||
+ | To handle persistence of the field with the repository, I modify the <tt>NoteRepositoryImpl.java</tt> class in <tt>modules/notes/impl/repository/</tt> so that the client domain field is transferred between my abstract domain class <tt>Note.java</tt> and my persistence class <tt>NoteData.java</tt>: | ||
+ | <pre> | ||
+ | private static Note makeNote(NoteData noteData) { | ||
+ | // ... | ||
+ | note.setClientDomain(noteData.getClientDomain()); | ||
+ | // ... | ||
+ | |||
+ | private static NoteData makeNoteData(Note note) { | ||
+ | // ... | ||
+ | noteData.setClientDomain(note.getClientDomain()); | ||
+ | // ... | ||
+ | </pre> |
Revision as of 00:33, 24 February 2012
In this tutorial, I will take you through the steps to customizing the opentaps 2 Notes application and show you how to work with the OSGi framework.
Right now our notes application is looking pretty good -- I can create notes from my html client application using the REST interface. I plan on using my notes application for comments from my different sites. To keep track of which site the note came from, I'd like to add a new field to store where the notes are coming from.
The first step is to add the field to my data model. Our data model is part of the repository from the Domain Driven Architecture, so there is an abstract representation of the data model in the repository interfaces and its concrete implementation with JPA for persistence with a database. We first need to add our new data field to the definition of notes, which is the Note.java class in org/opentaps/notes/domain/Note.java in modules/notes/api/services/src/main/java:
private String clientDomain;
Notice that's all I'm adding -- a field (plus getters and setters with Eclipse). It doesn't matter how the field is actually implemented here, since this Note.java class is just an object-oriented representation of my data model.
I don't need to modify the repository interface, because the repository interface simply defines methods that operate on the Note.java class, and none of them are affected by this new field. If I were to need a method that worked on this field, such as returning a list of notes from a particular domain, however, I would need to add it to NoteRepository.java in the modules/notes/api module.
Now I need to change my implementation of the repository so that this field shows up in my database table and will be persisted correctly. To add this field to the database, I need to modify the JPA definition for Note.java, which is the org/opentaps/notes/entity/NoteData.java class modules/notes/impl/repository/. Here I will add a new field (notice the JPA markup):
@Column(name = "CLIENT_DOMAIN") private String clientDomain;
and use Eclipse to create get and set methods for it.
Just to make sure I did it correctly, I build opentaps 2 again with mvn clean install, use the Geronimo to uninstall the old org.opentaps.notes.eba and deploy the new one. Then I create another note from my html client and check the database:
mysql> show fields from NOTE_DATA; +--------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------------+--------------+------+-----+---------+-------+ | NOTE_ID | varchar(32) | NO | PRI | NULL | | | ATTRIBUTE_1 | varchar(255) | YES | | NULL | | | ATTRIBUTE_10 | varchar(255) | YES | | NULL | | | ATTRIBUTE_2 | varchar(255) | YES | | NULL | | | ATTRIBUTE_3 | varchar(255) | YES | | NULL | | | ATTRIBUTE_4 | varchar(255) | YES | | NULL | | | ATTRIBUTE_5 | varchar(255) | YES | | NULL | | | ATTRIBUTE_6 | varchar(255) | YES | | NULL | | | ATTRIBUTE_7 | varchar(255) | YES | | NULL | | | ATTRIBUTE_8 | varchar(255) | YES | | NULL | | | ATTRIBUTE_9 | varchar(255) | YES | | NULL | | | CREATED_BY_USER_ID | varchar(255) | YES | | NULL | | | DATE_TIME_CREATED | datetime | YES | | NULL | | | USER_ID_TYPE | varchar(255) | YES | | NULL | | | SEQUENCE_NUM | bigint(20) | YES | | NULL | | | NOTE_TEXT | text | YES | | NULL | | | CLIENT_DOMAIN | varchar(255) | YES | | NULL | | +--------------------+--------------+------+-----+---------+-------+ 17 rows in set (0.05 sec)
Yay! My new field was added automatically when I accessed the notes application again.
To handle persistence of the field with the repository, I modify the NoteRepositoryImpl.java class in modules/notes/impl/repository/ so that the client domain field is transferred between my abstract domain class Note.java and my persistence class NoteData.java:
private static Note makeNote(NoteData noteData) { // ... note.setClientDomain(noteData.getClientDomain()); // ... private static NoteData makeNoteData(Note note) { // ... noteData.setClientDomain(note.getClientDomain()); // ...