Featured FREE Whitepapers

What's New Here?

javafx-logo

JavaFX 2: Create Login Form

In this tutorial I will design a nice looking Login Form with JavaFX 2 and CSS. It’s clasic login form with username and password, and login button. In order to follow this tutorial I strongly recommend you to check these tutorials below:Getting started with JavaFX 2 in Eclipse IDE JavaFX 2: HBox JavaFX 2: GridPane JavaFX 2: Styling Buttons JavaFX 2: Working with Text and Text EffectsUsername: JavaFX2 Password: password You can enter this information above and click on Login button. It will tell you with a little message that login is successful, but if you enter wrong information, it will tell you with a little message that login isn’t successful. The final output screenshot of this tutorial will be like below image.JavaFX 2 Login FormHere is Java code of our example: import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; import javafx.scene.effect.DropShadow; import javafx.scene.effect.Reflection; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.FontWeight; import javafx.scene.text.Text; import javafx.stage.Stage; /** * * @web http://zoranpavlovic.blogspot.com/ */ public class Login extends Application { String user = "JavaFX2"; String pw = "password"; String checkUser, checkPw; public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("JavaFX 2 Login"); BorderPane bp = new BorderPane(); bp.setPadding(new Insets(10,50,50,50)); //Adding HBox HBox hb = new HBox(); hb.setPadding(new Insets(20,20,20,30)); //Adding GridPane GridPane gridPane = new GridPane(); gridPane.setPadding(new Insets(20,20,20,20)); gridPane.setHgap(5); gridPane.setVgap(5); //Implementing Nodes for GridPane Label lblUserName = new Label("Username"); final TextField txtUserName = new TextField(); Label lblPassword = new Label("Password"); final PasswordField pf = new PasswordField(); Button btnLogin = new Button("Login"); final Label lblMessage = new Label(); //Adding Nodes to GridPane layout gridPane.add(lblUserName, 0, 0); gridPane.add(txtUserName, 1, 0); gridPane.add(lblPassword, 0, 1); gridPane.add(pf, 1, 1); gridPane.add(btnLogin, 2, 1); gridPane.add(lblMessage, 1, 2); //Reflection for gridPane Reflection r = new Reflection(); r.setFraction(0.7f); gridPane.setEffect(r); //DropShadow effect DropShadow dropShadow = new DropShadow(); dropShadow.setOffsetX(5); dropShadow.setOffsetY(5); //Adding text and DropShadow effect to it Text text = new Text("JavaFX 2 Login"); text.setFont(Font.font("Courier New", FontWeight.BOLD, 28)); text.setEffect(dropShadow); //Adding text to HBox hb.getChildren().add(text); //Add ID's to Nodes bp.setId("bp"); gridPane.setId("root"); btnLogin.setId("btnLogin"); text.setId("text"); //Action for btnLogin btnLogin.setOnAction(new EventHandler() { public void handle(ActionEvent event) { checkUser = txtUserName.getText().toString(); checkPw = pf.getText().toString(); if(checkUser.equals(user) && checkPw.equals(pw)){ lblMessage.setText("Congratulations!"); lblMessage.setTextFill(Color.GREEN); } else{ lblMessage.setText("Incorrect user or pw."); lblMessage.setTextFill(Color.RED); } txtUserName.setText(""); pf.setText(""); } }); //Add HBox and GridPane layout to BorderPane Layout bp.setTop(hb); bp.setCenter(gridPane); //Adding BorderPane to the scene and loading CSS Scene scene = new Scene(bp); scene.getStylesheets().add(getClass().getClassLoader().getResource("login.css").toExternalForm()); primaryStage.setScene(scene); primaryStage.titleProperty().bind( scene.widthProperty().asString(). concat(" : "). concat(scene.heightProperty().asString())); //primaryStage.setResizable(false); primaryStage.show(); } }In order to style this application properly you’ll need to create login.css file in /src folder of your project. If you dont know how to do that, please check out JavaFX 2: Styling Buttons tutorial. Here is CSS code of our example:#root { -fx-background-color: linear-gradient(lightgray, gray); -fx-border-color: white; -fx-border-radius: 20; -fx-padding: 10 10 10 10; -fx-background-radius: 20; }#bp { -fx-background-color: linear-gradient(gray,DimGrey ); }#btnLogin { -fx-background-radius: 30, 30, 29, 28; -fx-padding: 3px 10px 3px 10px; -fx-background-color: linear-gradient(orange, orangered ); }#text { -fx-fill: linear-gradient(orange , orangered); }Thats’all folks for this tutorial, if you have any comments or problems, feel free to comment. If you like this tutorial, you can check out more JavFX 2 tutorials on this blog. You might want to take a look at these tutorials below:JavaFX 2: Styling Buttons with CSS JavaFX 2: Styling Text with CSSReference: JavaFX 2: Create Nice Login Form from our JCG partner Zoran Pavlovic at the Zoran Pavlovic blog blog....
google-aps-logo

Google Services Authentication in App Engine, Part 1

This post will illustrate how to build a simple Google App Engine (GAE) Java application that authenticates against Google as well as leverages Google’s OAuth for authorizing access to Google’s API services such as Google Docs. In addition, building on some of the examples already provided by Google, it will also illustrate how to persist data using the App Engine Datastore and Objectify. Project Source Code The motivation behind this post is that I struggled to previously find any examples that really tied these technologies together. Yet, these technologies really represent the building-blocks for many web applications that want to leverage the vast array of Google API services. To keep things simple, the demo will simply allow the user to login via a Google domain; authorize access to the user’s Google Docs services; and display a list of the user’s Google Docs Word and Spreadsheet documents. Throughout this tutorial I do make several assumptions about the reader’s expertise, such as a pretty deep familiarity with Java.Overview of the Flow Before we jump right into the tutorial/demo, let’s take a brief look at the navigation flow.While it may look rather complicated, the main flow can be summarized as:User requests access to listFiles.jsp (actually any of the JSP pages can be used). A check is make to see if the user is logged into Google. If not, they are re-directed to a Google login page — once logged in, they are returned back. A check is then made to determine whether the user is stored in the local datastore. If not, the user is added along with the user’s Google domain email address. Next, we check to see if the user has granted OAuth credentials to the Google Docs API service. If not, the OAuth authentication process is initiated. Once the OAuth credentials are granted, they are stored in the local user table (so we don’t have to ask each time the user attempts to access the services). Finally, a list of Google Docs Spreadsheet or Word docs is displayed.This same approach could be used to access other Google services, such as YouTube (you might display a list of the user’s favorite videos, for example). Environment Setup For this tutorial, I am using the following:Eclipse Indigo Service Release 2 along with the Google Plugin for Eclipse (see setup instructions). Google GData Java SDK Eclipse plugin version 1.47.1 (see setup instructions). Google App Engine release 1.6.5. Some problems exist with earlier versions, so I’d recommend making sure you are using it. It should install automatically as part of the Google Plugin for Eclipse. Objectify version 3.1. The required library is installed already in the project’s war/WEB-INF/lib directory.After you have imported the project into Eclipse, your build path should resemble:The App Engine settings should resemble:You will need to setup your own GAE application, along with specifying your own Application ID (see the Google GAE developer docs). The best tutorial I’ve seen that describes how to use OAuth to access Google API services can be found here. One of the more confusing aspects I found was how to acquire the necessary consumer key and consumer secret values that are required when placing the OAuth request. The way I accomplished this was:Create the GAE application using the GAE Admin Console. You will need to create your own Application ID (just a name for your webapp). Once you have it, you will update your Application ID in the Eclipse App Engine settings panel that is shown above. Create a new Domain for the application. For example, since my Application ID was specified above as ‘tennis-coachrx’, I configured the target URL path prefix as: http://tennis-coachrx.appspot.com/authSub. You will see how we configure that servlet to receive the credentials shortly. To complete the domain registration, Google will provide you an HTML file that you can upload. Include that file the root path under the /src/war directory and upload the application to GAE. This way, when Google runs it’s check, the file will be present and it will generate the necessary consumer credentials. Here’s a screenshot of what the setup looks like after it is completed:Once you have the OAuth Consumer Key and OAuth Consumer Secret, you will then replace the following values in the com.zazarie.shared.Constant file: final static String CONSUMER_KEY = ‘ ‘; final static String CONSUMER_SECRET = ‘ ‘; Whew, that seemed like a lot of work! However, it’s a one-time deal, and you shouldn’t have to fuss with it again. Code Walkthrough Now that we got that OAuth configuration/setup out of the way, we can dig into the code. Let’s begin by looking at the structure of the war directory, where your web assets reside:The listFiles.jsp is the default JSP page that is displayed when your first enter the webapp. Let’s now look at the web.xml file to see how this is configured, along with the servlet filter which is central to everything. <?xml version='1.0' encoding='UTF-8'?> <web-app xmlns:xsi='http:www.w3.org2001XMLSchema-instance' xsi:schemaLocation='http:java.sun.comxmlnsjavaee http:java.sun.comxmlnsjavaeeweb-app_2_5.xsd' version='2.5' xmlns='http:java.sun.comxmlnsjavaee'> <!-- Filters --> <filter> <filter-name>AuthorizationFilter<filter-name> <filter-class>com.zazarie.server.servlet.filter.AuthorizationFilter<filter-class> <filter> <filter-mapping> <filter-name>AuthorizationFilter<filter-name> <url-pattern>html*<url-pattern> <filter-mapping> <!-- Servlets --> <servlet> <servlet-name>Step2<servlet-name> <servlet-class>com.zazarie.server.servlet.RequestTokenCallbackServlet<servlet-class> <servlet> <servlet-mapping> <servlet-name>Step2<servlet-name> <url-pattern>authSub<url-pattern> <servlet-mapping> <!-- Default page to serve --> <welcome-file-list> <welcome-file>htmllistFiles.jsp<welcome-file> <welcome-file-list> <web-app>The servlet filter called AuthorizationFilter is invoked whenever a JSP file located in the html directory is requested. The filter, as we’ll look at in a moment, is responsible for ensuring that the user is logged into Google, and if so, then ensures that the OAuth credentials have been granted for that user (i.e., it will kick off the OAuth credentialing process, if required). The servlet name of Step2 represents the servlet that is invoked by Google when the OAuth credentials have been granted — think of it as a callback. We will look at this in more detail in a bit. Let’s take a more detailed look at the AuthorizationFilter. AuthorizationFilter Deep Dive The doFilter method is where the work takes place in a servlet filter. Here’s the implementation: @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session = request.getSession(); LOGGER.info('Invoking Authorization Filter'); LOGGER.info('Destination URL is: ' + request.getRequestURI()); if (filterConfig == null) return; get the Google user AppUser appUser = LoginService.login(request, response); if (appUser != null) { session.setAttribute(Constant.AUTH_USER, appUser); } identify if user has an OAuth accessToken - it not, will set in motion oauth procedure if (appUser.getCredentials() == null) { need to save the target URI in session so we can forward to it when oauth is completed session.setAttribute(Constant.TARGET_URI, request.getRequestURI()); OAuthRequestService.requestOAuth(request, response, session); return; } else store DocService in the session so it can be reused session.setAttribute(Constant.DOC_SESSION_ID, LoginService.docServiceFactory(appUser)); chain.doFilter(request, response); } Besides the usual housekeeping stuff, the main logic begins with the line: AppUser appUser = LoginService.login(request, response); As we will see in a moment, the LoginService is responsible for logging the user into Google, and also will create the user in the local BigTable datastore. By storing the user locally, we can then store the user’s OAuth credentials, eliminating the need for the user to have to grant permissions every time they access a restricted/filtered page. After LoginService has returned the user ( AppUser object), we then store that user object into the session (NOTE: to enable sessions, you must set sessions-enabled in the appengine-web.xml file): session.setAttribute(Constant.AUTH_USER, appUser); We then check to see whether the OAuth credentials are associated with that user: if (appUser.getCredentials() == null) { session.setAttribute(Constant.TARGET_URI, request.getRequestURI()); OAuthRequestService.requestOAuth(request, response, session); return; } else session.setAttribute(Constant.DOC_SESSION_ID,LoginService.docServiceFactory(appUser)); If getCredentials() returns a null, the OAuth credentials have not already been assigned for the user. This means that the OAuth process needs to be kicked off. Since this involves a two-step process of posting the request to Google and then retrieving back the results via the callback ( Step2 servlet mentioned above), we need to store the destination URL so that we can later redirect the user to it once the authorization process is completed. This is done by storing the URL requested into the session using the setAttribute method. We then kick off the OAuth process by calling the OAuthRequestService.requestOAuth() method (details discussed below). In the event that if getCredentials() returns a non-null value, this indicates that we already have the user’s OAuth credentials from their local AppUser entry in the datastore, and we simply add it to the session so that we can use it later. LoginService Deep Dive The LoginService class has one main method called login, followed by a bunch of JPA helper methods for saving or updating the local user in the datastore. We will focus on login(), since that is where most of the business logic resides. public static AppUser login(HttpServletRequest req, HttpServletResponse res) { LOGGER.setLevel(Constant.LOG_LEVEL); LOGGER.info('Initializing LoginService'); String URI = req.getRequestURI(); UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); if (user != null) { LOGGER.info('User id is: '' + userService.getCurrentUser().getUserId() + '''); String userEmail = userService.getCurrentUser().getEmail(); AppUser appUser = (AppUser) req.getSession().getAttribute( Constant.AUTH_USER); if (appUser == null) { LOGGER.info('appUser not found in session'); see if it is a new user appUser = findUser(userEmail); if (appUser == null) { LOGGER.info('User not found in datastore...creating'); appUser = addUser(userEmail); } else { LOGGER.info('User found in datastore...updating'); appUser = updateUserTimeStamp(appUser); } } else { appUser = updateUserTimeStamp(appUser); } return appUser; } else { LOGGER.info('Redirecting user to login page'); try { res.sendRedirect(userService.createLoginURL(URI)); } catch (IOException e) { e.printStackTrace(); } } return null; } The first substantive thing we do is use Google UserService class to determine whether the user is logged into Google: UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); If the User object returned by Google’s call is null, the user isn’t logged into Google, and they are redirected to a login page using: res.sendRedirect(userService.createLoginURL(URI)); If the user is logged (i.e., not null), the next thing we do is determine whether that user exists in the local datastore. This is done by looking up the user with their logged-in Google email address with appUser = findUser(userEmail). Since JPA/Objectify isn’t the primary discussion point for this tutorial, I won’t go into how that method works. However, the Objectify web site has some great tutorials/documentation. If the user doesn’t exist locally, the object is populated with Google’s email address and created using appUser = addUser(userEmail). If the user does exist, we simply update the login timestamp for logging purposes.OAuthRequestService Deep DiveAs you may recall from earlier, once the user is setup locally, the AuthorizationFilter will then check to see whether the OAuth credentials have been granted by the user. If not, the OAuthRequestService.requestOAuth() method is invoked. It is shown below: public static void requestOAuth(HttpServletRequest req, HttpServletResponse res, HttpSession session) { LOGGER.setLevel(Constant.LOG_LEVEL); LOGGER.info('Initializing OAuthRequestService'); GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(Constant.CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret(Constant.CONSUMER_SECRET); Set the scope. oauthParameters.setScope(Constant.GOOGLE_RESOURCE); Sets the callback URL. oauthParameters.setOAuthCallback(Constant.OATH_CALLBACK); GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper( new OAuthHmacSha1Signer()); try { Request is still unauthorized at this point oauthHelper.getUnauthorizedRequestToken(oauthParameters); Generate the authorization URL String approvalPageUrl = oauthHelper .createUserAuthorizationUrl(oauthParameters); session.setAttribute(Constant.SESSION_OAUTH_TOKEN, oauthParameters.getOAuthTokenSecret()); LOGGER.info('Session attributes are: ' + session.getAttributeNames().hasMoreElements()); res.getWriter().print( '<a href='' + approvalPageUrl + ''>Request token for the Google Documents Scope'); } catch (OAuthException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } To simplify working with OAuth, Google has a set of Java helper classes that we are utilizing. The first thing we need to do is setup the consumer credentials (acquiring those was discussed earlier): GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(Constant.CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret(Constant.CONSUMER_SECRET); Then, we set the scope of the OAuth request using: oauthParameters.setScope(Constant.GOOGLE_RESOURCE); Where Constant.GOOGLE_RESOURCE resolves to https://docs.google.com/feeds/. When you make an OAuth request, you specify the scope of what resources you are attempting to gain access. In this case, we are trying to access Google Docs (the GData API’s for each service have the scope URL provided). Next, we establish where we want Google to return the reply. oauthParameters.setOAuthCallback(Constant.OATH_CALLBACK); This value changes whether we are running locally in dev mode, or deployed to the Google App Engine. Here’s how the values are defined in the the Constant interface: // Use for running on GAE //final static String OATH_CALLBACK = ‘http://tennis-coachrx.appspot.com/authSub’; // Use for local testing final static String OATH_CALLBACK = ‘http://127.0.0.1:8888/authSub’; When then sign the request using Google’s helper: GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer()); We then generate the URL that the user will navigate to in order to authorize access to the resource. This is generated dynamically using: String approvalPageUrl = oauthHelper.createUserAuthorizationUrl(oauthParameters); The last step is to provide a link to the user so that they can navigate to that URL to approve the request. This is done by constructing some simple HTML that is output using res.getWriter().print(). Once the user has granted access, Google calls back to the servlet identified by the URL parameter /authSub, which corresponds to the servlet class RequestTokenCallbackServlet. We will examine this next. RequestTokenCallbackServlet Deep DiveThe servlet uses the Google OAuth helper classes to generate the required access token and secret access token’s that will be required on subsequent calls to to the Google API docs service. Here is the doGet method that receives the call back response from Google: public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Create an instance of GoogleOAuthParameters GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters(); oauthParameters.setOAuthConsumerKey(Constant.CONSUMER_KEY); oauthParameters.setOAuthConsumerSecret(Constant.CONSUMER_SECRET); GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper( new OAuthHmacSha1Signer()); String oauthTokenSecret = (String) req.getSession().getAttribute( Constant.SESSION_OAUTH_TOKEN); AppUser appUser = (AppUser) req.getSession().getAttribute( Constant.AUTH_USER); oauthParameters.setOAuthTokenSecret(oauthTokenSecret); oauthHelper.getOAuthParametersFromCallback(req.getQueryString(), oauthParameters); try { String accessToken = oauthHelper.getAccessToken(oauthParameters); String accessTokenSecret = oauthParameters.getOAuthTokenSecret(); appUser = LoginService.getById(appUser.getId()); appUser = LoginService.updateUserCredentials(appUser, new OauthCredentials(accessToken, accessTokenSecret)); req.getSession().setAttribute(Constant.DOC_SESSION_ID, LoginService.docServiceFactory(appUser)); RequestDispatcher dispatcher = req.getRequestDispatcher((String) req .getSession().getAttribute(Constant.TARGET_URI)); if (dispatcher != null) dispatcher.forward(req, resp); } catch (OAuthException e) { e.printStackTrace(); } } The Google GoogleOAuthHelper is used to perform the housekeeping tasks required to populate the two values we are interested in: String accessToken = oauthHelper.getAccessToken(oauthParameters); String accessTokenSecret = oauthParameters.getOAuthTokenSecret(); Once we have these values, we then requery the user object from the datastore, and save those values into the AppUser.OauthCredentials subclass: appUser = LoginService.getById(appUser.getId()); appUser = LoginService.updateUserCredentials(appUser, new OauthCredentials(accessToken, accessTokenSecret)); req.getSession().setAttribute(Constant.DOC_SESSION_ID, LoginService.docServiceFactory(appUser)); In addition, you’ll see they are also stored into the session so we have them readily available when the API request to Google Docs is placed. Now that we’ve got everything we need, we simply redirect the user back to the resource they had originally requested: RequestDispatcher dispatcher = req.getRequestDispatcher((String) req .getSession().getAttribute(Constant.TARGET_URI)); dispatcher.forward(req, resp); Now, when they access the JSP page listing their documents, everything should work! Here’s a screencast demo of the final product: Hope you enjoyed the tutorial and demo — look forward to your comments! Continue to the second part of this tutorial. Reference: Authenticating for Google Services in Google App Engine from our JCG partner Jeff Davis at the Jeff’s SOA Ruminations blog....
google-aps-logo

Google Services Authentication in App Engine, Part 2

In the first part of the tutorial I described how to use OAuth for access/authentication for Google’s API services. Unfortunately, as I discovered a bit later, the approach I used was OAuth 1.0, which has apparently now been officially deprecated by Google in favor of version 2.0 of OAuth. Obviously, I was a bit bummed to discovered this, and promised I would create a new blog entry with instructions on how to use 2.0. The good news is that, with the 2.0 support, Google has added some additional helper classes that make things easier, especially if you are using Google App Engine, which is what I’m using for this tutorial. The Google Developers site now has a pretty good description on how to setup OAuth 2.0. However, it still turned out to be a challenge to configure a real-life example of how it’s done, so I figured I’d document what I’ve learned. Tutorial Scenario In the last tutorial, the project I created illustrated how to access a listing of a user’s Google Docs files. In this tutorial, I changed things up a bit, and instead use YouTube’s API to display a list of a user’s favorite videos. Accessing a user’s favorites does require authentication with OAuth, so this was a good test. Getting Started (Eclipse project for this tutorial can be found here). The first thing you must do is follow the steps outlined in Google’s official docs on using OAuth 2.0. Since I’m creating a web-app, you’ll want to follow the section in those docs titled ‘Web Server Applications’. In addition, the steps I talked about previously for setting up a Google App Engine are still relevant, so I’m going to jump right into the code and bypass these setup steps. (NOTE: The Eclipse project can be found here — I again elected not to use Maven in order to keep things simple for those who don’t have it installed or are knowledgeable in Maven). The application flow is very simple (assuming a first-time user):When the user accesses the webapp (assuming you are running it locally at http://localhost:8888 using the GAE developer emulator), they must first login to Google using their gmail or Google domain account. Once logged in, the user is redirected to a simple JSP page that has a link to their YouTube favorite videos. When the click on the link, a servlet will initiate the OAuth process to acquire access to their YouTube account. The first part of this process is being redirected to a Google Page that prompts them whether they want to grant the application access. Assuming the user responds affirmative, a list of 10 favorites will be displayed with links. If they click on the link, the video will load.Here’s the depiction of the first 3 pages flow:And here’s the last two pages (assuming that the user clicks on a given link):While this example is specific to YouTube, the same general principles apply for accessing any of the Google-based cloud services, such as Google+, Google Drive, Docs etc. They key enabler for creating such integrations is obviously OAuth, so let’s look at how that process works. OAuth 2.0 Process Flow Using OAuth can be a bit overwhelming for the new developer first learning the technology. The main premise behind it is to allow users to selectively identify which ‘private’ resources they want to make accessible to an external application, such as we are developing for this tutorial. By using OAuth, the user can avoid having to share their login credentials with a 3rd party, but instead can simply grant that 3rd party access to some of their information. To achieve this capability, the user is navigated to the source where their private data resides, in this case, YouTube. They can then either allow or reject the access request. If they allow it, the source of the private data (YouTube) then returns a single-use authorization code to the 3rd party application. Since it’s rather tedious for the user to have to grant access every time access is desired, there is an additional call that can be played that will ‘trade-in’ their single use authorization for a longer term one. The overall flow for the web application we’re developing for this tutorial can be seen below. OAuth FlowThe first step that takes place is to determine whether the user is already logged into Google using either their gmail or Google Domain account. While not directly tied to the OAuth process, it’s very convenient to enable users to login with their Google account as opposed to requiring them to sign up with your web site. That’s the first callout that is made to Google. Then, once logged in, the application determines whether the user has a local account setup with OAuth permissions granted. If they are logging in for the first time, they won’t. In that case, the OAuth process is initiated. The first step of that process is to specify to the OAuth provider, in this case Google YouTube, what ‘scope’ of access is being requested. Since Google has a lot of services, they have a lot of scopes. You can determine this most easily using their OAuth 2.0 sandbox. When you kickoff the OAuth process, you provide them the scope(s) you want access to, along with the OAuth client credentials that Google has provided you (these steps are actually rather generic to any provider that supports OAuth). For our purposes, we’re seeking access to the user’s YouTube account, so the scope provided by Google is: https://gdata.youtube.com/. If the end-user grants access to the resource identify by the scope, Google will then post back an authorization code to the application. This is captured in a servlet. Since the returned code is only a ‘single-use’ code, it is exchanged for a longer running access token (and related refresh token). That step is represented above by the activity/box titled ‘Access & Refresh Token Requested’. Once armed with the access token, the application can then access the users’ private data by placing an API call along with the token. If everything checks out, the API will return the results. It’s not a terrible complicated process — it just involves a few steps. Let’s look at some of the specific implementation details, beginning with the servlet filter that determines whether the user has already logged into Google and/or granted OAuth access. AuthorizationFilter Let’s take a look at the first few lines of the AuthorizationFilter (to see how it’s configured as a filter, see the web.xml file). public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session = request.getSession(); if not present, add credential store to servlet context if (session.getServletContext().getAttribute(Constant.GOOG_CREDENTIAL_STORE) == null) { LOGGER.fine('Adding credential store to context ' + credentialStore); session.getServletContext().setAttribute(Constant.GOOG_CREDENTIAL_STORE, credentialStore); } if google user isn't in session, add it if (session.getAttribute(Constant.AUTH_USER_ID) == null) { LOGGER.fine('Add user to session'); UserService userService = UserServiceFactory.getUserService(); User user = userService.getCurrentUser(); session.setAttribute(Constant.AUTH_USER_ID, user.getUserId()); session.setAttribute(Constant.AUTH_USER_NICKNAME, user.getNickname()); if not running on app engine prod, hard-code my email address for testing if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) { session.setAttribute(Constant.AUTH_USER_EMAIL, user.getEmail()); } else { session.setAttribute(Constant.AUTH_USER_EMAIL, 'jeffdavisco@gmail.com'); } }The first few lines simply cast the generic servlet request and response to their corresponding Http equivalents — this is necessary since we want access to the HTTP session. The next step is to determine whether a CredentialStore is present in the servlet context. As we’ll see, this is used to store the user’s credentials, so it’s convenient to have it readily available in subsequent servlets. The guts of the matter begin when we check to see whether the user is already present in the session using: if (session.getAttribute(Constant.AUTH_USER_ID) == null) { If not, we get their Google login credentials using Google’s UserService class. This is a helper class available to GAE users to fetch the user’s Google userid, email and nickname. Once we get this info from UserService, we store some of the user’s details in the session. At this point, we haven’t done anything with OAuth, but that will change in the next series of code lines: try { Utils.getActiveCredential(request, credentialStore); } catch (NoRefreshTokenException e1) { // if this catch block is entered, we need to perform the oauth process LOGGER.info(‘No user found – authorization URL is: ‘ + e1.getAuthorizationUrl()); response.sendRedirect(e1.getAuthorizationUrl()); } A helper class called Utils is used for most of the OAuth processing. In this case, we’re calling the static method getActiveCredential(). As we will see in a moment, this method will return a NoRefreshTokenException if no OAuth credentials have been previously captured for the user. As a custom exception, it will return URL value that is used for redirecting the user to Google to seek OAuth approval. Let’s take a look at the getActiveCredential() method in more detail, as that’s where much of the OAuth handling is managed. public static Credential getActiveCredential(HttpServletRequest request, CredentialStore credentialStore) throws NoRefreshTokenException { String userId = (String) request.getSession().getAttribute(Constant.AUTH_USER_ID); Credential credential = null; try { if (userId != null) { credential = getStoredCredential(userId, credentialStore); } if ((credential == null || credential.getRefreshToken() == null) && request.getParameter('code') != null) { credential = exchangeCode(request.getParameter('code')); LOGGER.fine('Credential access token is: ' + credential.getAccessToken()); if (credential != null) { if (credential.getRefreshToken() != null) { credentialStore.store(userId, credential); } } } if (credential == null || credential.getRefreshToken() == null) { String email = (String) request.getSession().getAttribute(Constant.AUTH_USER_EMAIL); String authorizationUrl = getAuthorizationUrl(email, request); throw new NoRefreshTokenException(authorizationUrl); } } catch (CodeExchangeException e) { e.printStackTrace(); } return credential; } The first thing we do is fetch the Google userId from the session (they can’t get this far without it being populated). Next, we attempt to get the user’s OAuth credentials (stored in the Google class with the same name) from the CredentialStore using the Utils static method getStoredCredential(). If no credentials are found for that user, the Utils method called getAuthorizationUrl() is invoked. This method, which is shown below, is used to construct the URL that the browser is redirected to which is used to prompt the user to authorize access to their private data (the URL is served up by Google, since it will ask the user for approval). private static String getAuthorizationUrl(String emailAddress, HttpServletRequest request) { GoogleAuthorizationCodeRequestUrl urlBuilder = null; try { urlBuilder = new GoogleAuthorizationCodeRequestUrl( getClientCredential().getWeb().getClientId(), Constant.OATH_CALLBACK, Constant.SCOPES) .setAccessType('offline') .setApprovalPrompt('force'); } catch (IOException e) { TODO Auto-generated catch block e.printStackTrace(); } urlBuilder.set('state', request.getRequestURI()); if (emailAddress != null) { urlBuilder.set('user_id', emailAddress); } return urlBuilder.build(); } As you can see, this method is using the class (from Google) called GoogleAuthorizationCodeRequestUrl. It constructs an HTTP call using the OAuth client credentials that is provided by Google when you sign up for using OAuth (those credentials, coincidentally, are stored in a file called client_secrets.json. Other parameters include the scope of the OAuth request and the URL that the user will be redirected back to if approval is granted by the user. That URL is the one you specified when signing up for Google’s OAuth access:Now, if the user had already granted OAuth access, the getActiveCredential()method would instead grab the credentials from the CredentialStore. Turning back to the URL that receives the results of the OAuth credentials, in this case, http://localhost:8888/authSub, you maybe wondering, how can Google post to that internal-only address? Well, it’s the user’s browser that is actually posting back the results, so localhost, in this case, resolves just fine. Let’s look that the servlet called OAuth2Callback that is used to process this callback (see the web.xml for how the servlet mapping for authSub is done). public class OAuth2Callback extends HttpServlet { private static final long serialVersionUID = 1L; private final static Logger LOGGER = Logger.getLogger(OAuth2Callback.class.getName()); public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { StringBuffer fullUrlBuf = request.getRequestURL(); Credential credential = null; if (request.getQueryString() != null) { fullUrlBuf.append('?').append(request.getQueryString()); } LOGGER.info('requestURL is: ' + fullUrlBuf); AuthorizationCodeResponseUrl authResponse = new AuthorizationCodeResponseUrl(fullUrlBuf.toString()); check for user-denied error if (authResponse.getError() != null) { LOGGER.info('User-denied access'); } else { LOGGER.info('User granted oauth access'); String authCode = authResponse.getCode(); request.getSession().setAttribute('code', authCode); response.sendRedirect(authResponse.getState()); } } } The most important take-away from this class is the line: AuthorizationCodeResponseUrl authResponse = new AuthorizationCodeResponseUrl(fullUrlBuf.toString()); The AuthorizationCodeResponseUrl class is provided as a convenience by Google to parse the results of the OAuth request. If the getError() method of that class isn’t null, that means that the user rejected the request. In the event that it is null, indicating the user approved the request, the method call getCode() is used to retrieve the one-time authorization code. This code value is placed into the user’s session, and when the Utils.getActiveCredential() is invoked following the redirect to the user’s target URL (via the filter), it will exchange that authorization code for a longer-term access and refresh token using the call: credential = exchangeCode((String) request.getSession().getAttribute(‘code’)); The Utils.exchangeCode() method is shown next: public static Credential exchangeCode(String authorizationCode) throws CodeExchangeException { try { GoogleTokenResponse response = new GoogleAuthorizationCodeTokenRequest( new NetHttpTransport(), Constant.JSON_FACTORY, Utils .getClientCredential().getWeb().getClientId(), Utils .getClientCredential().getWeb().getClientSecret(), authorizationCode, Constant.OATH_CALLBACK).execute(); return Utils.buildEmptyCredential().setFromTokenResponse(response); } catch (IOException e) { e.printStackTrace(); throw new CodeExchangeException(); } } This method also uses a Google class called GoogleAuthorizationCodeTokenRequest that is used to call Google to exchange the one-time OAuth authorization code for the longer-duration access token. Now that we’ve (finally) got our access token that is needed for the YouTube API, we’re ready to display to the user 10 of their video favorites.Calling the YouTube API Services With the access token in hand, we can now proceed to display the user their list of favorites. In order to do this, a servlet called FavoritesServlet is invoked. It will call the YouTube API, parse the resulting JSON-C format into some local Java classes via Jackson, and then send the results to the JSP page for processing. Here’s the servlet: public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { LOGGER.fine('Running FavoritesServlet'); Credential credential = Utils.getStoredCredential((String) request.getSession().getAttribute(Constant.AUTH_USER_ID), (CredentialStore) request.getSession().getServletContext().getAttribute(Constant.GOOG_CREDENTIAL_STORE)); VideoFeed feed = null; if the request fails, it's likely because access token is expired - we'll refresh try { LOGGER.fine('Using access token: ' + credential.getAccessToken()); feed = YouTube.fetchFavs(credential.getAccessToken()); } catch (Exception e) { LOGGER.fine('Refreshing credentials'); credential.refreshToken(); credential = Utils.refreshToken(request, credential); GoogleCredential googleCredential = Utils.refreshCredentials(credential); LOGGER.fine('Using refreshed access token: ' + credential.getAccessToken()); retry feed = YouTube.fetchFavs(credential.getAccessToken()); } LOGGER.fine('Video feed results are: ' + feed); request.setAttribute(Constant.VIDEO_FAVS, feed); RequestDispatcher dispatcher = getServletContext().getRequestDispatcher('htmllistVids.jsp'); dispatcher.forward(request, response); } Since this post is mainly about the OAuth process, I won’t go into too much detail how the API call is placed, but the most important line of code is: feed = YouTube.fetchFavs(credential.getAccessToken()); Where feed is an instance of VideoFeed. As you can see, another helper class called YouTube is used for doing the heavy-lifting. Just to wrap things up, I’ll show the fetchFavs() method. public static VideoFeed fetchFavs(String accessToken) throws IOException, HttpResponseException { HttpTransport transport = new NetHttpTransport(); final JsonFactory jsonFactory = new JacksonFactory(); HttpRequestFactory factory = transport.createRequestFactory(new HttpRequestInitializer() { @Override public void initialize(HttpRequest request) { set the parser JsonCParser parser = new JsonCParser(jsonFactory); request.addParser(parser); set up the Google headers GoogleHeaders headers = new GoogleHeaders(); headers.setApplicationName('YouTube Favorites1.0'); headers.gdataVersion = '2'; request.setHeaders(headers); } }); build the YouTube URL YouTubeUrl url = new YouTubeUrl(Constant.GOOGLE_YOUTUBE_FEED); url.maxResults = 10; url.access_token = accessToken; build the HTTP GET request HttpRequest request = factory.buildGetRequest(url); HttpResponse response = request.execute(); execute the request and the parse video feed VideoFeed feed = response.parseAs(VideoFeed.class); return feed; } It uses the Google class called HttpRequestFactory to construct an outbound HTTP API call to YouTube. Since we’re using GAE, we’re limited as to which classes we can use to place such requests. Notice the line of code: url.access_token = accessToken; That’s where we are using the access token that was acquired through the OAuth process. So, while it took a fair amount of code to get the OAuth stuff working correctly, once it’s in place, you are ready to rock-and-roll with calling all sorts of Google API services! Reference: Authenticating for Google Services, Part 2 from our JCG partner Jeff Davis at the Jeff’s SOA Ruminations blog....
terracotta-logo

Fast, Predictable & Highly-Available @ 1 TB/Node

The world is pushing huge amounts of data to applications every second, from mobiles, the web, and various gadgets. More applications these days have to deal with this data. To preserve performance, these applications need fast access to the data tier.RAM prices have crumbled over the past few years and we can now get hardware with a Terabyte of RAM much more cheaply. OK, got the hardware, now what? We generally use virtualization to create smaller virtual machines to meet applications scale-out requirements, as having a Java application with a terabyte of heap is impractical. JVM Garbage Collection will slaughter your application right away. Ever imagined how much time will it take to do a single full garbage collection for a terabyte of heap? It can pause an application for hours, making it unusable.BigMemory is the key to access terabytes of data with milliseconds of latency, with no maintenance of disk/raid configurations/databases.BigMemory = Big Data + In-memory  BigMemory can utilize your hardware to the last byte of RAM. BigMemory can store up to a terabyte of data in single java process.BigMemory provides “fast”, “predictable” and “highly-available” data at 1 terabytes per node.The following test uses two boxes, each with a terabyte of RAM. Leaving enough room for the OS, we were able to allocate 2 x 960 GB of BigMemory, for a total of 1.8+ TB of data. Without facing the problems of high latencies, huge scale-out architectures … just using the hardware as it is.Test results: 23K readonly transactions per second with 20 ms latency. Graphs for test throughput and periodic latency over time.Readonly Periodic Throughput GraphReadonly Periodic Latency GraphReference: Fast, Predictable & Highly-Available @ 1 TB/Node from our JCG partner Himadri Singh at the Billions & Terabytes blog....
javaone-logo

JavaOne 2012 – 2400 hours to go! Some recommendations

As you might have seen the JavaOne 2012 Content Catalog is online. The Program Committee had some very intense weeks of sorting, reviewing, rating and discussing every single proposal and we finally managed to setup a (hopefully) interesting mix for you. With exactly 105 days or 2400 hours to go I thought it could be a good day to offer you a list of my favorites to come.I had the pleasure to work with two teams on the program tracks this year so you will get some recommendations for both the Java EE Web Profile and Platform Technologies and the Enterprise Service Architectures and the Cloud track. Let’s start with the first one.Java EE Web Profile and Platform Technologies   This track has 64 sessions, 31 BoFs and 6 tutorials overall. It’s hard to highlight the right ones here without being unfair to anybody. All the speakers did a great job in submitting their proposals and it was amazingly hard to pick the final ones. Even if I have my favorites I highly encourage you to look at all the content in this track to make your own decisions!Oracle 50 Tips in 50 Minutes ForGlassFish Fans Arun Gupta, Christopher Kasso ( CON4701) This fast-paced session presents 50 tips and tricks for using GlassFish Server technology. Presented by two GlassFish experts, the session offers tips to help novice users as well as seasoned developers get the most out of GlassFish.Apache TomEE, Java EE 6 Web Profile on Tomcat David Blevins IBM (CON7469) Making its Java EE 6 Web Profile certification debut at JavaOne 2011, Apache TomEE combines the simplicity of Tomcat with the power of Java EE. If you’re a Tomcat lover or a TomEE enthusiast, this is the session you don’t want to miss!Building HTML5 Web Applications with Avatar Bryan Atsatt and Santiago Pericasgeertsen – Oracle (CON7042) This session focuses on how to build HTML5, thin-server Web applications with the Avatar framework. It introduces the notion of thin-server architectures as well as the major features in the Avatar framework for building rich UI applications.Standardizing Web Flow Technology with JSF Faces Flows Edward Burns and David Schneider – Oracle (CON4627) With the introduction of Faces Flows, a flow technology based on Oracle Application Development Framework (Oracle ADF) task flows and Spring Web flows. This session provides an overview of the Faces Flows technology and how it can be used to increase application modularity and code reuse. Real-World Java EE 6 Tutorial Paul Bakker and BERT ERTMAN – Luminis Technologies (TUT5064) This tutorial demonstrates how to use the Java EE 6 APIs together to build a portable, full-stack enterprise application and solve real-world problems. It not only focuses on the APIs but also shows you how to set up a vanilla Maven build from scratch and do unit and integration testing—going into almost all parts of the Java EE 6 specs.GlassFish Community BOF Anil Gaur and Arun Gupta – Oracle (BOF4670) The GlassFish Community is large and vibrant and has had a tradition of getting together at JavaOne for the past few years. Attend this BOF to meet with the key members of the Oracle GlassFish team. They will share the roadmap for how Java EE 7 will provide a standards-based PaaS platform for running your enterprise Java applications in the cloud.Nashorn, Node, and Java Persistence Douglas Clarke and Akhil Arora – Oracle (BOF6661) With Project Nashorn, developers will have a full and modern JavaScript engine available on the JVM. In addition, they will have support for running Node applications with Node.jar. This unique combination of capabilities opens the door for best-of-breed applications combining Node with Java SE and Java EE.Meet the Java EE 7 Specification Leads Linda Demichiel, William Shannon – Oracle (BOF4213) This is your chance to meet face-to-face with the engineers who are developing the next version of the Java EE platform. In this session, the specification leads for the leading technologies that are part of the Java EE 7 platform discuss new and upcoming features and answer your questions. Come prepared with your questions, your feedback, and your suggestions for new features in Java EE 7 and beyond.The Arquillian Universe: A Tour Around the Astrophysics Lab Daniel Allen and Aslak Kntusen – Red Hat (CON6918) This presentation guides you through the Arquillian extensions by demonstrating how specific extensions solve common problematic testing scenarios faced by enterprise developers. You will get a overview of what is available and possible today as well as what is brewing in the community. Enterprise Service Architectures and the Cloud   This track has 61 sessions, 24 BoFs and 4 tutorials. The same as for the previous track applies here. That is far too many content to feature the one and only ones. So please see this as a good excuse to make your own decisions ;)GlassFish 4: From Clustering to the Cloud Fabien Leroy – SERLI (CON4930) Expected by the end of 2012, GlassFish 4 leverages the 3.1 clustering functionalities to enter into the cloud computing era. The session takes a look under the hood to show you what makes GlassFish 4 a PaaS solution able to dynamically allocate all the services needed by an application. See a live demo of GlassFish cloud features already running with a VMware virtual cluster.Making Apps Scale with CDI and Data Grids Manik Surtani – Red Hat (CON5875) This session walks through a live demo of building a Website with CDI, clustering it with Java EE clustering capabilities, and then introducing a data grid into the mix to dramatically boost performance and load-handling capacity.Utilize the Full Power of GlassFish Server and Java EE Security Masoud Kalali – Oracle (CON3964) In this session, learn how to utilize Java EE security and what GlassFish Server technology provides to address your security requirements. The presentation explains a two-phase authentication mechanism.Other News and Noteworthy Things   You might have heard that the Java Strategy, Partner, and Technical keynotes will be held on the Sunday of conference week, beginning at 4:00 p.m. at the historic Masonic Auditorium on Nob Hill. After the keynotes, attendees can go to the official JavaOne Open House at the Taylor Street Café @ the Zone. As in years past, Sunday will feature User Group meetings (at Moscone West) and Java University courses (Hilton San Francisco Union Square). On Thursday, the Java Community keynote will return. More information should flow out in the next couple of weeks. If you have not already done so, register.Planning to go? Have a look at my post 10 Ways to make the Best out of a Conference.Reference: JavaOne 2012 – 2400 hours to go! Some recommendations from our JCG partner Markus Eisele at the Enterprise Software Development with Java blog....
hamcrest-logo

Moving Beyond Core Hamcrest in JUnit

In the post Improving On assertEquals with JUnit and Hamcrest I introduced use of Hamcrest with JUnit. I then looked at JUnit’s Built-in Hamcrest Core Matcher Support. In this post, I look at how to apply Hamcrest’s non-core matchers with JUnit. These non-core matchers are NOT included with JUnit by default, but are available by including a Hamcrest JAR in the classpath.Although JUnit‘s inclusion of Hamcrest core matchers makes them easier to use if one only wants to use the core matchers, this inclusion can make use of the non-core matchers more difficult and is a well-known issue.Because the non-core Hamcrest matchers are not included with JUnit, the Hamcrest JAR needs to be downloaded. For my examples in this post, I am using hamcrest-all-1.2.jar.The next screen snapshot indicates the problems with combining the hamcrest-all JAR with the normal JUnit library (JUnit 4.10 as provided by NetBeans 7.2 beta in my example). As the screen snapshot indicates, when the junit-4.10.jar is included in the NetBeans libraries BEFORE the hamcrest-all-1.2.jar, the previously working code (from my previous post) breaks. Both NetBeans and the command-line compiler show this breakage in this screen snapshot.Switching the order of the test libraries so that the Hamcrest library is listed first and the JUnit JAR listed after it, makes the compiler break on the test code go away. This is shown in the next screen snapshot.Although switching the order of the dependent libraries so that the Hamcrest JAR is included before the JUnit JAR does prevent the build problem, this is not typically a satisfactory approach. This approach is too fragile for long-term maintainability. Fortunately, there is a better approach that JUnit directly supports to deal with this issue.A special Hamcrest-less JUnit JAR can be downloaded. The next screen snapshot shows the one I use in this example: junit-dep-4.10.jar. The -dep in the JAR name is the clue that it’s Hamcrest-free. The notation next to the JAR on the download page (screen snapshot shown next) points this out as well (“Jar without hamcrest”).With the Hamcrest-free “dep” version of the JUnit JAR, I can include it in the test libraries at any point I like with relation to the Hamcrest JAR and will still be able to build the test code. This is a much more favorable approach than relying on a specific order of test libraries. The next image shows the screen snapshot of NetBeans and the command-line build being successful even with the JUnit JAR listed first.With the appropriate libraries in use (JUnit-dep JAR and the Hamcrest “all” JAR), all of Hamcrest’s matchers can be used with JUnit-based tests. Hamcrest provides numerous matchers beyond the core matches that are now bundled with JUnit. One way to get an idea of the additional matchers available is to look at the classes in the Hamcrest JAR. The following is output from running a jar tvf command against the Hamcrest JAR and removing many of the entries to leave some of the most interesting ones. The “core” matchers tend to be based on the classes in the “core” package and the non-core matchers tend to be based on the classes in all the other packages without “core” in their name. 4029 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/AllOf.java 3592 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/AnyOf.java 1774 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/CombinableMatcher.java 1754 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/DescribedAs.java 1104 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/Every.java 2088 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/Is.java 1094 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsAnything.java 2538 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsCollectionContaining.java 1862 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsEqual.java 2882 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsInstanceOf.java 1175 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsNot.java 1230 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsNull.java 960 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/IsSame.java 675 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/StringContains.java 667 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/StringEndsWith.java 678 Thu May 21 23:21:20 MDT 2009 org/hamcrest/core/StringStartsWith.java 2557 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArray.java 1805 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArrayContaining.java 1883 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArrayContainingInAnyOrder.java 1765 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArrayContainingInOrder.java 1388 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsArrayWithSize.java 1296 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsCollectionWithSize.java 812 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsEmptyCollection.java 866 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsEmptyIterable.java 1086 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsIn.java 3426 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsIterableContainingInAnyOrder.java 3479 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsIterableContainingInOrder.java 993 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsIterableWithSize.java 1899 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsMapContaining.java 1493 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsMapContainingKey.java 1421 Thu May 21 23:21:20 MDT 2009 org/hamcrest/collection/IsMapContainingValue.java1380 Thu May 21 23:21:20 MDT 2009 org/hamcrest/number/IsCloseTo.java 2878 Thu May 21 23:21:20 MDT 2009 org/hamcrest/number/OrderingComparison.java1082 Thu May 21 23:21:20 MDT 2009 org/hamcrest/object/HasToString.java 918 Thu May 21 23:21:20 MDT 2009 org/hamcrest/object/IsCompatibleType.java 2080 Thu May 21 23:21:20 MDT 2009 org/hamcrest/object/IsEventFrom.java1164 Thu May 21 23:21:20 MDT 2009 org/hamcrest/text/IsEmptyString.java 1389 Thu May 21 23:21:20 MDT 2009 org/hamcrest/text/IsEqualIgnoringCase.java 2058 Thu May 21 23:21:20 MDT 2009 org/hamcrest/text/IsEqualIgnoringWhiteSpace.java 1300 Thu May 21 23:21:20 MDT 2009 org/hamcrest/text/StringContainsInOrder.java4296 Thu May 21 23:21:20 MDT 2009 org/hamcrest/xml/HasXPath.javaJUnit’s providing of a JAR without Hamcrest automatically built in (the “dep” JAR) allows developers to more carefully building up their classpaths if Hamcrest matchers above and beyond the “core” matchers are desired for use with JUnit.Reference: Moving Beyond Core Hamcrest in JUnit from our JCG partner Dustin Marx at the Inspired by Actual Events blog....
jaspersoft-jasperreports-logo

JasperReports JSF Plugin Use Cases Series

This is the entry point of an article series in which I will try to cover some of the use cases of JasperReport JSF Plugin, a tool created to easily integrate business reports designed for JasperReports in JSF applications. All the examples described in this series are available from the JasperReports JSF Plugin web site, at the samples section and will be part of the same business application: An online book store. The series will go through the steps needed to build the previous mentioned web application. I will try to keep the articles as neat, self-contained and complete as possible but I will deliberately omit some parts not specifically related with none of the main technologies exposed here. This way each article will go straight to the point and will be less verbose enabling easier understanding of main actors and their roles. Before getting deep into the material in which I will explain the different scenarios for JasperReports JSF Plugin we need to setup the web application project that will be the starting point for the further use cases. The main tools used in this series to work on that project are as follows:JasperReports 4.5.1 : the reporting engine. iReport 4.5.1 : the visual report designer Java Server Faces 1.2 & Facelets 1.1.1 : the web framework for my application (notice that this can be easily migrated into JSF 2.x). JasperReports JSF Plugin 1.0 : the integration bridge between the reporting engine and the web framework. Apache Derby 10.8.2.2 : database that will hold the information that we need. Apache Tomcat 6.0.35: the application server that I will use to deploy and test the application.The data to be shown by each specific report will come from a simple database with a few tables that will hold the information we need. The main entities that I will be using to compound the domain model are, basically: books, customers, orders and order lines. Contents1 Project Setup 2 Configuring iReport 3 The Domain Model 4 ConclusionProject Setup The approach I will follow is to create a new web-based project that will use that database model. I will use Maven to configure and manage the dependencies that I will use since I’m pretty used to it and it will avoid me to grab all the jar files independently and configure them in my code base by hand. Any other can use the tool of his/her preference (Ant, Gradle, IDE-based, etc.). A good example for doing this with Maven is the “simple-webapp” archetype sample from the Maven Book. I will post here the command line sentence I used to generate my project structure using that archetype: mvn archetype:create -DgroupId=net.sf.jasperreports.jsf.sample -DartifactId=jrjsf-usecases -Dpackage=net.sf.jasperreports.jsf.sample.usecases -Dversion=1.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeVersion=1.0 This will generate a Maven project in a folder with name jrjsf-usecases and with the following initial values:groupId: net.sf.jasperreports.jsf.sample artifactId: jrjsf-usecases version: 1.0-SNAPSHOT package: net.sf.jasperreports.jsf.sample.usecasesNow the pom.xml file needs to be modified a bit to hold the dependencies needed for our project. The main changes I will do will consist on adding support for Java 1.5 (and higher) and the dependencies to the items listed at the beginning of the article. To be able to use generics and other fancy features added to Java after the release of Java 5 we need to configure the maven-compiler-plugin so the Java compiler can recognise that we want support for those features: <project> ... <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <groupId>org.apache.maven.plugins</groupId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> </project> And now let’s add the dependencies we need to implement our application: <project> ... <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.4</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>el-api</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>javax.faces</groupId> <artifactId>jsf-api</artifactId> <version>1.2_14</version> </dependency> <dependency> <groupId>javax.faces</groupId> <artifactId>jsf-impl</artifactId> <version>1.2_14</version> </dependency> <dependency> <groupId>com.sun.facelets</groupId> <artifactId>jsf-facelets</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>4.5.1</version> </dependency> <dependency> <groupId>net.sf.jasperreports.jsf</groupId> <artifactId>jasperreports-jsf</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.apache.derby</groupId> <artifactId>derbyclient</artifactId> <version>10.8.2.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> </dependencies> </project> In this project we will be using a container-managed data source accessible through JNDI. This kind of configuration is dependant of the type of application server that we are using. Since I’m using Tomcat as my application server, I need to add a context.xml file to our project under the folder src/main/webapp/META-INF to tell it how to get access to that database and the type of resource I want: <Context path='/jrjsf-usecases' reloadable='true'><Resource name='jdbc/BookStoreDB' auth='Container' type='javax.sql.DataSource' maxActive='100' maxIdle='30' maxWait='10000' username='app' password='' driverClassName='org.apache.derby.jdbc.ClientDriver' url='jdbc:derby://localhost:1527/bookstoredb;create=true' /></Context>Configuring iReport We need to configure iReport to make it able to connect to our database so let’s launch the iReport design tool and configure it to have it ready for the design work. iReport doesn’t bring support to the Apache Derby database out-of-the-box, we need to add the libraries to its classpath and configure the Derby JDBC driver by hand. This exercise will teach us to configure the tool to support any other database by the way. First of all, download the Apache Derby database from its website and install it (decompress the zip file) in a folder of your choice in your local machine, if you haven’t done it yet. Then open iReport’s preferences/options window and select the classpath tab:I will add the Derby’s lib folder into the iReport classpath. To do so click on “Add Folder” button and browse your filesystem until you get to the lib folder inside the Apache Derby installation:Once done, click the OK button at preferences window and now the Apache Derby client classes should be available in iReport. At this moment we are ready to configure the Apache Derby datasource in iReport which is going to be used by our reports. To add a new datasource we can start from either the iReport welcome page and clicking on “Step 1: Create a database connection …” button or by clicking on the “Report datasources” button at the tool bar and then clicking on the “Add” button. Either way we will get to a window like the following:The Apache Derby datasource needs to be completely configured by hand in iReport so choose “Database JDBC connection” in the list from previous window, click on “Next >” and fill in the values for the JDBC driver in the next window:The values for the fields are as follows:Name: BookStoreDB JDBC Driver: org.apache.derby.jdbc.ClientDriver JDBC URL: jdbc:derby://localhost:1527/bookstoredb Username: app Password: <empty>Now, before continuing, make sure that your Apache Derby instance is running to allow connections against it and click on the “Test” button to check everything is fine. The Domain Model Let’s say that our project is configured and ready to start to work on it (we have a basic project folder structure and all the basic dependencies are in our classpath, and iReport is able to connect to our database) so let’s start with a bit of code. My first step in this area will be to create a SQL file (bookstore.create.sql) to initialize the domain model I’ve been talking about in the Introduction paragraph of this series. Copy the text below this paragraph and paste it into a file inside your project folder structure so you can use it later: create table book ( book_id int generated by default as identity primary key, title varchar(50) not null, author varchar(50) not null, published_year varchar(4) not null, genre varchar(20) not null, price numeric not null );create table customer ( customer_id int generated by default as identity primary key, name varchar(250) not null );create table purchase_order ( order_id int generated by default as identity primary key, customer_id int not null, created_date date not null,constraint customer_fk foreign key (customer_id) references customer(customer_id) );create table purchase_order_line ( order_line_id int generated by default as identity primary key, order_id int not null, book_id int not null, item_count int not null,constraint order_fk foreign key (order_id) references purchase_order(order_id), constraint book_fk foreign key (book_id) references book(book_id) ); This is just the backend part of my domain model, in my application I need to represent those entities as Java classes as well. So, to have this domain model complete my next step will be to write the Java classes that I need to represent the previous defined domain model inside my Java application. Now it’s time to take a look to previous model, we have 4 different entities so we will need 4 different classes inside our Java application to comply with that model: Book public class Book {private Long id;private String title;private String author;private String publishedYear;private String genre;private double price;public String getAuthor() { return author; }public void setAuthor(String author) { this.author = author; }public String getGenre() { return genre; }public void setGenre(String genre) { this.genre = genre; }public Long getId() { return id; }public void setId(Long id) { this.id = id; }public double getPrice() { return price; }public void setPrice(double price) { this.price = price; }public String getPublishedYear() { return publishedYear; }public void setPublishedYear(String publishedYear) { this.publishedYear = publishedYear; }public String getTitle() { return title; }public void setTitle(String title) { this.title = title; }} Customer public class Customer {private Long id;private String name;public Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }} Order public class Order {private Long id;private Customer customer;private Date createdDate;private List lines = new ArrayList();public Date getCreatedDate() { return createdDate; }public void setCreatedDate(Date createdDate) { this.createdDate = createdDate; }public Customer getCustomer() { return customer; }public void setCustomer(Customer customer) { this.customer = customer; }public Long getId() { return id; }public void setId(Long id) { this.id = id; }public List getLines() { return lines; }public void setLines(List lines) { this.lines = lines; }} OrderLine public class OrderLine {private Long id;private Order order;private Book book;private int itemCount;public Book getBook() { return book; }public void setBook(Book book) { this.book = book; }public Long getId() { return id; }public void setId(Long id) { this.id = id; }public int getItemCount() { return itemCount; }public void setItemCount(int itemCount) { this.itemCount = itemCount; }public Order getOrder() { return order; }public void setOrder(Order order) { this.order = order; }} Now, use the tool of your choice to connect to your database and execute the bookstoredb.create.sql file to create the table structure. Conclusion I’m trying to keep the code as simple and clean as possible. The Java classes listed in the previous section can be mapped to our relational database using ORM tools such as Hibernate, iBATIS, Ebean, etc. I leave the choice of the Object Relational Mapping layer to the reader as there are many choices and none of them will affect the way we integrate our report with the web framework. Our web application should contain other classes to compose its architecture as DAO’s and business facades and view controllers. However, adding all of them in this article is completely out of scope for the same reason that I am not adding any ORM information that may help to link the model classes to the database tables. There are a lot of IoC containers out there nowadays (Spring Framework, Weld, Seam, etc) and what really matters in this series is to demonstrate the usage of the JasperReports JSF Plugin. (View controllers will be listed in its specific article as they are part of each specific use case). And this is all we need to start working in the different examples of this nifty tool. During the next weeks new articles will be published under the JasperReports JSF Plugin category giving detailed examples that demonstrate how implement the most common use cases. Hope you enjoy them, any comments are welcome. Reference: JasperReports JSF Plugin Use Cases Series from our JCG partner Alonso Dominguez at the Code Nibbles blog....
jsf-logo

Full WebApplication JSF EJB JPA JAAS – Part 1

This post will be the biggest so far in my blog! We will see a full web application. It will be done will the newest technologies (until today), but I will give some hints to show how to adapt this post to older technologies. In the end of this post you will find the source code to download. You can use it as you wish. Just go to the last page and do the download. \o/ If you downloaded the code and did not understand something, in this post I will explain every detail found in the code. Just read the subject inside this post that you want. I will list bellow the technologies that I will use in this post:JSF 2.0 Mojarra – With ManagedBeans as RequestScope and SessionScope. Message Internationalization – File that will have all the messages of our system; it will be easier to translate you pages. Default CSS file that will be imported as a library. EJB 3 – Our DAOs and Façades will be @Stateless. Generic DAO – A generic DAO that will have the CRUD actions to make our life easier. JPA 2 – To map our classes in the DB JAAS – To control the login and the user access to the pages. MVC – I will use this pattern with small modifications. Postgres as database, but I will show how to set up your app to MySQL also.I will not use TDD – JUnit to test our View/Model/Classes, but in the following link you can see a technique to use the JUnit to test your ManagedBeans: JUnit with HSQLDB, JPA and Hibernate. Tools that we will use:Eclipse Indigo – http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/indigor I will use JBoss 7 (some readers of this blog asked me for it) – http://download.jboss.org/jbossas/7.0/jboss-as-7.0.2.Final/jboss-as-7.0.2.Final.zip the version is: JBoss 7 Everything (NOT Java EE6 Certified). Indigo JBoss Tools (milestone version) – https://www.jboss.org/tools/download/dev.html if you do not know how to install the JBoss Tools in this post I will show how to (User Login Validation with JAAS and JSF). Be aware that in the post I will show how to install to another eclipse version, but the difference is the URL; use this URL instead the URL used in the link above: http://download.jboss.org/jbosstools/updates/development/indigo/ I will use the Postgres database but you can use any database you want; you will need only to download the database and the JDBC driver. Here you can download the latest Postgres JDBC: http://jdbc.postgresql.org/download.html; the latest version so far is the 4: http://jdbc.postgresql.org/download/postgresql-9.1-901.jdbc4.jar.This post will have several pages; this first page is just to show the technical details of the post today. I will not code to interface my model/DAO, just to save space. Remember that you should always code to interfaces (Design Pattern – Strategy). Before you continue be sure that you installed the JBoss Tools and the JBoss 7 in this exactly order. Business – Model Let us create the EJB project that will hold our system business.Click in the “Finish” button. Let us create the User and Dog classes that will be inside the “com” package. It will have the code bellow: package com.model;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.NamedQuery; import javax.persistence.Table;@Entity @Table(name = 'USERS') @NamedQuery(name='User.findUserByEmail', query='select u from User u where u.email = :email') public class User {public static final String FIND_BY_EMAIL = 'User.findUserByEmail';@Id @GeneratedValue(strategy=GenerationType.AUTO) private int id;@Column(unique = true) private String email; private String password; private String name; private String role;public int getId() { return id; }public void setId(int id) { this.id = id; }public String getEmail() { return email; }public void setEmail(String email) { this.email = email; }public String getPassword() { return password; }public void setPassword(String password) { this.password = password; }public String getName() { return name; }public void setName(String name) { this.name = name; }public String getRole() { return role; }public void setRole(String role) { this.role = role; }@Override public int hashCode() { return getId(); }@Override public boolean equals(Object obj) { if(obj instanceof User){ User user = (User) obj; return user.getEmail().equals(getEmail()); }return false; } } package com.model;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table;@Entity @Table(name = 'DOGS') public class Dog {@Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String name; private double weight;public int getId() { return id; }public void setId(int id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public double getWeight() { return weight; }public void setWeight(double weight) { this.weight = weight; }@Override public int hashCode() { return getId(); }@Override public boolean equals(Object obj) {if(obj instanceof Dog){ Dog dog = (Dog) obj; return dog.getId() == getId(); }return false; } } About the code above:The User class has a field named “role” that will store the role level of the user. I created as a single field and we will leave all data in the same table just to make easier to understand. If you want more details about JAAS you can in this post: User Login Validation with JAAS and JSF. I will let the JPA handle the tables Id generations. If you want to change the way of the Id creation you can check this posts to see how to do it: JPA SequenceGenerator, JPA TableGenerator – Simple Primay Key. The email will be unique; it will be the login identifier. Notice that a class to be declared as Entity, it only needs the following annotations: “@Entity” and “@Id”. The class does not need to implement the Serializable interface.Business – DAOs I will use a generic DAO to basic CRUD operations and others two DAOs: one for User and another for Dog. It will be very easy to understand its use: package com.dao;import java.util.List; import java.util.Map; import java.util.Map.Entry;import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.criteria.CriteriaQuery;public abstract class GenericDAO<T> { private final static String UNIT_NAME = 'CrudPU';@PersistenceContext(unitName = UNIT_NAME) private EntityManager em;private Class<T> entityClass;public GenericDAO(Class<T> entityClass) { this.entityClass = entityClass; }public void save(T entity) { em.persist(entity); }public void delete(T entity) { T entityToBeRemoved = em.merge(entity);em.remove(entityToBeRemoved); }public T update(T entity) { return em.merge(entity); }public T find(int entityID) { return em.find(entityClass, entityID); }// Using the unchecked because JPA does not have a // em.getCriteriaBuilder().createQuery()<T> method @SuppressWarnings({ 'unchecked', 'rawtypes' }) public List<T> findAll() { CriteriaQuery cq = em.getCriteriaBuilder().createQuery(); cq.select(cq.from(entityClass)); return em.createQuery(cq).getResultList(); }// Using the unchecked because JPA does not have a // ery.getSingleResult()<T> method @SuppressWarnings('unchecked') protected T findOneResult(String namedQuery, Map<String, Object> parameters) { T result = null;try { Query query = em.createNamedQuery(namedQuery);// Method that will populate parameters if they are passed not null and empty if (parameters != null && !parameters.isEmpty()) { populateQueryParameters(query, parameters); }result = (T) query.getSingleResult();} catch (Exception e) { System.out.println('Error while running query: ' + e.getMessage()); e.printStackTrace(); }return result; }private void populateQueryParameters(Query query, Map<String, Object> parameters) {for (Entry<String, Object> entry : parameters.entrySet()) { query.setParameter(entry.getKey(), entry.getValue()); } } } package com.dao;import javax.ejb.Stateless;import com.model.Dog;@Stateless public class DogDAO extends GenericDAO<Dog> {public DogDAO() { super(Dog.class); } } package com.dao;import java.util.HashMap; import java.util.Map;import javax.ejb.Stateless;import com.model.User;@Stateless public class UserDAO extends GenericDAO<User> {public UserDAO() { super(User.class); }public User findUserByEmail(String email){ Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put('email', email);return super.findOneResult(User.FIND_BY_EMAIL, parameters); } } About the code above:I hid some warnings because the JPA code does not “understand” generics yet. The method “findOneResult” is with protected access just to prevent external access from other classes; this method requires logic to populate the parameters as we can see in the UserDAO. The class GenericDAO has a complete CRUD methods plus a method that returns a single object given a NamedQuery. The UserDAO class has a method (findUserByEmail) that belongs only to the class; but it has all CRUD methods by inheritance. With this pattern of DAOs we got a code more flexible. The DogDAO has no method in it but only the CRUD methods; you could implement any method in the class without problem. Instead using a method to “save” and other to “update” your objects you could use one method “entityManager.merge()”. You will have the same result but you will need to pay attention to the Cascade options. I did not use Interfaces because EJB 3.1 allows us to have Stateless Local Session Beans without interface. If you are using an older EJB version you will need to implement an interface (how to Implement EJBs with interfaces we will see in this post, in the Façades page). I will not develop with interfaces my DAO/Model just to save space in this post. Remember: “Always program to an interface” (Design Pattern – Strategy). If you use the JBoss 4.2 you could use the org.jboss.annotation.ejb.LocalBinding or org.jboss.annotation.ejb.RemoteBinding annotations; in this annotation you can write the name that will be mapped and referred by the EJB.Business – Façades I will create Façades that will be the “bridge” between the View and the DAO. In the Façade we will leave all the business rules leaving the DAO only the “database” functions/transactions, e.g. CRUD and queries. Let us see how our class UserFacade and DogFacade will be: package com.facade;import java.util.List;import javax.ejb.Local;import com.model.Dog;@Local public interface DogFacade {public abstract void save(Dog dog);public abstract Dog update(Dog dog);public abstract void delete(Dog dog);public abstract Dog find(int entityID);public abstract List<Dog> findAll(); } package com.facade;import java.util.List;import javax.ejb.EJB; import javax.ejb.Stateless;import com.dao.DogDAO; import com.model.Dog;@Stateless public class DogFacadeImp implements DogFacade {@EJB private DogDAO dogDAO;@Override public void save(Dog dog) { isDogWithAllData(dog);dogDAO.save(dog); }@Override public Dog update(Dog dog) { isDogWithAllData(dog);return dogDAO.update(dog); }@Override public void delete(Dog dog) { dogDAO.delete(dog); }@Override public Dog find(int entityID) { return dogDAO.find(entityID); }@Override public List<Dog> findAll() { return dogDAO.findAll(); }private void isDogWithAllData(Dog dog){ boolean hasError = false;if(dog == null){ hasError = true; }if (dog.getName() == null || ''.equals(dog.getName().trim())){ hasError = true; }if(dog.getWeight() <= 0){ hasError = true; }if (hasError){ throw new IllegalArgumentException('The dog is missing data. Check the name and weight, they should have value.'); } } } package com.facade;import javax.ejb.Local;import com.model.User;@Local public interface UserFacade { public User findUserByEmail(String email); } package com.facade;import javax.ejb.EJB; import javax.ejb.Stateless;import com.dao.UserDAO; import com.model.User;@Stateless public class UserFacadeImp implements UserFacade {@EJB private UserDAO userDAO;public User findUserByEmail(String email) { return userDAO.findUserByEmail(email); } } About the code above:The DogFacadeImp class does all the work of protecting the DogDAO from the view. It might have the business rules and avoid access to the database if some data is missing or any other business rule has being broken. The UserFacade has only one method because we will not have a User crud in this post; the bean will only search for a User if the view does not find it in the HttpSession. If you use the JBoss 4.2 you could use the org.jboss.annotation.ejb.LocalBinding or org.jboss.annotation.ejb.RemoteBinding annotations; in this annotation you can write the name that will be mapped and referred by the EJB. I do a validation in the DogFacadeImp to be sure that the Dog has only valid data. Remember that everyone can send you invalid data and your view validation may not work as you expect. The data of your application is very important and a double check is always worth.The interfaces are annotated with the @Local but I remember you that this annotation is optional. If you do no write the @Local annotation your server will assume that your EJB is local by default. Business – Datasource (by module) We also need to setup our datasource. At first I tried to create a datasource by following this tutorial http://community.jboss.org/wiki/JBossAS7-DatasourceConfigurationForPostgresql (I do follow tutorials just like any other human being does), but several errors started to happen after deploy with EJBs and the JBoss could not locate the Postgres jar. If you are using the JBoss 6 or any version under it you do not need to create the module; just put the file in the “default/lib” folder. If you have any doubt about set up a datasource, I show how to do it, in the JBoss 6 or other version under it, here: User Login Validation with JAAS and JSF. Let us create the Postgres module. Inside your JBoss 7 create the directory: “YOUR_JBOSS/modules/org/postgresql/main”. Copy the jar to the created directory and create a file named “module.xml”; copy the code bellow inside the “module.xml” file: <?xml version='1.0' encoding='UTF-8'?> <module xmlns='urn:jboss:module:1.0' name='org.postgresql'> <resources> <resource-root path='postgresql-9.1-901.jdbc4.jar'/> </resources> <dependencies><module name='javax.api'/></dependencies> </module> Notice that inside the “module.xml” file we have the jar file name written, the name must be the same of the Postgres jar file name. To create the MySQL module create the following folder “YOUR_JBOSS/modules/com/mysql/main”. Copy the jar to the created directory and create a file named “module.xml”; copy the code bellow inside the “module.xml” file: <?xml version='1.0' encoding='UTF-8'?><!-- ~ JBoss copyrights ~ http://community.jboss.org/wiki/DataSourceConfigurationInAS7 --><module xmlns='urn:jboss:module:1.0' name='com.mysql'> <resources> <resource-root path='mysql-connector-java-5.1.15.jar'/> </resources> <dependencies> <module name='javax.api'/> </dependencies> </module> Let us edit the file “YOUR_JBOSS/standalone/configuration/standalone.xml”. Inside the key “<datasources>” add the code bellow: <datasources> <!-- Add this config: begin --> <datasource jndi-name='CrudDS' pool-name='CrudDS_Pool' enabled='true' jta='true' use-java-context='true' use-ccm='true'> <connection-url>jdbc:postgresql://localhost:5432/CrudDB</connection-url> <driver-class>org.postgresql.Driver</driver-class> <driver>postgresql-jdbc4</driver> <pool> <min-pool-size>2</min-pool-size> <max-pool-size>20</max-pool-size> <prefill>true</prefill> <use-strict-min>false</use-strict-min> <flush-strategy>FailingConnectionOnly</flush-strategy> </pool> <security> <user-name>postgres</user-name> <password>postgres</password> </security> <validation> <check-valid-connection-sql>SELECT 1</check-valid-connection-sql> <validate-on-match>false</validate-on-match> <background-validation>false</background-validation> <use-fast-fail>false</use-fast-fail> </validation> </datasource> <!-- Add this config: end --> <drivers> <!-- Add this config: begin --> <driver name='postgresql-jdbc4' module='org.postgresql'/> <!-- Add this config: end --> </drivers> To configure your datasource with MySQL take a look here: http://community.jboss.org/wiki/DataSourceConfigurationInAS7 Business – XML Configurations Let us see how our persistence.xml will be (this file must be inside the folder src/META-INF): <?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='CrudPU' transaction-type='JTA'> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/CrudDS</jta-data-source> <properties> <property name='hibernate.hbm2ddl.auto' value='update'/> </properties> </persistence-unit> </persistence> We got a very simple code; it is just pointing to a datasource and the option to generate all the database tables with “update”. Add the EJB project to the JBoss. Create the database in the Postgres and start the JBoss; after you started it the JPA will create the tables. Check the image bellow to see the tables/sequences that the JPA created for us.Create a file named “jboss-web.xml” inside the WEB-INF folder and write the code bellow in it: <?xml version='1.0' encoding='UTF-8'?><jboss-web> <!-- URL to access the web module --> <context-root>CrudJSF</context-root><!-- Realm that will be used --> <security-domain>java:/jaas/CrudJSFRealm</security-domain> </jboss-web> In the file above we set up the Realm that our application will use. Let us insert the users in the database that will do the login by the JAAS (if you want to see more details about JAAS you can see it here: User Login Validation with JAAS and JSF). I will not get in the JAAS details because you can find every step detailed in the previous link. See in the image bellow the data that I inserted manually in the database (you should do the same):Continue to the second part of the tutorial. Reference: Full WebApplication JSF EJB JPA JAAS from our JCG partner Hebert Coelho at the uaiHebert blog....
jsf-logo

Full WebApplication JSF EJB JPA JAAS – Part 2

View – Creation and JSF set up This tutorial continues from part 1. Let us create a new Dynamic Web Project. Create it like the image bellow:Pay attention: in some moment the Eclipse will ask you if you want to add the JSF Capabilities (auto complete), enable it. Like the screens bellow:After the project creation, let us edit the “web.xml” file; it should have the same code as bellow: <?xml version='1.0' encoding='UTF-8'?> <web-app xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://java.sun.com/xml/ns/javaee' xmlns:web='http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd' id='WebApp_ID' version='3.0'> <display-name>CrudJSF</display-name> <welcome-file-list> <welcome-file>pages/protected/user/listAllDogs.xhtml</welcome-file> </welcome-file-list> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> <url-pattern>*.jsf</url-pattern> <url-pattern>*.xhtml</url-pattern> </servlet-mapping><!-- Protected area definition --> <security-constraint> <web-resource-collection> <web-resource-name>Restricted Area - ADMIN Only</web-resource-name> <url-pattern>/pages/protected/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>ADMIN</role-name> </auth-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>Restricted Area - USER and ADMIN</web-resource-name> <url-pattern>/pages/protected/user/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>USER</role-name> <role-name>ADMIN</role-name> </auth-constraint> </security-constraint><!-- Login page --> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/pages/public/login.xhtml</form-login-page> <form-error-page>/pages/public/loginError.xhtml</form-error-page> </form-login-config> </login-config><!-- System roles --> <security-role> <role-name>ADMIN</role-name> </security-role> <security-role> <role-name>USER</role-name> </security-role> </web-app> You do not have to worry if some warning/error shows up; we will solve them later. Notice that I have added all the JAAS code that we will need (If you want a detailed post about these JAAS configurations you can check it here: User Login Validation with JAAS and JSF). According to the JAAS configurations a regular user (USER role) will only see the files inside the user folder, that will be only the listing of the dogs recorded in our database; the ADMIN will be able to do all the CRUD actions because all the pages are inside the admins folder. Our “faces-config.xml” should have the code bellow: <?xml version='1.0' encoding='UTF-8'?><faces-config xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd' version='2.0'><navigation-rule> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/pages/protected/user/listAllDogs.xhtml</to-view-id> <redirect/> </navigation-case> </navigation-rule> <navigation-rule> <navigation-case> <from-outcome>listAllDogs</from-outcome> <to-view-id>/pages/protected/user/listAllDogs.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <navigation-case> <from-outcome>createDog</from-outcome> <to-view-id>/pages/protected/admin/createDog.xhtml</to-view-id> <redirect/> </navigation-case> </navigation-rule> <navigation-rule> <navigation-case> <from-outcome>updateDog</from-outcome> <to-view-id>/pages/protected/admin/updateDog.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <navigation-case> <from-outcome>deleteDog</from-outcome> <to-view-id>/pages/protected/admin/deleteDog.xhtml</to-view-id> </navigation-case> </navigation-rule><application> <resource-bundle> <base-name>messages</base-name> <var>msgs</var> </resource-bundle> </application></faces-config> Notice that to some actions I used the redirect action. With this action we will update the requested link in the URL bar of the browser, after the URL get updated the JAAS will deny access to an illegal user. We also have a file that will contain all the messages of our system. You will notice that all the texts displayed in our pages are in this file (create a file named “messages.properties” inside the src folder): #Dog dog=Dog dogName=Name dogWeight=Weight#Dog messages dogCreateHeader=Create a new Dog dogUpdateHeader=Update the Dog dogDeleteHeader=Delete this Dog dogNameRequired=The dog needs a name. dogWeightRequired=The dog needs a weight.#Actions update=Update create=Create delete=Delete cancel=Cancel#Login loginHello=Hello loginErrorMessage=Could not login. Check you UserName/Password loginUserName=Username loginPassword=Password logout=Log Out View – Creation and JSF set up Let us now create the ManagedBeans. First, we need to add the EJB to the Web Project. Right click with your mouse on the JSF project > Properties:Java Build Path > Projects > Add > Check CrudEJB > OKFirst, let us create the DogMB: package com.mb;import java.util.List;import javax.ejb.EJB; import javax.ejb.EJBException; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.context.FacesContext;import com.facade.DogFacade; import com.model.Dog;@ManagedBean @RequestScoped public class DogMB {@EJB private DogFacade dogFacade;private static final String CREATE_DOG = 'createDog'; private static final String DELETE_DOG = 'deleteDog'; private static final String UPDATE_DOG = 'updateDog'; private static final String LIST_ALL_DOGS = 'listAllDogs'; private static final String STAY_IN_THE_SAME_PAGE = null;private Dog dog;public Dog getDog() {if(dog == null){ dog = new Dog(); }return dog; }public void setDog(Dog dog) { this.dog = dog; }public List<Dog> getAllDogs() { return dogFacade.findAll(); }public String updateDogStart(){ return UPDATE_DOG; }public String updateDogEnd(){ try { dogFacade.update(dog); } catch (EJBException e) { sendErrorMessageToUser('Error. Check if the weight is above 0 or call the adm'); return STAY_IN_THE_SAME_PAGE; }sendInfoMessageToUser('Operation Complete: Update'); return LIST_ALL_DOGS; }public String deleteDogStart(){ return DELETE_DOG; }public String deleteDogEnd(){ try { dogFacade.delete(dog); } catch (EJBException e) { sendErrorMessageToUser('Error. Call the ADM'); return STAY_IN_THE_SAME_PAGE; }sendInfoMessageToUser('Operation Complete: Delete');return LIST_ALL_DOGS; }public String createDogStart(){ return CREATE_DOG; }public String createDogEnd(){ try { dogFacade.save(dog); } catch (EJBException e) { sendErrorMessageToUser('Error. Check if the weight is above 0 or call the adm');return STAY_IN_THE_SAME_PAGE; }sendInfoMessageToUser('Operation Complete: Create');return LIST_ALL_DOGS; }public String listAllDogs(){ return LIST_ALL_DOGS; }private void sendInfoMessageToUser(String message){ FacesContext context = getContext(); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, message)); }private void sendErrorMessageToUser(String message){ FacesContext context = getContext(); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message)); }private FacesContext getContext() { FacesContext context = FacesContext.getCurrentInstance(); return context; } } About the code above:All navigation you will find in the faces-config.xml. You should use constants or a resource bundle with the navigations of your pages; this approach is a better approach than just leave strings in your methods. Notice that we are only using @EJB to inject the EJB inside of the MB. This happens because we are using everything inside the same EAR. The JBoss 7 turns easy this localization. If the injection does not work with JBoss 6 (or if you are using the EJB jar outside the EAR) you can use the injection like this: @EJB(mappedName=“DogFacadeImp/local”). Notice that a message is displayed to the user of our system. We have a try/catch to each action that we execute in the Façade, if some error happens we will send an error message to the user. The correct actions would be to validate the data in the ManagedBean and in the Façade. Those validations have a low CPU cost. If you are using the JBoss 4.2 you will need to do a JNDI lookup like the code bellow(just like a said earlier in this post use the LocalBinding annotation). Annotate your class like this: @Stateless @LocalBinding(jndiBinding='MyBean') public class MyBeanImp implements MyBean{ @Override public String hello() { return 'Value From EJB'; } } // In your Servlet class you would lookup like the code bellow: public class Inject extends HttpServlet {private MyBean local;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { InitialContext iniCtx = new InitialContext(); local = (MyBean) iniCtx.lookup('MyBean'); } catch (NamingException e) { e.printStackTrace(); }System.out.println(local.hello()); request.getRequestDispatcher('/finish.jsp').forward(request, response); }/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {} }Now Let us see the UserMB: package com.mb;import javax.ejb.EJB; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.servlet.http.HttpServletRequest;import com.facade.UserFacade; import com.model.User;@SessionScoped @ManagedBean public class UserMB { private User user;@EJB private UserFacade userFacade;public User getUser(){ if(user == null){ ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); String userEmail = context.getUserPrincipal().getName();user = userFacade.findUserByEmail(userEmail); }return user; }public boolean isUserAdmin(){ return getRequest().isUserInRole('ADMIN'); }public String logOut(){ getRequest().getSession().invalidate(); return 'logout'; }private HttpServletRequest getRequest() { return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest(); } } About the code above:This MB is only used to store the session user of our application. You will use this MB to display the user name or any other action regarding the user of the application. Notice that this is a Session MB; we check just one time if the user is null, and if returns true, we will go to the database. With this condition we will go just once to the database saving performance. If the @EJB injection raises an exception, check the tips given in the DogMB above.View – Pages Bellow the pages, css and its respective paths:Do not mind with the interrogation icons or any other icon type that is displayed in the picture above. Those are versioning icons that points to my code. Always save your code. I am using RequestScope in the ManagedBean, which is why you will see the h:inputHidden in all my pages. I think it is a better approach for you to repeat this field with RequestScope MBs because you will have more free memory in your server instead using SessionScope MBs. /WebContent/resources/css/main.css .table { border-collapse: collapse; }.tableColumnsHeader { text-align: center; background: none repeat scroll 0 0 #E5E5E5; border-bottom: 1px solid #BBBBBB; padding: 16px; }.tableFirstLine { text-align: center; background: none repeat scroll 0 0 #F9F9F9; border-top: 1px solid #BBBBBB; }.tableNextLine { text-align: center; background: none repeat scroll 0 0 #FFFFFFF; border-top: 1px solid #BBBBBB; }.panelGrid { border: 1px solid; }.panelFirstLine { text-align: center; border-top: 1px solid #BBBBBB; }.panelNextLine { text-align: center; border-top: 1px solid #BBBBBB; } /WebContent/pages/public/login.xhtml <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:f='http://java.sun.com/jsf/core' xmlns:h='http://java.sun.com/jsf/html' xmlns:ui='http://java.sun.com/jsf/facelets'> <h:head> <h:outputStylesheet library='css' name='main.css' /> </h:head> <h:body> <p>Login to access secure pages:</p> <form method='post' action='j_security_check'> <h:messages layout='table' errorStyle='background: #AFEEEE;' infoStyle='background: #AFEEEE;' globalOnly='true' /> <h:panelGrid columns='2'> <h:outputLabel value='Username: ' /> <input type='text' id='j_username' name='j_username' /> <h:outputLabel value='Password: ' /> <input type='password' id='j_password' name='j_password' /> <h:outputText value='' /> <h:panelGrid columns='1'> <input type='submit' name='submit' value='Login' /> </h:panelGrid> </h:panelGrid> <br /> </form> </h:body> </html> Notice how we import the css like if it was a library. The action that you see in the form tag, points to an unknown action to us, but is the JAAS the responsible to manage that. /WebContent/pages/public/loginError.xhtml <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:f='http://java.sun.com/jsf/core' xmlns:h='http://java.sun.com/jsf/html' xmlns:ui='http://java.sun.com/jsf/facelets'> <h:head> <h:outputStylesheet library='css' name='main.css' /> </h:head> <h:body> #{msgs.loginErrorMessage} </h:body> </html> /WebContent/pages/protected/user/listAllDogs.xhtml <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:f='http://java.sun.com/jsf/core' xmlns:h='http://java.sun.com/jsf/html' xmlns:ui='http://java.sun.com/jsf/facelets'> <h:head> <h:outputStylesheet library='css' name='main.css' /> </h:head> <h:body> <h:form> <h3>#{msgs.loginHello}: #{userMB.user.name} || <h:commandLink action='#{userMB.logOut()}' value='#{msgs.logout}' /> </h3><h:messages /> <h:dataTable value='#{dogMB.allDogs}' var='dog' styleClass='table' headerClass='tableColumnsHeader' rowClasses='tableFirstLine,tableNextLine' > <h:column> <f:facet name='header'> #{msgs.dogName} </f:facet>#{dog.name} </h:column> <h:column> <f:facet name='header'> #{msgs.dogWeight} </f:facet>#{dog.weight} </h:column> <h:column> <h:panelGrid columns='2'> <!-- Always save the id as hidden when you use a request scope MB --> <h:inputHidden value='#{dog.id}' /><h:commandButton action='#{dogMB.updateDogStart()}' value='#{msgs.update}' rendered='#{userMB.userAdmin}' > <f:setPropertyActionListener target='#{dogMB.dog}' value='#{dog}' /> </h:commandButton> <h:commandButton action='#{dogMB.deleteDogStart()}' value='#{msgs.delete}' rendered='#{userMB.userAdmin}' > <f:setPropertyActionListener target='#{dogMB.dog}' value='#{dog}' /> </h:commandButton> </h:panelGrid> </h:column> </h:dataTable> <!-- This button is displayed to the user, just to you see the error msg --> <h:commandButton action='createDog' value='#{msgs.create} #{msgs.dog}' /> </h:form> </h:body> </html> About the code above:Always remember to wrap your code with the h:form tag. There are frameworks (like Primefaces) that will not work without the h:form, h:head and h:body. We use the UserMB to display the user name and to logout our user. The <h:messages /> tag will display the messages sent by the DogMB. Notice that in the line 33 the id is hidden. It is a necessary value if you use RequestScope instead SessionScope. I rather use RequestScope than SessionScope, your server memory will have less data in it. Notice that the buttons have the rendered=”#{userMB.userAdmin}” to indicate that only the ADMIN role will have access to the delete/update. I am passing to my MB the selected dog through the tag : “f:setPropertyActionListener”. The “create” button does not have the rendered option. It is just to display to you if a regular user tries to access a page./WebContent/pages/protected/admin/createDog.xhtml <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:f='http://java.sun.com/jsf/core' xmlns:h='http://java.sun.com/jsf/html' xmlns:ui='http://java.sun.com/jsf/facelets'> <h:head> <h:outputStylesheet library='css' name='main.css' /> </h:head> <h:body> <h:form> <h:messages/><h3>${msgs.dogCreateHeader}</h3> <h:panelGrid columns='2' styleClass='panelGrid' rowClasses='panelFirstLine,panelNextLine' > <h:outputLabel for='dogName' value='#{msgs.dogName}' /> <h:inputText id='dogName' value='#{dogMB.dog.name}' required='true' requiredMessage='#{msgs.dogNameRequired}' /><h:outputLabel for='dogWeight' value='#{msgs.dogWeight}' /> <h:inputText id='dogWeight' value='#{dogMB.dog.weight}' required='true' requiredMessage='#{msgs.dogWeightRequired}' > <f:convertNumber /> </h:inputText> </h:panelGrid> <h:panelGrid columns='2'> <h:commandButton action='#{dogMB.createDogEnd()}' value='#{msgs.create}' /> <h:commandButton action='#{dogMB.listAllDogs()}' value='#{msgs.cancel}' immediate='true' /> </h:panelGrid> <br/> </h:form> </h:body> </html> About the code above:The fields name and weight are required and will print an error message if you leave it empty. The cancel button needs the option immediate=“true”; with this option the JSF will not validate any field./WebContent/pages/protected/admin/deleteDog.xhtml <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:f='http://java.sun.com/jsf/core' xmlns:h='http://java.sun.com/jsf/html' xmlns:ui='http://java.sun.com/jsf/facelets'> <h:head> <h:outputStylesheet library='css' name='main.css' /> </h:head> <h:body> <h:form> <h:messages/><h3>#{msgs.dogDeleteHeader}: #{dogMB.dog.name}?</h3> <h:inputHidden value='#{dogMB.dog.id}' /> <h:panelGrid columns='2'> <h:commandButton action='#{dogMB.deleteDogEnd()}' value='#{msgs.delete}' /> <h:commandButton action='#{dogMB.listAllDogs()}' value='#{msgs.cancel}' immediate='true' /> </h:panelGrid> <br/> </h:form> </h:body> </html> Notice that in the line 15 the id is hidden. It is a necessary value if you use RequestScope instead SessionScope. I rather use RequestScope than SessionScope, your server memory will have less data in it. /WebContent/pages/protected/admin/updateDog.xhtml <!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:f='http://java.sun.com/jsf/core' xmlns:h='http://java.sun.com/jsf/html' xmlns:ui='http://java.sun.com/jsf/facelets'> <h:head> <h:outputStylesheet library='css' name='main.css' /> </h:head> <h:body> <h:form> <h:messages/><h3>#{msgs.dogUpdateHeader}: #{dogMB.dog.name}</h3> <h:inputHidden value='#{dogMB.dog.id}' /> <h:panelGrid columns='2' styleClass='panelGrid' rowClasses='panelFirstLine,panelNextLine' > <h:outputLabel for='dogName' value='#{msgs.dogName}' /> <h:inputText id='dogName' value='#{dogMB.dog.name}' required='true' requiredMessage='#{msgs.dogNameRequired}' /><h:outputLabel for='dogWeight' value='#{msgs.dogWeight}' /> <h:inputText id='dogWeight' value='#{dogMB.dog.weight}' required='true' requiredMessage='#{msgs.dogWeightRequired}' > <f:convertNumber /> </h:inputText> </h:panelGrid> <h:panelGrid columns='2'> <h:commandButton action='#{dogMB.updateDogEnd()}' value='#{msgs.update}' /> <h:commandButton action='#{dogMB.listAllDogs()}' value='#{msgs.cancel}' immediate='true' /> </h:panelGrid> <br/> </h:form> </h:body> </html> About the code above:Notice that in the line 15 the id is hidden. It is a necessary value if you use RequestScope instead SessionScope. I rather use RequestScope than SessionScope, your server memory will have less data in it. The fields name and weight are required and will print an error message if you leave it empty. The cancel button needs the option immediate=“true”; with this option the JSF will not validate any field.View – JBoss 7 JAAS Configuration Now we need just a few more steps to finish our software (Finally!). We need to edit the JBoss configurations and to add our JAAS configurations. Open again the file “YOUR_JBOSS/standalone/configuration/standalone.xml” and search for the key: “<security-domains>”. Add the code bellow (In this post I show how to do this set up for JBoss 6 – User Login Validation with JAAS and JSF): <subsystem xmlns='urn:jboss:domain:security:1.0'> <security-domains> <!-- add me: begin --> <security-domain name='CrudJSFRealm' cache-type='default'> <authentication> <login-module code='org.jboss.security.auth.spi.DatabaseServerLoginModule' flag='required'> <module-option name='dsJndiName' value='CrudDS'/> <module-option name='principalsQuery' value='select password from users where email=?' /> <module-option name='rolesQuery' value='select role, 'Roles' from users u where u.email=?' /> </login-module> </authentication> </security-domain> <!-- add me: end --><!-- Other data... --> </security-domains> </subsystem> Running our Application Let us create an EAR to unite our projects. File > New > Other >EnterpriseApplication ProjectWe just need to have in our JBoss the EAR added.Let us run our application. Start the JBoss and access our application by the URL: http://localhost:8080/CrudJSF/. I wrote the pages with a simple CSS to make easier the understanding. Login as USER and you will not see the update/delete buttons; you will only see the Create button that we left there just to see an exception off illegal access. Take a look bellow at our pages: Logged as ADMIN:Logged as USER:That is all for today To download the source code of this post, click here. I hope this post might help you. If you have any doubt or comment just post it bellow. See you soon. \o_ Links that helped me: http://7thursdays.wordpress.com/2008/03/18/dependency-injection-in-jboss-42-hold-your-excitement/ http://jan.zawodny.pl/blog/2011/07/jboss-7-postgresql-9 http://blog.xebia.com/2011/07/19/developing-a-jpa-application-on-jboss-as-7/ http://community.jboss.org/wiki/DataSourceConfigurationInAS7 http://stackoverflow.com/questions/286686/how-to-create-conditions-based-on-user-role-using-jsf-myfaces/ http://www.mkyong.com/jsf2/jsf-2-datatable-example/ Reference: Full WebApplication JSF EJB JPA JAAS from our JCG partner Hebert Coelho at the uaiHebert blog....
javafx-logo

Using the JavaFX AnimationTimer

In retrospect it was probably not a good idea to give the AnimationTimer its name, because it can be used for much more than just animation: measuring the fps-rate, collision detection, calculating the steps of a simulation, the main loop of a game etc. In fact, most of the time I saw AnimationTimer in action was not related to animation at all. Nevertheless there are cases when you want to consider using an AnimationTimer for your animation. This post will explain the class and show an example where AnimationTimer is used to calculate animations.The AnimationTimer provides an extremely simple, but very useful and flexible feature. It allows to specify a method, that will be called in every frame. What this method is used for is not limited and, as already mentioned, does not have anything to do with animation. The only requirement is, that it has to return fast, because otherwise it can easily become the bottleneck of a system.To use it, a developer has to extend AnimationTimer and implement the abstract method handle(). This is the method that will be called in every frame while the AnimationTimer is active. A single parameter is passed to handle(). It contains the current time in nanoseconds, the same as what you would get when calling System.nanoTime().Why should one use the passed in value instead of calling System.nanoTime() or its little brother System.currentTimeMillis() oneself? There are several reasons, but the most important probably is, that it makes your life a lot easier while debugging. If you ever tried to debug code, that depended on these two methods, you know that you are basically screwed. But the JavaFX runtime goes into a paused state while it is waiting to execute the next step during debugging and the internal clock does not proceed during this pause. In other words no matter if you wait two seconds or two hours before you resume a halted program while debugging, the increment of the parameter will roughly be the same!AnimationTimer has two methods start() and stop() to activate and deactivate it. If you override them, it is important that you call these methods in the super class.The Animation API comes with many feature rich classes, that make defining an animation very simple. There are predefined Transition classes, it is possible to define a key-frame based animation using Timeline, and one can even write a custom Transition easily. But in which cases does it make sense to use an AnimationTimer instead? – Almost always you want to use one of the standard classes. But if you want to specify many simple animations, using an AnimationTimer can be the better choice.The feature richness of the standard animation classes comes with a price. Every single animation requires a whole bunch of variables to be tracked – variables that you often do not need for simple animations. Plus these classes are optimized for speed, not for small memory footprint. Some of the variables are stored twice, once in the format the public API requires and once in a format that helps faster calculation while playing.Below is a simple example that shows a star field. It animates thousands of rectangles flying from the center to the outer edges. Using an AnimationTimer allows to store only the values that are needed. The calculation is extremely simple compared to the calculation within a Timeline for example, because no advanced features (loops, animation rate, direction etc.) have to be considered. package fxsandbox;import java.util.Random; import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.stage.Stage;public class FXSandbox extends Application { private static final int STAR_COUNT = 20000; private final Rectangle[] nodes = new Rectangle[STAR_COUNT]; private final double[] angles = new double[STAR_COUNT]; private final long[] start = new long[STAR_COUNT]; private final Random random = new Random();@Override public void start(final Stage primaryStage) { for (int i=0; i<STAR_COUNT; i++) { nodes[i] = new Rectangle(1, 1, Color.WHITE); angles[i] = 2.0 * Math.PI * random.nextDouble(); start[i] = random.nextInt(2000000000); } final Scene scene = new Scene(new Group(nodes), 800, 600, Color.BLACK); primaryStage.setScene(scene); primaryStage.show(); new AnimationTimer() { @Override public void handle(long now) { final double width = 0.5 * primaryStage.getWidth(); final double height = 0.5 * primaryStage.getHeight(); final double radius = Math.sqrt(2) * Math.max(width, height); for (int i=0; i<STAR_COUNT; i++) { final Node node = nodes[i]; final double angle = angles[i]; final long t = (now - start[i]) % 2000000000; final double d = t * radius / 2000000000.0; node.setTranslateX(Math.cos(angle) * d + width); node.setTranslateY(Math.sin(angle) * d + height); } } }.start(); } public static void main(String[] args) { launch(args); } }Reference: Using the JavaFX AnimationTimer from our JCG partner Michael Heinrichs at the Mike’s Blog blog....
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books