Thursday Jan 17, 2008

JSF Component Authoring Made Easy

Frustrated with the complexities of writing a JavaServer Faces component? With the help of the JSFTemplating and Woodstock projects, you can write a component with only two files.[Read More]

Thursday May 10, 2007

Howto win a Helicopter

How to win a helicopter @ JavaONE

BT had a booth at JavaONE for their Web21C SDK.  The SDK, among other things, allows you to write software that invokes a WebService hosted by BT to place a phone call between 2 parties.  You simply need to provide 2 phone numbers and BT calls both parties and connects the two.  They provide a limited amount of usage for free, and for a small fee you can use their service more, here's a link to their pricing.  The Web21C SDK opens up the door to many possibilities, however, that's outside the scope of this blog.

BT was offering a challenge at their booth: Use their SDK to place a phone call and win a remote controlled helicopter.  My son is 5 and would love to crash the helicopter, and it sounded like any easy task for GlassFish + JSFTemplating... so I got to work!

Here's what I had to do:

1) I started with the JSFTemplating demo application. (Note: I used the version from CVS so that I would already have a build environment setup which uses APT.)

2) I added the Web21C jar files to my WEB-INF/lib directory of the demo app.  They gave me a memory stick with these, but I think you can find them here.

3) I had problems w/ some of their jar files because many of them are already part of GlassFish and were not needed.  Also some of the versions may not have been compatible.  I ended up turning off classloader delegation by adding this to my sun-web.xml file:

  <class-loader delegate="false"/>

4) I registered my application.  BT requires you to register your application.  This was a necessary, but the most painful part of the process.  It required me to download the Web21C-Certificate-Tool, patch the JDK with the unlimited strength policy files, run their certificate tool, place the generated file in the WEB-INF/classes directory of the demo app, and create / place a security.properties file in the WEB-INF/classes directory that pointed to the generated file.

5) With the environment finally setup, I was ready to write the app!  I created the following JSFTemplating page:


call.jsf

<sun:page>
<sun:html>
<sun:head />
<sun:body>
<sun:form>
<sun:messageGroup />
<sun:propertySheet>
<sun:propertySheetSection label="Web21 Phone Dialer">
<sun:property>
<sun:textField required="true" label="Call From:" value="#{requestScope.from}" />
</sun:property>
<sun:property>
<sun:textField required="true" label="Call To:" value="#{requestScope.to}" />
</sun:property>
<sun:property>
<sun:button text="Make Call">
<!command
Web21.call(from="#{requestScope.from}", to="#{requestScope.to}");
navigate("calling.jsf");
/>
</sun:button>
</sun:property>
</sun:propertySheetSection>
</sun:propertySheet>
</sun:form>
</sun:body>
</sun:html>
</sun:page>



6) I created the following handler in a new java file called Web21Handlers.java (see above call.jsf page where the button is invoking this handler):

Web21Handlers.java

package org.example.handlers;

import com.sun.jsftemplating.annotation.Handler;
import com.sun.jsftemplating.annotation.HandlerInput;
import com.sun.jsftemplating.annotation.HandlerOutput;
import com.sun.jsftemplating.layout.descriptors.handler.HandlerContext;


/\*\*
\* <p> This class is written to demonstrate how to write a
\* <code>Handler</code>.</p>
\*/
public class Web21CHandlers {

/\*\*
\* <p> This is a handler makes phone calls.</p>
\*
\* @param context The <code>HandlerContext</code>.
\*/
@Handler(id="Web21.call",
input={
@HandlerInput(name="to", type=String.class, required=true),
@HandlerInput(name="from", type=String.class, required=true)
})
public static void calculateResponse(HandlerContext context) {
// Get the input.
String to = (String) context.getInputValue("to");
if (!to.startsWith("tel:+")) {
to = "tel:+" + to;
}
String from = (String) context.getInputValue("from");
if (!from.startsWith("tel:+")) {
from = "tel:+" + from;
}

com.bt.sdk.thirdpartycall.ThirdPartyCall tpc = new com.bt.sdk.thirdpartycall.ThirdPartyCall(to, from);
tpc.startCall();
}
}



7) I compiled the app (just typed "ant" on the command line, the demo application already has the build environment setup), started the server and went to http://localhost:8080/demo/call.jsf where I saw:

Screenshot 

After typing in the 2 phone numbers and clicking the "Make Call" button... the 2 phones rang! 

8) Finally... I showed this to the Web21C people and they gave me a helicopter!

Ken and Senthil 

(I'm in the blue Sun shirt.  You can also see this on flickr.)

That's how to get a helicopter using JSFTemplating + Web21C + GlassFish at JavaONE.


Sunday May 06, 2007

Streaming Content in JSF with JSFTemplating's FileStreamer

 

FileStreamer

I have received questions from several people about how to use the "FileStreamer" feature of JSFTemplating.  So I thought a blog would be the best way to demonstrate how it works. 

FileStreamer provides the ability for the FacesServlet to stream content to the client (i.e. web browser).  If that sounds generic, it is because FileStreamer is very generic.  It allows you to define a ContentSource that is capable of getting content from just about anywhere.  You might choose to get content from a database, retrieve it via a web service, generate it in code, access it from the filesystem or the classpath, or just about anywhere else.  The ContentSource interface allows you to specify the content and information about it so that appropriate http headers will be set, causing the client (browser) to treat it correctly (i.e. Content-type, Content-Disposition, etc.).  In addition to this, FileStreamer works in the context of JSF, meaning you will have access to managed beans or anything you require from your JSF environment.  (NOTE: FileStreamer actually provides a Context which interacts with its environment.  This allows different Context implementations to be provided for different environments; Servlet and JSF Contexts are currently available, see: ServletStreamerContext and FacesStreamerContext).

Lets look at a couple of examples.

Setup

First you have to have your JSFTemplating evironment setup.  Follow these instructions for this. 

Next to configure FileStreamer for JSF, add the following to your web.xml file:

  <context-param>
    <param-name>ContentSources</param-name>
    <param-value>org.example.contentSources.ExampleContentSource,org.example.contentSources.ProxyContentSource</param-value>
  </context-param>
  <servlet-mapping>
    <servlet-name>FacesServlet</servlet-name>
    <url-pattern>/resource/\*</url-pattern>
  </servlet-mapping>

The context-param registers 2 ContentSources.  The source to both of these is checked into JSFTemplating's demo application.  You can browse that source online here.  The servlet-mapping requires a prefix mapping and needs its own dedicated FacesServlet mapping.  "/resource/\*" is the default, however, this can be configured, see RESOURCE_PREFIX for more info.

ExampleContentSource

Let's take a look at the key part of the ExampleContentSource to see how it works.


ExampleContentSource.java:

public InputStream getInputStream(Context ctx) throws IOException {
// See if we already have it.
InputStream in = (InputStream) ctx.getAttribute("inputStream");
if (in == null) {
// Create some content...
in = new ByteArrayInputStream(("<b>Hello! You requested: '"
+ ctx.getAttribute(Context.FILE_PATH) + "'</b>").getBytes());


// Set the extension so it can be mapped to a MIME type
ctx.setAttribute(Context.CONTENT_TYPE, "text/plain");

// Save in case method is called multiple times
ctx.setAttribute("inputStream", in);
}

// Return the InputStream
return in;

The above ContentSource (ExampleContentSource) is very simple, it generates its content from a String (see green text above).  The String is some text with the request path (which is the PATH_INFO of the request, in other words the part of the URL after the "/resource").  Notice I added some HTML tags to show how they're treated.  The red text shows that the Content-type is being explicitly set to "text/plain".  This should cause the browser not to parse any html (so we should see those <b> tags on the screen).

 ExampleContentSource in action

As you can see, this simple ContentSource produces plain text in the browser.  You also see that the URL requires "contentSourceId=example".  "example" comes from the "id" of ExampleContentSource.

ProxyContentSource

Let's take a look at 1 more example ContentSource.  We'll use the same URL, except we'll use the contentSourceId of "proxy" to target our other ContentSource.  Below is the interesting part of the source code for ProxyContentSource.java:

ProxyContentSource.java:

public InputStream getInputStream(Context ctx) throws IOException {
// See if we already have it.
InputStream in = (InputStream) ctx.getAttribute("inputStream");
if (in == null) {
// Get the path...
String path = (String) ctx.getAttribute(Context.FILE_PATH);
while (path.startsWith("/")) {
path = path.substring(1);
}

// Get the URL...
URL url = new URL("http://" + path);

// Set the extension so it can be mapped to a MIME type
int index = path.lastIndexOf('.');
if (index > 0) {
ctx.setAttribute(Context.EXTENSION, path.substring(index + 1));
}

// Open the InputStream
in = url.openStream();

// Save in case method is called multiple times
ctx.setAttribute("inputStream", in);
}

// Return the InputStream
return in;

Again we are creating an InputStream, however, this time we are getting it via a URL.  This time instead of hard-coding the Content-type, we're setting the extension of the file so that it will be mapped to an appropriate Content-type.  Here's the output for the same URL as before (except w/ our "proxy" contentSourceId):

ProxyContentSource in action!

In this example, the content is pulled from java.sun.com from the server (not the client), then streamed to the client.  The appropriate Content-type of "image/gif" was sent to the browser so that it could treat the content correctly.  If you run this example, try other urls and types of media (html, pdf, doc, etc.).

I hope this blog gives you an idea of how FileStreamer functionality is useful.  Please leave a comment and let me know what you think!  Below is one more section describing how to configure FileStreamer in a Servlet environment (doesn't need JSF):

Servlet Setup

  <servlet>
    <servlet-name>servletStreamer</servlet-name>
    <servlet-class>com.sun.jsftemplating.util.fileStreamer.ServletStreamer</servlet-class>
    <init-param>
        <param-name>ContentSources</param-name>
        <param-value>org.example.contentSources.ExampleContentSource,org.example.contentSources.ProxyContentSource</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>servletStreamer</servlet-name>
    <url-pattern>/resource/\*</url-pattern>
  </servlet-mapping>

 

That's it... the rest is the same as above.  You can change the url mapping directly in the web.xml file in this case.  Oh... and yes, you can use the same ContentSources in both environments!

Have Fun!

 

Thursday Feb 15, 2007

Woodstock is here!

 

Woodstock JavaServer Faces Components 

Sun has delivered some great components as part of Sun Java Studio Creator and NetBeans Visual Web Pack.  But if you don't use one of those products, you probably didn't know it.  Well, now you don't have to use these tools to enjoy the rich JavaServer Faces components they provide.  In fact not only are they available outside these products, they are now Open Source!

Project Woodstock is the Java.net project which contains the source code for these components.  Both Creator's and NB VWP components were derived from earlier versions of this code base.  The code is released under the very flexible CDDL license.  These components have been in the making for over 2 years and have gone through several development cycles.  They're stable, full featured, and work seemlessly together sharing a common theme -- they're ready for production!

Let's take a look at what some of these components look like:

  • The CommonTasks component produces a page of common tasks for your application, complete with drop-down help and nice roll-over visual effects:

Common Tasks

 

  • This Table component can create simple to very complicated tables.  It takes advantage of the unique "DataProvider" feature that makes managing your data efficient and a breeze!  Below is a fairly complicated table: 

 

Table

 

  • The Masthead component allows you to present a visual appealing and very functional masthead complete with status information, buttons, branding, and more: 

Masthead

  • The Wizard component allows you to create web-based wizards for walking your user through a process:

Wizard 

  • The Tree component provides a both a server-side and client-side rendering option and nice visual appeal: 

Tree 

  • The PropertySheet and FileChooser shown below are two more nifty components that provides a nice page layout and the ability to browse and select a file on the server: 

 

All of these components are "themed" so you can adapt the look of these components to your company's look and feel by creating your own theme.  Many of the components use Ajax (via Ed Burn's Dynamic Faces project), and more Ajax features are sure to come.  The TLD document and example application included in the project provide more than enough information to get you started.

If you're a Faclets user, Jason Lee is already working on creating a Facelets taglib for Woodstock.  And of course if you're a JSFTemplating user, I have full support for the Woodstock components built in... plus I have a simple example app on the site to get you started.  Plus, the entire GlassFish admin console (source here) is built using JSFTemplating and Woodstock components.  So whatever your JSF environment (NetBeans, Facelets, JSFTemplating), you'll be able to use these components.


So what are you waiting for?  Go download the components and try them out!

Ken
 

 

Wednesday Feb 07, 2007

Jive Clearspace is Great on GlassFish


[Read More]

Tuesday Jan 09, 2007

JSFTemplating + DynamicFaces = Easy Ajax

Ok, let's get right to it.  Ajax is hot, but it needs to be "real".  You need a fast way to be productive with Ajax, not gfx-clock productive, but real-world productive.  Let me offer a suggestion...

In an effort to keep my blog entries concise (part of my New Year's Resolution), I will get right to the point.  By using JSFTemplating with Ed Burns's DynamicFaces project, you have a perfect Ajax solution tailored to JSF's component architecture.  Add JSF widgets like those found Greg Murray's jMaki project and you have a complete solution.  However, I will save jMaki for a later blog.  I want to stick to the basics for this entry -- Keep It Simple.

I created a very simple example which shows all you need and little more.  You can download the complete war file and try it out.  Here are the contents of the .war file:

guess.jsf                                         <-- JSF page
WEB-INF/lib/dataprovider.jar                      <-- Sun component libraries & dependencies
WEB-INF/lib/json2.jar
WEB-INF/lib/webui-jsf.jar
WEB-INF/lib/webui-jsf-suntheme.jar
WEB-INF/lib/jsftemplating.jar                     <-- JSFTemplating .jar file
WEB-INF/lib/jsftemplating-dynafaces-0.1.jar       <-- JSFTemplating/DynamicFaces integration .jar file
WEB-INF/web.xml                                   <-- deployment descriptor

 

This is a 1 page application -- doesn't get much simpler than that.  It also doesn't use any managed beans, or any custom Java code.  Instead it leverages JSFTemplating to do everything in the .jsf file.  Let's look at the page:

        Guess Demo Screenshot 

 

And the source:

 

 <sun:html>
    <sun:head title="Ajax Zone">
<jsfExt:scripts />
</sun:head>

    <sun:body>
<sun:form id="form">
            "<p>&nbsp;</p><center>

            <sun:markup tag="div" id="result">
                <staticText value="#{pageSession.msg}">
<!beforeCreate
setPageSessionAttribute(key="msg" value="Guess my number [1-100]!");
/>
</staticText>
	    </sun:markup>

            "<p>&nbsp;</p>
            // The data input / processing...
<sun:textField id="guess" label="Your guess: " value="#{requestScope.guess}" />
<sun:button text="Submit AJAX Request" onClick="
DynaFaces.fireAjaxTransaction(this,
{execute: this.id + ',form:guess',
immediate: false,
inputs: this.id + ',form:guess_field',
render: 'form:result' });
return false;

">
<!command
if ("#{requestScope.guess}>64") {
setPageSessionAttribute(key="msg" value="#{requestScope.guess} is too high!");
}
if ("#{requestScope.guess}=64") {
setPageSessionAttribute(key="msg" value="You WIN!!! It was #{requestScope.guess}.");
}
if ("#{requestScope.guess}<64") {
setPageSessionAttribute(key="msg" value="#{requestScope.guess} is too low!");
}
/>

</sun:button>

"<p>&nbsp;</p>

// This fields below exist to show required fields are NOT effected
<sun:textField label="This is required: " required="#{true}" />
<sun:button text="Submit (non-AJAX)" />

"</center>
</sun:form>
</sun:body>
</sun:html>
 

The blue area above defines an area where a prompt will be shown to the user.  The beforeCreate event allows an initial value to be set.  PageSession is a JSFTemplating-added scope.  The value bound to the pageSession variable msg will be shown to the user.  This is plain, oridinary text that will be replaced by an Ajax request.

The red areas is the JavaScript from DynamicFaces that is needed to submit the request.  In this case, I've specified several things for this Ajax request:

  • execute: A JavaScript String specifying which JSF component id's to process.  In this case the button itself and the field to submit.

  • immediate: Not really needed, but if there was validation on the field in "execute" immediate would skip the validation.  In this example it does nothing useful.  I added it to show that the other required field on the page truely isn't processed even when immediate is false.  This is true partial-page processing.

  •  inputs: The values sent to the server.  This may be different than the components processed.  In this case the HTML id of the form field is different than the component id because of how the componet is implemented, so I need to send "form:guess_field" for the value to be sent correctly during the Ajax request.

  • render: This specifies which area(s) of the screen should be updated with the response.  In this case the <div> around our message text.

Finally, the green area is the business logic.  It evaluates the submitted value and displays an appropriate response.  In real-world JSFTemplating applications, you'd likely put this in Java code in a handler such as is done by the built-in "setPageSessionAttribute" handler in this example.  But to keep the example simple (1 page), JSFTemplating's condition processing was used instead.

That's it!  The user types something in the box, clicks the button, an Ajax request displays the response.  The beauty is its simplicity.  You work with Ajax requests on the server-side exactly as you would with any other JSF action.  You glue it together with a small amount of JavaScript which, as you can see, gives you \*lots\* of flexibility on what is sent to the server, what is updated, etc.  So your next step is to look at your own application and see where you could improve your user experience by doing partial page updates, or other asynchronous checks.  The plumbing is in place... now use it!

References:

JSFTemplating: https://jsftemplating.dev.java.net

DynamicFaces: https://jsf-extensions.dev.java.net/nonav/mvn/features-ajax.html

Tuesday May 16, 2006

Scripting in JavaServer Faces Technology BOF @ JavaONE

Get my slides to my JavaONE BOF on Scripting in JavaServer Faces Technology here.  I share this BOF with Jerome and Roberto.  It starts in 10 minutes... got to go.

Friday Apr 14, 2006

BluePrints AJAX JSF Components


The BluePrints team has added some of the AJAX JSF components they have recently built.  These components serve as good examples of strategies to combine AJAX and JSF together via reusable components -- and since they are components, they're easy to plug in to your application.  Check them out at:  https://blueprints.dev.java.net/ajaxcomponents.html

Ken

Monday Apr 03, 2006

Jive Forums Gold 5 on GlassFish



In an earlier entry I wrote about Security Manager woes when I attempted to install Jive Forums from Jive Software.  Many applications (including Jive Forums) require privileges that may be considered "unsafe" in some environments -- Java's security manager allows administrators to control the settings ensure applications don't write to disk, send email, load unsafe classes, etc.  However, this can get in the way when a user attempts to install trusted software, yet the server doesn't have security properly configured (and it's not easy to properly configure).

GlassFish has changed.  It no longer enables the security manger by default.  This is consitent with most other application servers and makes deploying applications (such as Jive Forums) much easier.  Here's what I had to do when installing Jive Forums Gold 5 on GlassFish (build 42):



  1. Download Jive Forums files (server + license file) (Find it on: Jive Software's web site)

  2. Copy jiveHome to a new directory

  3. Copy the license file into the new diretory; name it jive.license

  4. Start GlassFish (i.e. asadmin start-domain)

  5. Go to GlassFish's Admin GUI: http://localhost:4848 
    - Applications -> Web Applications -> Deploy
    - Upload "jiveforums.war"
    - Select options (defaults are fine)

  6. Go to the application (I clicked on "Launch" button in Admin GUI)

  7. Message states jiveHome is not set.  Type in the correct path (the new directory from step 2).  Click the update button.

  8. Click continue (everything should have a "success" check now).

  9. Choose embedded DB (you may want something else), click continue.

  10. Click continue (db should be configured properly).

  11. I picked "Default" for authentication. Click continue.

  12. Setup your email server settings. Click continue.

  13. Setup your admin user.  Click continue.

  14. Setup should be complete, click "Login to Admin Tool"

  15. I logged in as "admin" / "<admin-password>"...
That's it... in fact everything after step 6 is just walking through Jive's software setup.  No more security errors, everything just works.

Have fun!

Ken

Tuesday Feb 21, 2006

Use Java EE 5 Faster with Screencasts




Sun released a beta version of Java EE 5 today.  It includes many cool ease-of-use features, but rather than read about them, why not watch them?

Then make some popcorn, recline your chair, and learn about the new exciting world of Java EE 5!

To take it for a spin, visit the download page.  Or get even more involved: goto the GlassFish site and start contributing!

Have fun!

Ken

About

paulsen

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
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