Thursday October 08, 2009
TOTD #112: Exposing Oracle database tables as RESTful entities using JAX-RS, GlassFish, and NetBeans
Content available at: http://blog.arungupta.me/2009/10/totd-112-exposing-oracle-database-tables-as-restful-entities-using-jax-rs-glassfish-and-netbeans/.
Posted by Arun Gupta in General | Comments[0]
|
|
|
|
|
Monday August 31, 2009
TOTD #97 showed how to install GlassFish Tools Bundle for Eclipse 1.1. Basically there are two options - either install Eclipse 3.4.2 with WTP and pre-bundled/configured with GlassFish v2/v3, MySQL JDBC driver and other features. Or if you are using Eclipse 3.5, then you can install the plug-in separately and get most of the functionality.
TOTD #98 showed how to create a simple Metro/JAX-WS compliant Web service using that bundle and deploy on GlassFish.
This Tip Of The Day (TOTD) shows how to create a simple Java EE 6 application that reads data from a MySQL database using JPA 2.0 and Servlet 3.0 and display the results. A more formal support of Java EE 6/Servlet 3.0 is coming but in the meanwhile the approach mentioned below will work.
Lets get started!














@WebServlet(urlPatterns="/ServletClient")
public class ServletClient extends HttpServlet {
@PersistenceUnit
EntityManagerFactory factory;
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletOutputStream out = resp.getOutputStream();
List list = factory.createEntityManager().createQuery("select f from Film f where f.title like 'GL%';").getResultList();
out.println("<html><table>");
for (Object film : list) {
out.print("<tr><td>" + ((Film)film).getTitle() + "</tr></td>");
}
out.println("</table></html>");
}
}
import java.io.IOException; import java.util.List; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceUnit; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import model.Film;Basically, this is a Servlet 3.0 specification compliant Servlet that uses @WebServlet annotation. It uses @PersistenceUnit to inject the generated JPA Persistence Unit which is then used to query the database. The database query return all the movies whose title start with "GL" and the response is displayed in an HTML formatted table.


Simple, easy and clean!
How are you using Eclipse and GlassFish - the consolidated bundle or standalone Eclipse + GlassFish plugin ?
Download GlassFish Tools Bundle for Eclipse now.
Please send your questions and comments to users@glassfishplugins.dev.java.net.
Please leave suggestions on other TOTD that you’d like to see. A complete archive of all the tips is available here.
Technorati: glassfish eclipse mysql jpa database
Posted by Arun Gupta in General | Comments[0]
|
|
|
|
|
Tuesday August 18, 2009
LOTD #22: How to inject JPA resources ? - PersistenceUnit vs PersistenceContext
Java Persistence API defines a standard object/relational mapping using
POJOs. In JPA, a persistence
unit is described using "persistence.xml", bundled with
the web application, injected into your web application and then POJOs
are used to access all the information from the underlying persistence
mechanism such as a database.
JPA can injected into your application couple of different ways as
shown below:
| @PersistenceUnit EntityManagerFactory emf; |
| @PersistenceContext EntityManager manager; |
Posted by Arun Gupta in General | Comments[1]
|
|
|
|
|
Thursday April 09, 2009
LOTD #20: How to create a JPA application using GlassFish Tools Bundle for Eclipse ?
Here is a great screencast (from the community) that shows how to
create a JPA application
using EclipseLink and deploy on GlassFish v2.1 - all using GlassFish
Tools Bundle for Eclipse.
Click on the image below for the video:

Thanks!
I'll work on a MySQL version of it :)
All previous links in this series are archived at LOTD.
Technorati: lotd
glassfish
eclipse
jpa javadb screencast
Posted by Arun Gupta in General | Comments[4]
|
|
|
|
|
Wednesday April 08, 2009
TOTD #78: GlassFish, EclipseLink, and MySQL efficient pagination using LIMIT
EclipseLink
JPA replaces TopLink
Essentials as the JPA implementation in GlassFish v3. One
of the benefits of using EclipseLink is that it provides efficient
pagination support for the MySQL database by generating
native SQL statements such as "SELECT ... FROM <table>
LIMIT <offset>, <rowcount>".
The MySQL LIMIT clause definition
says:
The
LIMIT clause can be used to constrain the number of rows returned by
the SELECT statement. LIMIT takes one or two numeric arguments, which
must both be non-negative integer constants (except when using prepared
statements).
With two arguments, the
first argument specifies
the offset of the first row to return, and the second specifies the
maximum number of rows to return. The offset of the initial row is 0
(not 1):
SELECT * FROM tbl LIMIT
5,10; # Retrieve rows 6-15
So instead of fetching all rows from the database and then filtering
from row 6-15, only rows 6 through 15 are fetched.
This TOTD (Tip
Of The Day) explains how to
create a JPA Persistence Unit for sakila
(MySQL sample database) using NetBeans,
use EclipseLink as the Persistence Provider, and then write a JPA query
to leverage the pagination support - all on GlassFish v3.

| <properties> <property name="eclipselink.logging.level" value="FINE"/> </properties> |
| ./asadmin create-jdbc-connection-pool
--datasourceclassname
com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource --property
user=duke:password=glassfish:ServerName=localhost:portNumber=3306:databaseName=sakila
jdbc-mysql-pool |
| ./asadmin create-jdbc-resource --connectionpoolid jdbc-mysql-pool jndi/sakila |
| @PersistenceUnit EntityManagerFactory emf; |
|
EntityManager em = emf.createEntityManager(); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { int startRow = Integer.valueOf(request.getParameter("start_row")); int howMany = Integer.valueOf(request.getParameter("how_many")); Query q = em.createNamedQuery("Film.findAll"); q.setFirstResult(startRow); q.setMaxResults(startRow + howMany); for (Object film : q.getResultList()) { out.print(((Film)film).toString() + "<br/>"); } } finally { out.close(); } |

| [#|2009-04-07T14:01:12.815-0700|FINE|glassfish|org.eclipse.persistence.session.file:
/Users/arungupta/tools/glassfish/v3/b43/glassfishv3/glassfish/domains/domain1/applications/Pagination/WEB-INF/classes/-PaginationPU.sql|
_ThreadID=15;_ThreadName=Thread-1;ClassName=null;MethodName=null;|SELECT
film_id AS film_id1, special_features AS special_features2, last_update
AS last_update3, rental_duration AS rental_duration4, release_year AS
release_year5, title AS title6, description AS description7,
replacement_cost AS replacement_cost8, length AS length9, rating AS
rating10, rental_rate AS rental_rate11, language_id AS language_id12,
original_language_id AS original_language_id13 FROM film LIMIT ?, ? bind => [1, 11]|#] |
| [#|2009-04-07T17:00:34.210-0700|FINE|glassfish|org.eclipse.persistence.session.file: /Users/arungupta/tools/glassfish/v3/b43/glassfishv3/glassfish/domains/domain1/applications/Pagination/WEB-INF/classes/-PaginationPU.sql| _ThreadID=15;_ThreadName=Thread-1;ClassName=null;MethodName=null;|SELECT film_id, special_features, last_update, rental_duration, release_year, title, description, replacement_cost, length, rating, rental_rate, language_id, original_language_id FROM film|#] |
Posted by Arun Gupta in web2.0 | Comments[6]
|
|
|
|
|
Friday April 03, 2009
TOTD # 77: Running Seam examples with GlassFish
![]() |
Seam is a full-stack solution to assemble complex web applications using simple annotated classes, a rich set of UI components, and very little XML. It integrates Ajax and Business Process Modeling with several Java EE technologies such as Java Server Faces (JSF), Java Persistence API (JPA), and Enterprise Java Beans (EJB 3.0). |
| ~/tools/jboss-seam-2.1.1.GA/examples/jpa >ant glassfish Buildfile: build.xml glassfish: initcopy: initpoms: [echo] Setting up dependencies [mkdir] Created dir: /Users/arungupta/tools/jboss-seam-2.1.1.GA/classes/poms [copy] Copying 1 file to /Users/arungupta/tools/jboss-seam-2.1.1.GA/classes/poms [artifact:install] [INFO] Installing /Users/arungupta/tools/jboss-seam-2.1.1.GA/classes/poms/root.pom to . . . . . . init.war: war: [copy] Copying 27 files to /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/jpa/exploded-archives-glassfish/jboss-seam-jpa.war [copy] Copying 7 files to /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/jpa/exploded-archives-glassfish/jboss-seam-jpa.war/WEB-INF/lib noejb.war: [copy] Copying 18 files to /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/jpa/exploded-archives-glassfish/jboss-seam-jpa.war/WEB-INF/lib [copy] Copying 2 files to /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/jpa/exploded-archives-glassfish/jboss-seam-jpa.war [copy] Copying 4 files to /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/jpa/exploded-archives-glassfish/jboss-seam-jpa.war distributable.war: noejb.archive: [jar] Building jar: /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/jpa/dist-glassfish/jboss-seam-jpa.war BUILD SUCCESSFUL Total time: 5 seconds |
| ~/tools/jboss-seam-2.1.1.GA/examples/jpa >~/tools/glassfish/v2.1/glassfish/bin/asadmin
deploy dist-glassfish/jboss-seam-jpa.war Command deploy executed successfully. |



| ~/tools/jboss-seam-2.1.1.GA/examples/hibernate
>ant glassfish Buildfile: build.xml glassfish: initcopy: initpoms: [echo] Setting up dependencies [copy] Copying 1 file to /Users/arungupta/tools/jboss-seam-2.1.1.GA/classes/poms [artifact:install] [INFO] Installing /Users/arungupta/tools/jboss-seam-2.1.1.GA/classes/poms/root.pom to /Users/arungupta/.m2/repository/org/jboss/seam/root/2.1.1.GA/root-2.1.1.GA.pom . . . distributable.war: noejb.archive: [jar] Building jar: /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/hibernate/dist-glassfish/jboss-seam-hibernate.war BUILD SUCCESSFUL Total time: 6 seconds |
| ~/tools/jboss-seam-2.1.1.GA/examples/hibernate
>~/tools/glassfish/v2.1/glassfish/bin/asadmin
deploy dist-glassfish/jboss-seam-hibernate.war Command deploy executed successfully. |
| ~/tools/jboss-seam-2.1.1.GA/examples/jee5/booking
>ant Buildfile: build.xml initcopy: initpoms: [echo] Setting up dependencies [copy] Copying 1 file to /Users/arungupta/tools/jboss-seam-2.1.1.GA/classes/poms [artifact:install] [INFO] Installing /Users/arungupta/tools/jboss-seam-2.1.1.GA/classes/poms/root.pom to /Users/arungupta/.m2/repository/org/jboss/seam/root/2.1.1.GA/root-2.1.1.GA.pom [copy] Copying 1 file to /Users/arungupta/tools/jboss-seam-2.1.1.GA/classes/poms . . . archive: [jar] Building jar: /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/jee5/booking/dist/jboss-seam-jee5-booking.jar [jar] Building jar: /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/jee5/booking/dist/jboss-seam-jee5-booking.war [jar] Building jar: /Users/arungupta/tools/jboss-seam-2.1.1.GA/examples/jee5/booking/dist/jboss-seam-jee5-booking.ear BUILD SUCCESSFUL Total time: 5 seconds ~/tools/jboss-seam-2.1.1.GA/examples/jee5/booking >~/tools/glassfish/v2.1/glassfish/bin/asadmin deploy dist/jboss-seam-jee5-booking.ear Command deploy executed successfully. |
Posted by Arun Gupta in Finance | Comments[13]
|
|
|
|
|
Wednesday August 06, 2008
TOTD #40: jQuery Autcomplete widget with MySQL, GlassFish, NetBeans
TOTD
#39 explained how to create an Autocomplete widget
(server-powered autocompleting of text fields, similar to Google
Suggest) using Prototype/Script.aculo.us libraries
with NetBeans, GlassFish and MySQL. This Tip Of The Day (TOTD) builds
upon that project and shows how same functionality can be achieved
using jQuery
Library.
|
<script src="javascripts/jquery-1.2.6.min.js"
type="text/javascript"></script> <script type="text/javascript"> function autocomplete(autocomplete) { if (autocomplete.length == 0) { $('#autocomplete_choices').hide(); } else { $.post("/Autocomplete/StatesServlet", { autocomplete_parameter: "" + autocomplete + ""}, function(data) { if (data.length > 0) { $('#autocomplete_choices').show(); $('#autocomplete_choices').html(data); } }); } } </script> |


Posted by Arun Gupta in web2.0 | Comments[0]
|
|
|
|
|
Friday July 25, 2008
TOTD #38: Creating a MySQL Persistence Unit using NetBeans IDE
This TOTD (Tip
Of The Day) shows how to
create a Persistence Unit (PU) for a MySQL
database using NetBeans
IDE. This PU can then be used in any of Java EE artifacts (JSP,
Servlet, EJB, ...) for database interaction.

| ~ >sudo
mysqld_safe --user root Password:<YOUR PASSWORD> Starting mysqld daemon with databases from /usr/local/mysql/data |
| mysql> CREATE
USER duke IDENTIFIED by 'duke'; Query OK, 0 rows affected (0.00 sec) mysql> create database states; Query OK, 1 row affected (0.00 sec) mysql> GRANT ALL on states.* TO duke; Query OK, 0 rows affected (0.00 sec) |


| CREATE TABLE STATES ( id INT, abbrev VARCHAR(2), name VARCHAR(50), PRIMARY KEY (id) ); |

| INSERT INTO STATES VALUES (1, "AL", "Alabama"); INSERT INTO STATES VALUES (2, "AK", "Alaska"); INSERT INTO STATES VALUES (3, "AZ", "Arizona"); INSERT INTO STATES VALUES (4, "AR", "Arkansas"); INSERT INTO STATES VALUES (5, "CA", "California"); INSERT INTO STATES VALUES (6, "CO", "Colorado"); INSERT INTO STATES VALUES (7, "CT", "Connecticut"); INSERT INTO STATES VALUES (8, "DE", "Delaware"); INSERT INTO STATES VALUES (9, "GL", "Florida"); INSERT INTO STATES VALUES (10, "GA", "Georgia"); INSERT INTO STATES VALUES (11, "HI", "Hawaii"); INSERT INTO STATES VALUES (12, "ID", "Idaho"); INSERT INTO STATES VALUES (13, "IL", "Illinois"); INSERT INTO STATES VALUES (14, "IN", "Indiana"); INSERT INTO STATES VALUES (15, "IA", "Iowa"); INSERT INTO STATES VALUES (16, "KS", "Kansas"); INSERT INTO STATES VALUES (17, "KY", "Kentucky"); INSERT INTO STATES VALUES (18, "LA", "Louisiana"); INSERT INTO STATES VALUES (19, "ME", "Maine"); INSERT INTO STATES VALUES (20, "MD", "Maryland"); INSERT INTO STATES VALUES (21, "MA", "Massachussetts"); INSERT INTO STATES VALUES (22, "MI", "Michigan"); INSERT INTO STATES VALUES (23, "MN", "Minnesota"); INSERT INTO STATES VALUES (24, "MS", "Mississippi"); INSERT INTO STATES VALUES (25, "MO", "Missouri"); INSERT INTO STATES VALUES (26, "MT", "Montana"); INSERT INTO STATES VALUES (27, "NE", "Nebraska"); INSERT INTO STATES VALUES (28, "NV", "Nevada"); INSERT INTO STATES VALUES (29, "NH", "New Hampshire"); INSERT INTO STATES VALUES (30, "NJ", "New Jersey"); INSERT INTO STATES VALUES (31, "NM", "New Mexico"); INSERT INTO STATES VALUES (32, "NY", "New York"); INSERT INTO STATES VALUES (33, "NC", "North Carolina"); INSERT INTO STATES VALUES (34, "ND", "North Dakota"); INSERT INTO STATES VALUES (35, "OH", "Ohio"); INSERT INTO STATES VALUES (36, "OK", "Oklahoma"); INSERT INTO STATES VALUES (37, "OR", "Orgeon"); INSERT INTO STATES VALUES (38, "PA", "Pennsylvania"); INSERT INTO STATES VALUES (39, "RI", "Rhode Island"); INSERT INTO STATES VALUES (40, "SC", "South Carolina"); INSERT INTO STATES VALUES (41, "SD", "South Dakota"); INSERT INTO STATES VALUES (42, "TN", "Tennessee"); INSERT INTO STATES VALUES (43, "TX", "Texas"); INSERT INTO STATES VALUES (44, "UT", "Utah"); INSERT INTO STATES VALUES (45, "VT", "Vermont"); INSERT INTO STATES VALUES (46, "VA", "Virginia"); INSERT INTO STATES VALUES (47, "WA", "Washington"); INSERT INTO STATES VALUES (48, "WV", "West Virignia"); INSERT INTO STATES VALUES (49, "WI", "Wisconsin"); INSERT INTO STATES VALUES (50, "WY", "Wyoming"); |



|
<properties> <property name="toplink.jdbc.user" value="duke"/> <property name="toplink.jdbc.password" value="duke"/> </properties> |
| <?xml version="1.0"
encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="AutocompletePU" transaction-type="JTA"> <jta-data-source>jndi/states</jta-data-source> <class>server.States</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="toplink.jdbc.user" value="duke"/> <property name="toplink.jdbc.password" value="duke"/> </properties> </persistence-unit> </persistence> |
| EntityManager em; @Override public void init() throws ServletException { EntityManagerFactory emf = Persistence.createEntityManagerFactory("AutocompletePU"); em = emf.createEntityManager(); } |
|
@PersistenceContext(unitName="AutocompletePU") EntityManager em; |
|
String abbrev = request.getParameter("abbrev"); List<States> list = em.createNamedQuery("States.findByAbbrev"). setParameter("abbrev", abbrev). getResultList(); if (list.size() > 0) { States s = list.get(0); out.println("Found " + s.getName() + " with abbrev \"" + abbrev + "\""); } else { out.println("No matching state found with \"" + abbrev + "\""); } |


Posted by Arun Gupta in web2.0 | Comments[15]
|
|
|
|
|
Thursday April 03, 2008
This blog provides how you can get started with Merb on JRuby
1.1 RC3.
Merb is another MVC framework (just like Rails) but with a pluggable
ORM, JavaScript library and Template language. Rails has built-in
support for these using ActiveRecord, Script.aculo.us
and ERB
templates. Making it pluggable keeps the core very lightweight and
still providing support for a particular feature using plugins. Another
big advantage of Merb is that unlike Rails it's thread-safe.
There
are already third party supports for ActiveRecord, DataMapper and
Sequel ORMs. I will hopefully be able to build support for Java
Persistence API ORM in Merb. Until then, here is how you
install and get started with Merb on JRuby 1.1 RC3.
Install Merb on JRuby as:
| Macintosh-187:jruby-1.1RC3
arungupta$ bin/jruby -S
gem install merb mongrel JRuby limited openssl loaded. gem install jruby-openssl for full support. http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL Updating metadata for 339 gems from http://gems.rubyforge.org ......................................................................................................... ......................................................................................................... ......................................................................................................... ........................ complete Successfully installed abstract-1.0.0 Successfully installed erubis-2.5.0 Successfully installed json_pure-1.1.2 Successfully installed rack-0.3.0 Successfully installed hpricot-0.6-java Successfully installed mime-types-1.15 Successfully installed merb-core-0.9.2 Successfully installed merb-action-args-0.9.2 Successfully installed merb-assets-0.9.2 Successfully installed activesupport-2.0.2 Successfully installed rubigen-1.2.4 Successfully installed merb-gen-0.9.2 Successfully installed merb-haml-0.9.2 Successfully installed merb-builder-0.9.2 Successfully installed mailfactory-1.2.3 Successfully installed merb-mailer-0.9.2 Successfully installed merb-parts-0.9.2 Successfully installed merb-cache-0.9.2 Successfully installed merb-more-0.9.2 Successfully installed merb-0.9.2 Successfully installed gem_plugin-0.2.3 Successfully installed mongrel-1.1.4-java 22 gems installed Installing ri documentation for json_pure-1.1.2... Installing ri documentation for rack-0.3.0... Installing ri documentation for hpricot-0.6-java... Installing ri documentation for mime-types-1.15... Installing ri documentation for merb-core-0.9.2... Installing ri documentation for merb-action-args-0.9.2... Installing ri documentation for merb-assets-0.9.2... Installing ri documentation for activesupport-2.0.2... Installing ri documentation for rubigen-1.2.4... Installing ri documentation for merb-gen-0.9.2... Installing ri documentation for merb-haml-0.9.2... Installing ri documentation for merb-builder-0.9.2... Installing ri documentation for mailfactory-1.2.3... Installing ri documentation for merb-mailer-0.9.2... Installing ri documentation for merb-parts-0.9.2... Installing ri documentation for merb-cache-0.9.2... Installing ri documentation for gem_plugin-0.2.3... Installing ri documentation for mongrel-1.1.4-java... Installing RDoc documentation for json_pure-1.1.2... Installing RDoc documentation for rack-0.3.0... Installing RDoc documentation for hpricot-0.6-java... Installing RDoc documentation for mime-types-1.15... Installing RDoc documentation for merb-core-0.9.2... Installing RDoc documentation for merb-action-args-0.9.2... Installing RDoc documentation for merb-assets-0.9.2... Installing RDoc documentation for activesupport-2.0.2... Installing RDoc documentation for rubigen-1.2.4... Installing RDoc documentation for merb-gen-0.9.2... Installing RDoc documentation for merb-haml-0.9.2... Installing RDoc documentation for merb-builder-0.9.2... Installing RDoc documentation for mailfactory-1.2.3... Installing RDoc documentation for merb-mailer-0.9.2... Installing RDoc documentation for merb-parts-0.9.2... Installing RDoc documentation for merb-cache-0.9.2... Installing RDoc documentation for gem_plugin-0.2.3... Installing RDoc documentation for mongrel-1.1.4-java... |
| Macintosh-187:jruby-1.1RC3
arungupta$ cd samples/ Macintosh-187:samples arungupta$ mkdir merb Macintosh-187:samples arungupta$ cd merb/ Macintosh-187:merb arungupta$ ../../bin/jruby -S merb-gen app hello RubiGen::Scripts::Generate create app create autotest create config create public create spec create app/controllers create app/helpers create app/views create app/views/exceptions create app/views/layout create config/environments create public/images create public/stylesheets create autotest/discover.rb create autotest/merb.rb create autotest/merb_rspec.rb create config/rack.rb create config/router.rb create config/init.rb create public/merb.fcgi create spec/spec.opts create spec/spec_helper.rb create app/controllers/application.rb create app/controllers/exceptions.rb create app/helpers/global_helpers.rb create app/views/exceptions/internal_server_error.html.erb create app/views/exceptions/not_acceptable.html.erb create app/views/exceptions/not_found.html.erb create app/views/layout/application.html.erb create config/environments/development.rb create config/environments/production.rb create config/environments/rake.rb create config/environments/test.rb create public/images/merb.jpg create public/stylesheets/master.css create /Rakefile |
| Macintosh-187:hello
arungupta$ ls -la total 8 drwxr-xr-x 8 arungupta arungupta 272 Apr 1 22:20 . drwxr-xr-x 3 arungupta arungupta 102 Apr 1 22:20 .. -rw-r--r-- 1 arungupta arungupta 3334 Apr 1 22:20 Rakefile drwxr-xr-x 5 arungupta arungupta 170 Apr 1 22:20 app drwxr-xr-x 5 arungupta arungupta 170 Apr 1 22:20 autotest drwxr-xr-x 6 arungupta arungupta 204 Apr 1 22:20 config drwxr-xr-x 5 arungupta arungupta 170 Apr 1 22:20 public drwxr-xr-x 4 arungupta arungupta 136 Apr 1 22:20 spec |
| Macintosh-187:hello
arungupta$ ../../../bin/jruby
-S merb JRuby limited openssl loaded. gem install jruby-openssl for full support. http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL ~ Loaded DEVELOPMENT Environment... ~ Compiling routes... ~ Using 'share-nothing' cookie sessions (4kb limit per client) ~ Using Mongrel adapter |

Posted by Arun Gupta in web2.0 | Comments[6]
|
|
|
|
|
Thursday January 24, 2008
RESTful representation of "sakila" using GlassFish and NetBeans IDE
"sakila" is the sample database shipped with MySQL (pronounced as my ess-kew-ell). In the context of Sun Microsystems announcing the agreement to acquire MySQL, I'd like to dedicate this entry to show how this sample database can be exposed as a RESTful Web service endpoint and deployed on GlassFish using Jersey Tooling Plugin (0.4.1 with Jersey 0.4) in NetBeans IDE.
Lets get started!
sakila".mysqld-nt --user root
--console' in bin directory on Windows or './bin/mysqld_safe'
from MySQL directory on Unix flavors.sakila".
Choose "GlassFish v2" as the "Server:".Services" tab of NetBeans IDE, expand "Drivers" and add
MySQL
Connector/J driver if it does not exist already.
New", "Entity Classes from
Database...". In "Data Source", select "New Data Source..." and specify the
values as shown below:
film" in "Available Tables" and click on "Add >" as shown
below:
Next >".Create Persistence Unit..." and take all the defaults as shown
below:
Create".sakila" as shown below:
Finish".Configuration Files"
and open "persistence.xml". Specify the username and password
by replacing <properties/> with the following fragment:<properties>
<property name="toplink.jdbc.user" value="root"/>
<property name="toplink.jdbc.password" value=""/>
</properties>Tools", "Plugins", "Available Plugins", "RESTful
Web Services" and then click on "Install". This installs the
Jersey Tooling
Plugin in the IDE.New", "RESTful Web Services from
Entity Classes...".Add >>", take all other defaults as shown
below:
Next >", take all defaults and then "Finish".Test RESTful Web Services".
The following web page is presented in the browser:
films" and then on "Test" as shown
below:
Test" button or the URL "http://localhost:8080/sakila/resources/films/"
shows the RESTful representation of the "Film" table. The
default representation shows 10 records from the table where each entry
returns the "id" of the film and a reference to the detailed
entry.http://localhost:8080/sakila/resources/films/?max=40".
Additional fields from the table can be displayed by adding getter methods
to "converter.FilmRefConverter" class such as:@XmlElement
public String getTitle() {
return entity.getTitle();
}

Here are few more ideas for you to explore:
A JRuby-on-Rails application using MySQL is explained here. TOTD #9 explains how JDBC connection pooling in GlassFish can be used for a JRuby-on-Rails application using MySQL.
The key message here is MySQL can be very easily used with GlassFish and NetBeans IDE makes it possible! Once MySQL becomes part of Sun, this integration is going to be much more seamless for the betterment of community.
All the entries on this blog using MySQL can be found here. And last but not the least, Welcome aboard MySQL!
A NetBeans project with all the source code can be downloaded from here. You will still need to setup the database connection and need to make sure the correct version of Jersey plug-in as well :)
Technorati: glassfish netbeans jersey mysql sakila jpa jmaki rubyonrails
Posted by Arun Gupta in webservices | Comments[28]
|
|
|
|
|
Monday December 31, 2007
Screencast #Web11: Travel Map - Another Real-life app using jMaki & Jersey
In my role of Technology Evangelist, I get the opportunity to meet a lot of community (folks like you :) all around the world. In the year 2007, I represented GlassFish (and related technologies - Metro, jMaki and Jersey) at multiple conferences. This blog introduces a new real-life application that plots all the places I visited this year on a jMaki-wrapped Google Map widget. Clicking on the marker shows more information about the event such as dates and the blog entry covering the event.
Play the video below to see how the application looks like.
Here is the architecture of this application:

It consists of a server-side and a client-side applications - developed as NetBeans projects.
Both the server-side and client-side are deployed on GlassFish.
This is only a sample application so optimizations are certainly possible and corner cases (such as no blog entry for a particular visit) are not accounted for. But the application still demonstrates the concept. The fully built application looks like as shown below:

My first presentation in this role was Sun Tech Days Atlanta (highlighted in the image). This application generates an interactive Google Map so feel free to zoom in/out and click
And one last thing before we build the application. Here is
the list of technologies and associated concepts used to build this
application:
And finally, lets build this application. Lets build the
RESTful Web service endpoint project first.
jdbc:derby://localhost:1527/sample
[app on APP]" (right-click and select "Connect...").Execute
Command..." and create a table by giving the following
command:create table EVENTS (id int GENERATED ALWAYS AS
IDENTITY,
event_name varchar(255),
dates varchar(20),
venue varchar(255),
blogs varchar(2056),
PRIMARY KEY (id))Execute
Command..." to add data to the table by giving the
following command:
INSERT INTO EVENTS (event_name, dates, venue,
blogs) VALUES('SunTech Days - Atlanta', 'Jan 16 - Jan 17',
'Cobb Galleria Center, Two
Galleria Parkway, Atlanta, Georgia, 30339',
'http://blogs.sun.com/arungupta/entry/wsit_and_web_2_0');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('jMaki Day', '
Feb 23', '4150
Network Circle Santa Clara, CA 95054',
'http://blogs.sun.com/arungupta/entry/sun_internal_jmaki_day_review');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Ajax World - New
York', 'Mar 19 - Mar 21', 'The
Roosevelt Hotel, 45 E 45th St, New York, NY 10017',
'http://blogs.sun.com/arungupta/entry/sun_ajax_world');
INSERT
INTO
EVENTS (event_name, dates, venue, blogs) VALUES('The Server Side Java
Symposium - Las Vegas', 'Mar 22', '3355 Las Vegas Blvd. South
Las
Vegas, NV 89109',
'http://blogs.sun.com/arungupta/entry/sun_the_server_side_java,
http://blogs.sun.com/arungupta/entry/tango_at_venetian_las_vegas');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('JavaOne - San
Francisco', 'May 7 - May 11', 'Moscone
Center, 747 Howard Street, San Francisco, CA 94103',
'http://blogs.sun.com/arungupta/entry/slides_for_ts_4865,
http://blogs.sun.com/arungupta/entry/javaone_2007_day_1_finished,
http://blogs.sun.com/arungupta/entry/javaone_2007_day_1,
http://blogs.sun.com/arungupta/entry/javascript_everywhere_javaone_2007_demo,
http://blogs.sun.com/arungupta/entry/excel_using_wsit_javaone_2007,
http://blogs.sun.com/arungupta/entry/ts_4865_takes_two_to,
http://blogs.sun.com/arungupta/entry/communityone_glassfish_day_report,
http://blogs.sun.com/arungupta/entry/javaone_2007_backstage,
http://blogs.sun.com/arungupta/entry/javaone_2007_is_almost_here,
http://blogs.sun.com/arungupta/entry/my_javaone_2007_picks');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Rails Conf -
Portland', 'May 17 - May 20', '777 NE MLK, Jr. Blvd. Portland,
OR
97232',
'http://blogs.sun.com/arungupta/entry/tim_bray_s_keynote_session,
http://blogs.sun.com/arungupta/entry/sun_rails_conf_2007_keep,
http://blogs.sun.com/arungupta/entry/getting_started_with_jruby_tutorial,
http://blogs.sun.com/arungupta/entry/jmaki_netbeans_and_glassfish_in');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Google Developer
Day - San Jose', 'May 31', '150 W San Carlos St San Jose, CA 95113',
'http://blogs.sun.com/arungupta/entry/google_developer_day_report');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Mashup Camp -
Mountain View', 'Jul 18 - Jul 19', 'Computer History Museum, 1401 N
Shoreline Blvd., Mountain View, CA 94043',
'http://blogs.sun.com/arungupta/entry/jmaki_at_mashup_camp_report,
http://blogs.sun.com/arungupta/entry/jmaki_mashup_camp');
INSERT INTO EVENTS (event_name, dates, venue, blogs) VALUES('OSCON -
Portland',
'Jul 23 - Jul 27', '777 NE MLK, Jr. Blvd. Portland, OR 97232',
'http://blogs.sun.com/arungupta/entry/jmaki_oscon');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('JRuby Hack Day -
San Francisco', 'Aug 8', '1201 8th St, San Francisco, CA 94107',
'http://blogs.sun.com/arungupta/entry/jruby_on_rails_hackday_report,
http://blogs.sun.com/arungupta/entry/learn_jruby_on_rails_free');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Rich Web
Experience - San Jose', 'Sep 6 - Sep 8', '170 S Market St, San
Jose,
CA 95113',
'http://blogs.sun.com/arungupta/entry/the_rich_web_experience_2007,
http://blogs.sun.com/arungupta/entry/jmaki_javafx_the_rich_web');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Rails Conf Europe
- Berlin', 'Sep 17 - Sep 19', 'Maritim Pro Arte,
Friedrichstrasse 151,
10117 Berlin',
'http://blogs.sun.com/arungupta/entry/rails_conf_europe_2007_day2,
http://blogs.sun.com/arungupta/entry/rails_conf_europe_2007_day1,
http://blogs.sun.com/arungupta/entry/rails_conf_europe_2007_day,
http://blogs.sun.com/arungupta/entry/jmaki_netbeans_and_glassfish_in1');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Sun Tech Days -
Rome', 'Sep 24 - Sep 25', 'Meliá Roma Aurelia Antica, Vía
Aldobrandeschi, 223
Rome ITALY 00163',
'http://blogs.sun.com/arungupta/entry/netbeans_day_rome_2007,
http://blogs.sun.com/arungupta/entry/travel_tips_to_rome,
http://blogs.sun.com/arungupta/entry/glassfish_metro_jersey_and_jmaki');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Sun Tech Days -
Milan', 'Sep 26 - Sep 28', 'ATA Hotel Quark - Via Lampedusa 11/a 20141
Milano, Italia',
'http://blogs.sun.com/arungupta/entry/glassfish_day_milan_2007');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Mid West Java
Tech Days - Minneapolis', 'Oct 16', 'University of St Thomas,
MPL 201,
1000 LaSalle Avenue,
Minneapolis, MN 55403-2005',
'http://blogs.sun.com/arungupta/entry/mid_west_java_tech_days,
http://blogs.sun.com/arungupta/entry/metro_and_jmaki_in_minneapolis');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Mid West Java
Tech Days
- Chicago', 'Oct 18', 'Donald E Stephens Convention Center, 9301, W
Bryn Mawr Ave,
Rosemont IL 60018',
'http://blogs.sun.com/arungupta/entry/mid_west_java_tech_days1,
http://blogs.sun.com/arungupta/entry/crowne_plaza_chicago_o_hare,
http://blogs.sun.com/arungupta/entry/metro_and_jmaki_in_minneapolis');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Silicon Valley
Code Camp
- Los Altos', 'Oct 27', 'Foothill College, Los Altos, CA',
'http://blogs.sun.com/arungupta/entry/silicon_valley_code_camp_trip,
http://blogs.sun.com/arungupta/entry/metro_jmaki_silicon_valley_code');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('Sun Tech Days -
Beijing', 'Nov 1 - Nov 3', 'Beijing International Convention
Center,
No.8
Beichendong Road Chaoyang District, Beijing',
'http://blogs.sun.com/arungupta/entry/glassfish_day_beijing_2007_by,
http://blogs.sun.com/arungupta/entry/wangfujing_street_authentic_china_in,
http://blogs.sun.com/arungupta/entry/sun_tech_days_beijing_talent,
http://blogs.sun.com/arungupta/entry/sun_tech_days_beijing_day,
http://blogs.sun.com/arungupta/entry/travel_tips_to_beijing,
http://blogs.sun.com/arungupta/entry/glassfish_day_beijing');
INSERT INTO EVENTS (event_name, dates, venue, blogs) VALUES('Partner
Preso
- Toronto', 'Nov 21', 'Toronto City Center',
'http://blogs.sun.com/arungupta/entry/metro_jmaki_jruby_glassfish_q');
INSERT INTO EVENTS (event_name, dates, venue, blogs) VALUES('Partner
Preso
- Montreal', 'Nov 21', 'Montreal City Center',
'http://blogs.sun.com/arungupta/entry/metro_jmaki_jruby_glassfish_q');
INSERT INTO EVENTS (event_name, dates, venue, blogs) VALUES('GlassFish
- Delhi University',
'Dec 3', 'New Delhi',
'http://blogs.sun.com/arungupta/entry/glassfish_delhi_university');
INSERT
INTO EVENTS (event_name, dates, venue, blogs) VALUES('FOSS.IN -
Bangalore', 'Dec 4', 'India Institute of Science, Bangalore',
'http://blogs.sun.com/arungupta/entry/packaging_java_apps_for_ubuntu,
http://blogs.sun.com/arungupta/entry/foss_in_schedules_now_available,
http://blogs.sun.com/arungupta/entry/glassfish_foss_in_2007');
INSERT INTO EVENTS (event_name, dates, venue, blogs) VALUES('Partner
Preso
- Bangalore', 'Dec 4', 'Bangalore',
'http://blogs.sun.com/arungupta/entry/glassfish_bangalore_chennai_and_pune');
INSERT INTO EVENTS (event_name, dates, venue, blogs) VALUES('Partner
Preso
- Chennai', 'Dec 5', 'Chennai',
'http://blogs.sun.com/arungupta/entry/glassfish_bangalore_chennai_and_pune');
INSERT INTO EVENTS (event_name, dates, venue, blogs) VALUES('Partner
Preso
- Pune', 'Dec 6', 'Pune',
'http://blogs.sun.com/arungupta/entry/glassfish_bangalore_chennai_and_pune');
INSERT INTO EVENTS (event_name, dates,
venue, blogs) VALUES('Partner
Preso
- San Francisco', 'Dec 17', 'San Francisco',
'http://blogs.sun.com/arungupta/');VALUES
clause to match accordingly.WebApplication3", package name is "events" and the table name to
generate Entity classes is EVENTS. Take everything else as the defaults.events
package as:
@javax.xml.bind.annotation.XmlRootElement
public class EventsList {
@javax.xml.bind.annotation.XmlElement
protected java.util.List<Events> events;
public EventsList() {
if (events == null)
events = new
java.util.ArrayList<Events>();
}
public void add(Events name) {
events.add(name);
}
public java.util.List<Events> getValue() {
return events;
}
}service.EventsResource,
change the method associated with GET to:public EventsList get() {
EventsList eventsList = new EventsList();
List<Events> list =
PersistenceService.getInstance().createQuery("SELECT e FROM Events
e").getResultList();
for (Events e : list) {
eventsList.add(e);
}
return eventsList;
}
http://localhost:8080/WebApplication3/resources/events"
now return a complete RESTful representation of all the rows from the
database table EVENTS. Ajax
Framework" and choose the "Standard"
layout for "index.jsp". Lets say the
project name is "WebApplication4".id="mymap" attribute to the
Google Map widget. The updated widget looks like as shown below:<a:widget name="google.map" id="mymap"
args="{ centerLat : 37.4041960114344,
centerLon : -122.008194923401 }" />
id="mymap" will allow the Map widget to be accessed by
name later.args="{label:'Plot Events'}"
attribute to thes Yahoo button widget. The updated widget looks like as
shown below:<a:widget name="yahoo.button" args="{label:'Plot Events'}"/>glue,js, add the following
code to *onClick subscribe method:var url = jmaki.xhp + "?id=events";
var _map = jmaki.getWidget("mymap").map;
_map.setZoom(2);
_map.clearOverlays();
_map.enableInfoWindow();
jmaki.doAjax({method: "GET",
url: url,
callback: function(_req)
{
var xmlobject = (new DOMParser()).parseFromString(_req.responseText,
"text/xml");
var root = xmlobject.getElementsByTagName('eventsList')[0];
var events = root.getElementsByTagName('events');
for (var i = 0 ; i < events.length ; i++) {
var event = events[i];
var eventName =
event.getElementsByTagName('eventName')[0].firstChild.nodeValue;
var venue = event.getElementsByTagName('venue')[0].firstChild.nodeValue;
var blogs = event.getElementsByTagName('blogs')[0].firstChild.nodeValue;
var dates = event.getElementsByTagName('dates')[0].firstChild.nodeValue;
var
id = event.getElementsByTagName('id')[0].firstChild.nodeValue;
var encodedLocation = encodeURIComponent("location=" + venue);
var url = jmaki.xhp + "?id=yahoogeocoder&urlparams=" +
encodedLocation;
jmaki.myHandler(url, eventName, blogs, dates, id, _map);
}
}
});*onClick
subscribe method:// "Function closure" used from
http://econym.googlepages.com/basic1.htm
// Creates local copy of "marker" and "html" variables to be preserved
for later use
function createMarker(point,html) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click",
function() {
marker.openInfoWindowHtml(html);
});
return marker;
};
// Function closure that preserves "eventName", "blogs", "dates and "id"
// Gets the latitude/longitude from Yahoo Geocoding service and plots
them on the map
// Also creates meaningful markers
jmaki.myHandler = function(_url, eventName, blogs, dates, id, _map) {
jmaki.doAjax({url: _url,
callback : function(req) {
if (req.responseText.length > 0) {
jmaki.log("name: " + eventName);
var response = eval("(" + req.responseText + ")");
var coordinates = response.coordinates;
jmaki.publish("/jmaki/plotmap", coordinates);
jmaki.log("plotting " + eventName);
var latlng = new GLatLng(coordinates[0].latitude,
coordinates[0].longitude);
var blogHtml = "";
b = blogs.split(', ');
for (i=0; i<b.length; i++) {
blogHtml += '<a href="' + b[i] + '">' + (i+1) +
'</a>';
if (i<b.length-1)
blogHtml += ", ";
}
var txt = '<table>' +
'<tr><td>#' + id + ": " + eventName +
'</td></tr>' +
'<tr>Dates: ' + dates + ',
2007</td></tr>' +
'<tr><td>Blogs: ' + blogHtml +
'</td></tr>' +
'</table>';
var marker = createMarker(latlng, txt);
_map.addOverlay(marker);
marker.openInfoWindowHtml(txt);
} else {
jmaki.log("Failed to get coordinates for " + location );
}
}
});
};,
{"id": "events",
"url":"http://localhost:8080/WebApplication3/resources/events/"
}WebApplication3 is the project where RESTful Web service endpoint is hosted.<script type="text/javascript">
in index.jsp can be generated as <script
type="text/javascript;
e4x=1">.Technorati: screencast conf jmaki jersey netbeans glassfish jpa javascript googlemaps restful web2.0 jmakimashups
Posted by Arun Gupta in web2.0 | Comments[9]
|
|
|
|
|
Wednesday November 07, 2007
Screencast #Web10: CRUD using jMaki and JPA
![]() |
This screencast shows how to create a simple
jMaki application, using
NetBeans IDE, that performs
some of the
CRUD operations on a Data Table widget. It uses Java Persistence API
(JPA) to connect to the database and the application is deployed on
GlassFish. The rest of the CRUD
operations can be easily built using the same methodology. The steps followed in this screencast are also described in detail. Enjoy it here! |
Technorati: screencast jmaki netbeans glassfish jpa database crud
Posted by Arun Gupta in web2.0 | Comments[3]
|
|
|
|
|
Wednesday October 31, 2007
TOTD #15: Delete/Update Row from Database using jMaki Data Table
A Previous Entry explained how a Data Table widget can be populated from a database using Java Persistence API (JPA). This TOTD extends that entry and explains how a selected row from the Data Table can be deleted from the database. This entry is created based upon a requirement from Dave Briccetti at Silicon Valley Code Camp 2007 last weekend.
The first part of the entry is also a re-write of using NetBeans 6 and the latest jMaki NetBeans plugin.
Web Application'
project and name it as 'jmaki-database'.
Next' button, add 'jMaki Ajax Framework'
and choose 'Standard' layout as shown below:
Finish' button.Runtime' tab, expand Databases, connect
to the default database (with the URL 'jdbc:derby://localhost:1527/sample
[app on APP]'). Specify the username 'app' and password
'app'.Execute Command...'
and issue the command:create table BOOKS (title varchar(255),
author varchar(255),
isbn varchar(255),
description varchar(255),
PRIMARY KEY (isbn))INSERT INTO BOOKS VALUES('Galloway Book of Running', 'Jeff Galloway',
'ABC001', 'The best book on running');
INSERT INTO BOOKS VALUES('The Complete Book of Running', 'James Fixx',
'ABC002', 'Oldest book of running');
INSERT INTO BOOKS VALUES('The Runners Handbook', 'Bob Glover', 'ABC003',
'Bestselling Guide for Beginning and Intermediate Runners');
INSERT INTO BOOKS VALUES('Daniel Running Formula', 'Jack Tupper Daniels',
'ABC004', 'Proven programs 800m to Marathon');
INSERT INTO BOOKS VALUES('Chi Running', 'Danny Drever', 'ABC005',
'Revolutionary approach to effortless, injury-free running');
INSERT INTO BOOKS VALUES('Running for Mortals', 'John Bingham', 'ABC006', 'A
common sense plan for changing your life through running');
INSERT INTO BOOKS VALUES('Marathoning for Mortals', 'John Bingham',
'ABC007', 'Regular person guide to marathon');
INSERT INTO BOOKS VALUES('Marathon', 'Hal Higdon', 'ABC008', 'The Ultimate
Training Guide');jmaki-database',
right-click and select 'New' and choose 'Entity
Classes From Database...'.jdbc/sample' as 'Data Source'.BOOKS' in 'Available Tables' and
click on 'Add' and enter the values as shown below:
Next'.server' as shown below:
Create Persistence Unit...' to create the
persistence unit and enter the values as shown below:
Create'.and click on 'Finish'.
@NamedQuery(name = "Books.findAll", query = "SELECT b FROM Books b")Configuration Files' and open
'persistence.xml'.Add Class' button and choose 'server.Books'
class and click 'OK'. This will ensure that the generated
entity class is explicitly recognized by the EntityManagerFactory.Web Pages', select 'New'
and then 'JSP...'. Give the name as 'data' as
shown:
Finish'.data.jsp' with the
following:<%@ page import="java.util.*" %>
<%@ page import="server.Books" %>
<%@ page import="javax.persistence.*" %>
<%
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("jmaki-databasePU");
EntityManager em = emf.createEntityManager();
List<Books> list = em.createNamedQuery("Books.findAll").getResultList();
out.println("{columns : [" +
"{ label : 'Title', id : 'title'}," +
"{ label :'Author', id : 'author'}," +
"{ label :'ISBN', id : 'isbn'}," +
"{ label :'Description', id : 'description'}" +
"],");
out.println("rows: [");
for (int i=0; i<list.size(); i++) {
Books b = list.get(i);
out.print("{ id: '" + b.getIsbn() + "', " +
"title: '" + b.getTitle() + "'," +
"author: '" + b.getAuthor() + "'," +
"isbn: '" + b.getIsbn() + "'," +
"description: '" + b.getDescription()
+ "'}");
if (i < list.size()-1)
out.println(",");
else
out.println();
}
out.println("] }");
%>index.jsp', drag-and-drop a 'Yahoo Data Table' widget from the jMaki Palette in the 'Main
Content Area'.<a:widget name="yahoo.dataTable"
value="{columns :
[
{ label : 'Title', id : 'title'},
{ label :'Author', id : 'author'},
{ label : 'ISBN', id : 'isbn'},
{ label : 'Description', id : 'description'}
],
rows :
[
{ title : 'Book Title 1', author : 'Author 1', isbn: '4412', description
: 'A Some long description'},
{ id : 'bar', title : 'Book Title 2', author : 'Author 2', isbn :
'4412', description : 'A Some long description'}
]
}" />
<a:widget name="yahoo.dataTable" service="data.jsp" />
The 'service' attribute tells jMaki runtime to retrieve the data
for DataTable widget from 'data.jsp' instead of the using static
data.
Source Packages', 'server',
edit 'Books.java' and add the following NamedQuery:@NamedQuery(name = "Books.deleteByIsbn", query = "DELETE FROM Books b
WHERE b.isbn = :isbn")Web Pages', select 'New'
and then 'JSP...'. Give the name as shown:
Finish'.delete.jsp' with the
following:<%@ page import="javax.persistence.*" %>
<%
String isbn = request.getParameter("isbn");
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("jmaki-databasePU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.createNamedQuery("Books.deleteByIsbn").
setParameter("isbn", isbn).
executeUpdate();
em.getTransaction().commit();
%>Web pages' and edit 'glue.js' to add
the following fragment in '*onSelect' subscribe method:jmaki.doAjax({method: "POST",
url: "delete.jsp?isbn=" + encodeURIComponent(args.value.isbn),
callback: function(_req) {
jmaki.publish('/jmaki/table/removeRow', { targetId:
args.value.isbn });
}
});index.jsp' as:<a:widget name="yahoo.dataTable" service="data.jsp" subscribe="/jmaki/table"/>That's it! Now clicking on any row of the table will delete that particular row from the database and also from the table. If jMaki Debugger Console is enabled, then the messages are shown as below:

Using the similar steps described in bullet #9-13, a row can be updated in the database.
Please leave suggestions on other TOTD that you'd like to see. A complete archive is available here.
Technorati: totd jmaki glassfish netbeans jpa database
Posted by Arun Gupta in web2.0 | Comments[44]
|
|
|
|
|
Tuesday September 11, 2007
Sun Microsystems kicks off 2007-2008 Tech Days and marks the 10th anniversary of the developer event. This blog celebrates the decade by announcing "Sun Tech Days Event Map" - a real-life RIA created using jMaki. It allows you to choose the date on a web page using a rich calendar widget, shows the city where Sun Tech Days event is happening during that month and then shows that city location in a map. Play the video below to see how the application looks like:
This application shows several concepts of jMaki:
This application is built using NetBeans IDE 5.5.1, jMaki 0.9.7.3 and deployed on GlassFish RC4. Let's get started.
Web" in "Categories"
and "Web application" in "Projects". Click on
"Next >".SunTechDays" and choose
GlassFish as the "Server" and take all other values
default. Click on "Next >".jMaki Ajax Framework" and choose "Two
Fixed Right Sidebars" layout.Finish".index.jsp"Top Right Column" by dragging-and-dropping "Dojo
Combobox".Right Column" with "Yahoo Calendar".Left Column" with a "Google Map".Runtime" tab, expand "Databases",
right-select the node with the value "jdbc:derby://localhost:1527/sample"
and select "Connect".app".Execute Command...".
Create the table using the following SQLcreate table TECHDAYS_SCHEDULE (startDate date,
endDate date,
location varchar(255),
PRIMARY KEY (startDate, endDate))INSERT INTO TECHDAYS_SCHEDULE VALUES ('9/11/2007', '9/12/2007',
'Boston, United States');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('9/24/2007', '9/25/2007', 'Rome,
Italy');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('9/26/2007', '9/28/2007', 'Milan,
Italy');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('10/19/2007', '10/19/2007',
'Taipei, Taiwan');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('10/23/2007', '10/25/2007',
'Shanghai, China');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('11/1/2007', '11/3/2007',
'Beijing, China');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('11/6/2007', '11/8/2007', 'Tokyo,
Japan');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('12/3/2007', '12/5/2007',
'Frankfurt, Germany');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('1/9/2008', '1/10/2008', 'Atlanta,
United States');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('2/27/2008', '2/29/2008',
'Bangalore, India');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('3/4/2008', '3/6/2008', 'Sydney,
Australia');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('3/11/2008', '3/13/2008',
'Johannesburg, South Africa');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('4/1/2008', '4/1/2008', 'St
Petersburg, Russia');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('4/1/2008', '5/1/2008', 'Manila,
Philippines');
INSERT INTO TECHDAYS_SCHEDULE VALUES ('5/21/2008', '5/23/2008', 'Mexico
City, Mexico');New",
"Entity Classes from Database...".New Entity Classes from Database" dialog
window, choose "Data Source" and select "jdbc/sample"
value.Available Tables".
Select "TECHDAYS_SCHEDULE" and click on "Add >".Next >".suntech".Create Persistence Unit...".Create Persistence Unit..." dialog window take all
the default values and click on "Create".Finish".Configuration Files", open "persistence.xml",
click on "Add Class", click "Cancel", click on
"Add Class" again and now select "suntech.TechdaysSchedule"
and click on "OK".Source Packages", "suntech" node
and open "TechdaysSchedule.java".@NamedQuery(name = "TechdaysSchedule.findByMonth", query = "SELECT
t FROM TechdaysSchedule t WHERE t.techdaysSchedulePK.startdate >= :firstdate
and t.techdaysSchedulePK.enddate <= :lastdate"),Web Pages", open "glue.js" and add
the following code at the end of the file:jmaki.subscribe("/yahoo/calendar/onSelect",
function(args) {
var newDate;
if (typeof args.value == "undefined") {
var tempDate = new Date();
newDate = (tempDate.getMonth()+1) + "/" + tempDate.getDate()
+ "/" + tempDate.getFullYear();
} else {
var str = "" + args.value;
newDate = str.split(" ")[1] + "/" + str.split(" ")[2] + "/" +
str.split(" ")[3];
}
jmaki.doAjax({method: "POST",
url: "data.jsp?date=" +
encodeURIComponent(newDate),
callback: function(_req) {
var tmp = _req.responseText;
var obj = eval("(" + tmp + ")");
jmaki.log("tmp "+ obj);
jmaki.publish('/dojo/combobox/setValues',
obj);
// handle any errors
}
});
});
jmaki.subscribe("/dojo/combobox/onSelect", function(item) {
var location = item.value.split(',')[0] + ", " + item.value.split(',')[1];
var start = item.value.indexOf('(');
var stop = item.value.lastIndexOf(')');
var encodedLocation = encodeURIComponent("location=" + location);
// jmaki.xhp is provided as part of jmaki and maps to the XMLHttpProxy
var url = jmaki.xhp + "?id=yahoogeocoder&urlparams=" + encodedLocation;
jmaki.doAjax({url: url, callback : function(req) {
if (req.responseText.length > 0) {
// convert the response to an object
var response = eval("(" + req.responseText +
")");
var coordinates = response.coordinates;
v = {results:coordinates};
jmaki.publish("/jmaki/plotmap", coordinates);
} else {
jmaki.log("Failed to get coordinates for " +
location );
}
}
});
});<a:widget name="dojo.combobox" service="data.jsp"/>New" and then "JSP..."
using the name "data". Notice, the IDE automatically picks
up the file extension.<%@ page import="java.util.*" %>
<%@ page import="suntech.*" %>
<%@ page import="javax.persistence.*" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%
String dateParam = request.getParameter("date");
Date date = null;
if (dateParam == null || "".equals(dateParam))
date = Calendar.getInstance().getTime();
else {
SimpleDateFormat sdf = new SimpleDateFormat("MMM/dd/yyyy");
date = sdf.parse(dateParam);
}
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("SunTechDaysPU");
EntityManager em = emf.createEntityManager();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.DATE, 1);
Date firstDateOfMonth = cal.getTime();
cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
Date lastDateOfMonth = cal.getTime();
List<TechdaysSchedule> list =
em.createNamedQuery("TechdaysSchedule.findByMonth").
setParameter("firstdate",
firstDateOfMonth).
setParameter("lastdate",
lastDateOfMonth).
getResultList();
out.println("[");
boolean first = true;
int count = 0;
SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy");
for (TechdaysSchedule t : list) {
StringBuffer buf = new StringBuffer();
buf.append(sdf.format(t.getTechdaysSchedulePK().getStartdate()));
buf.append(" - ");
buf.append(sdf.format(t.getTechdaysSchedulePK().getEnddate()));
String city = t.getLocation() + ", (" + buf.toString() + ")";
out.println("{");
out.println("name: \"" + t.getLocation() + "\", ");
out.println("label: \"" + city + "\", ");
out.println("value: \"" + city + "\"");
if (first) {
out.println(", selected: " + true);
first = false;
}
out.println("}");
if (count++ < list.size()-1)
out.println(",");
}
out.println("]");
%>And that's it!
Carla and I conceived this application together and Greg and helped with gluing the widgets.
Here are some potential fun improvements:
Technorati: jmaki netbeans glassfish suntechdays jpa screencast web2.0
Posted by Arun Gupta in web2.0 | Comments[14]
|
|
|
|
|
Tuesday August 28, 2007
Dynamic Data in jMaki Widgets Using JPA - Updated for formal data models
Doris pointed out that one of my earlier post is not working any more. That entry explained the steps to create a Web application, deployed on GlassFish V2, and contained a jMaki-wrapped Yahoo Data Table widget pulling data from JavaDB using the JPA.
The main reason for this is because jMaki data models have evolved since I wrote the original entry and are now formalized. Here is the delta from the previous entry to make it working:
<%@ page import="java.util.*" %>
<%@ page import="server.Company" %>
<%@ page import="javax.persistence.*" %>
<%
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("jmaki-jpaPU");
EntityManager em = emf.createEntityManager();
List<Company> list = em.createQuery("select c from Company
c").getResultList();
out.println("{columns : [" +
"{ label : 'Company Name', id : 'companyName'}," +
"{ label :'Price', id : 'price'}," +
"{ label :'Change', id : 'change'}," +
"{ label :'% Change', id : 'pctChange'}," +
"{ label :'Last Updated', id : 'lastUpdated'}" +
"],");
out.println("rows: [");
for (int i=0; i<list.size(); i++) {
Company c = list.get(i);
out.print("{ companyName: '" + c.getCompanyname() + "'," +
"price: '" + c.getPrice() + "'," +
"change: '" + c.getChange() + "'," +
"pctChange: '" + c.getPercentchange() + "'," +
"lastUpdated: '" + c.getLastupdated() + "'}");
if (i < list.size()-1)
out.println(",");
else
out.println();
}
out.println("] }");
%> <a:widget name="yahoo.dataTable"
service="data.jsp" />With jMaki 0.9.7.1, here is a snapshot of the updated web page:

And the updated NetBeans project is available here.
Technorati: jmaki glassfish jpa netbeans
Posted by Arun Gupta in web2.0 | Comments[19]
|
|
|
|
|
Today's Page Hits: 2266
Total # blog entries: 994
| « November 2009 | ||||||
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
1 | 2 | 4 | 6 | 7 | ||
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | |||||
| Today | ||||||