Facebook Connect implementation using OAuth in java

facbook connect using appId



package com.apalya.action;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import org.codehaus.jettison.json.JSONObject;

import com.apalya.util.ApalyaProperties;
import com.visural.common.IOUtil;
import com.visural.common.StringUtil;

/**
 * 
 * @author Ravi
 * 
 */
public class Facebook extends BaseAction {

 /**
  * Register your web application here https://developers.facebook.com/apps
  * to get below credential.
  */
 private static final String api_key = 1608443106749145;
 private static final String secret = c21bf0af0d9479e8582e46ed36fe114av;
 private static final String client_id = 1608443106749145;

 /**
  * set this to your servlet URL for the authentication servlet/filter
  */
 private static final String redirect_uri = "http://your_application_url/redirect_action_to_call_method";

 /**
  * set this to the list of extended permissions you want
  */
 private static final String[] perms = new String[] { "publish_stream",
   "email" };

 public static String getLoginRedirectURL() {

  return "https://graph.facebook.com/oauth/authorize?client_id="
    + client_id + "&display=page&redirect_uri=" + redirect_uri
    + "&scope=" + StringUtil.delimitObjectsToString(",", perms);
 }

 public static String getAuthURL(String authCode) {
  return "https://graph.facebook.com/oauth/access_token?client_id="
    + client_id + "&redirect_uri=" + redirect_uri
    + "&client_secret=" + secret + "&code=" + authCode;
 }

 /**
  * Redirect url method which handle the facebook request.
  * 
  * @return success when the user successfully authenticated by facebook
  */
 public String getFbauth() {
  String code = getServletRequest().getParameter("code");
  if (StringUtil.isNotBlankStr(code)) {
   try {
    String authURL = Facebook.getAuthURL(getServletRequest()
      .getParameter("code"));
    URL url = new URL(authURL);
    String result = readURL(url);
    String accessToken = null;
    Integer expires = null;
    String[] pairs = result.split("&");
    for (String pair : pairs) {
     String[] kv = pair.split("=");
     if (kv.length != 2) {
      // log.error("Unexpected auth response");
     }
     if (kv[0].equals("access_token")) {
      accessToken = kv[1];
     }
     if (kv[0].equals("expires")) {
      expires = Integer.valueOf(kv[1]);
     }
    }
    if (accessToken != null && expires != null) {
     try {
      authFacebookLogin(accessToken, expires);
     } catch (Exception e) {
      // log.error("Auth Facebook Login failed",e);
      return "success";
     }
    } else {
     // log.error("Access token and expires not found");
    }
   } catch (IOException e) {
    // log.error("Access token and expires not found",e);
    return "success";
   }
  }
  return "success";

 }

 /**
  * After successfully login facebook return the json response object with
  * loggedin user details.
  * 
  * @param accessToken
  * @param expires
  */
 public void authFacebookLogin(String accessToken, int expires) {
  String userName = null;
  try {
   JSONObject resp = new JSONObject(
     IOUtil.urlToString(new URL(
       "https://graph.facebook.com/me?access_token="
         + accessToken)));
   // get user details and save in data base as per your requirement.
  } catch (Throwable ex) {
   // handle the exception
  } finally {
   getServletRequest().getSession().setAttribute("userName", userName);
   getServletRequest().getSession().setAttribute("fbAccessToken",accessToken);
  }
 }

 private String readURL(URL url) throws IOException {
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  InputStream is = url.openStream();
  int r;
  while ((r = is.read()) != -1) {
   baos.write(r);
  }
  return new String(baos.toByteArray());
 }

 public static String getAPIKey() {
  return api_key;
 }

 public static String getSecret() {
  return secret;
 }
}

IBATIS vs Hibernate

International Bibliography of Periodical Liter...

There are major differences between iBatis and Hibernate but both the solutions work well, given their specific domain. Personally I would suggest you should use iBATIS if:

  • You want to create your own SQL‘s and are willing to maintain them.
  • your environment is driven by relational data model.
  • you have to work existing and complex schema’s.

And simply use Hibernate if:

  • Your environment is driven by object model and wants generates SQL automatically.

To count there are few differences:

  • iBATIS is:
    • Simpler
    • Faster development time
    • Flixable
    • Much smaller in package size
  • Hibernate:
    • Generates SQL for you which means you don’t spend time on SQL
    • Provides much more advance cache
    • Highly scalable

Other difference is that iBATIS makes use of SQL which could be database dependent where as Hibernate makes use of HQL which is relatively independent of databases and it is easier to change db in Hibernate.

Hibernate maps your Java POJO objects to the Database tables where as iBatis maps the ResultSet from JDBC API to your POJO Objets.

If you are using stored procedures, well you can do it in Hibernate but it is little difficult in comparision of iBATIS. As an alternative solution iBATIS maps results sets to objects, so no need to care about table structures. This works very well for stored procedures, works very well for reporting applications, etc

Finally, Hibernate and iBATIS both are open source Object Relational Mapping(ORM) tools available in the industry. Use of each of these tools depends on the context you are using them. Hibernate and iBatis both also have good support from SPRING framework so it should not be a problem to chose one of them.

Android SDK: Unit Testing with the JUnit Testing Framework

Android Robot. Français : le logo d'android 日本...

In this tutorial, you will learn how to use Eclipse to create an Android JUnit Test Project, create automated unit tests and run them under a variety of conditions.

Before You Begin

The authors are assuming the reader has some basic knowledge of Android and have all of the tools such as Eclipse and the Android SDK installed and working. The examples given here are engineered to show how the Android JUnit framework can be used to test Android applications. Specifically, this tutorial will show you how to test aspects of an Activity and identify program errors. These errors are determined, but not addressed, as part of this tutorial.

Note: The code for the SimpleCalc application is available on Google Code as well as from the above link.

Step 1: Review the SimpleCalc Application

First, let’s take a few moments to look over the SimpleCalc application. It’s a very simple application with just one screen. The screen has two simple functions: it allows the user to input two values, adds or multiplies these values together and displays the result as shown below.

Junit Testing The SimpleCalc application

Step 2: Review the SimpleCalc Screen Layout

The SimpleCalc application has just one screen, so we have only one layout resource file called /res/layout/main.xml.

Here is a listing of the main.xml layout resource:
  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
  3.     android:orientation=”vertical” android:layout_width=”fill_parent”
  4.     android:layout_height=”fill_parent”>
  5.     <TextView android:layout_width=”fill_parent”
  6.         android:layout_height=”wrap_content” android:text=”@string/hello”
  7.         android:gravity=”center_horizontal” android:textSize=”48px”
  8.         android:padding=”12px” />
  9.     <EditText android:layout_height=”wrap_content” android:id=”@+id/value1″
  10.         android:hint=”@string/hint1″ android:inputType=”numberDecimal”
  11.         android:layout_width=”fill_parent” android:textSize=”48px”></EditText>
  12.     <EditText android:layout_height=”wrap_content” android:id=”@+id/value2″
  13.         android:hint=”@string/hint2″ android:inputType=”numberDecimal”
  14.         android:layout_width=”fill_parent” android:textSize=”48px”></EditText>
  15.     <FrameLayout android:id=”@+id/FrameLayout01″
  16.         android:layout_width=”wrap_content” android:layout_height=”wrap_content”
  17.         android:padding=”12px” android:background=”#ff0000″>
  18.         <LinearLayout android:id=”@+id/LinearLayout02″
  19.             android:layout_width=”wrap_content” android:layout_height=”wrap_content”
  20.             android:orientation=”horizontal” android:background=”#000000″
  21.             android:padding=”4px”>
  22.             <TextView android:layout_width=”wrap_content”
  23.                 android:layout_height=”wrap_content” android:text=”@string/resultLabel”
  24.                 android:textSize=”48px” android:id=”@+id/resultLabel”></TextView>
  25.             <TextView android:layout_width=”wrap_content”
  26.                 android:layout_height=”wrap_content” android:id=”@+id/result”
  27.                 android:textSize=”48px” android:textStyle=”bold”
  28.                 android:layout_marginLeft=”16px”></TextView>
  29.         </LinearLayout>
  30.     </FrameLayout>
  31.     <LinearLayout android:id=”@+id/LinearLayout03″
  32.         android:layout_height=”wrap_content” android:layout_width=”fill_parent”>
  33.         <Button android:layout_height=”wrap_content” android:id=”@+id/addValues”
  34.             android:text=”@string/add” android:textSize=”32px”
  35.             android:layout_width=”wrap_content”></Button>
  36.         <Button android:layout_height=”wrap_content” android:id=”@+id/multiplyValues”
  37.             android:text=”@string/multiply” android:textSize=”32px”
  38.             android:layout_width=”wrap_content”></Button>
  39.     </LinearLayout>
  40. </LinearLayout>

This layout is fairly straightforward. The entire content of the screen is stored within a LinearLayout, allowing the controls to display one after another vertically. Within this parent layout, we have the following controls:

  • A TextView control displaying the header “Unit Testing Sample.”
  • Two EditText controls to collect user input in the form of two numbers.
  • A FrameLayout control which contains a horizontal LinearLayout with the result label TextView and resulting sum or product TextView. The FrameLayout displays a red border around these controls, highlighting the result.
  • Finally, another horizontal LinearLayout with two child controls: a Button control for addition and a Button control for multiplication.

This layout is designed to look right in the Android Layout Designer when the Nexus One option (which has a screen size of 800×480) is chosen in both portrait and landscape modes. You’ll soon see that this is not a bullet-proof way of designing layouts. As with the code you’ll see in the next step, it isn’t designed to work perfectly.

Step 3: Review the SimpleCalc Activity

The SimpleCalc application has just one screen, so we have only one Activity as well: MainActivity.java. The MainActivity.java class controls the behavior of the one screen, whose user interface is dictated by the main.xml layout.

Here is a listing of the MainActivity.java class:

  1. package com.mamlambo.article.simplecalc;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;
  8. import android.widget.EditText;
  9. import android.widget.TextView;
  10. public class MainActivity extends Activity {
  11.    /** Called when the activity is first created. */
  12.    @Override
  13.    public void onCreate(Bundle savedInstanceState) {
  14.        final String LOG_TAG = “MainScreen”;
  15.        super.onCreate(savedInstanceState);
  16.        setContentView(R.layout.main);
  17.        final EditText value1 = (EditText) findViewById(R.id.value1);
  18.        final EditText value2 = (EditText) findViewById(R.id.value2);
  19.        final TextView result = (TextView) findViewById(R.id.result);
  20.        Button addButton = (Button) findViewById(R.id.addValues);
  21.        addButton.setOnClickListener(new OnClickListener() {
  22.            public void onClick(View v) {
  23.                try {
  24.                    int val1 = Integer.parseInt(value1.getText().toString());
  25.                    int val2 = Integer.parseInt(value2.getText().toString());
  26.                    Integer answer = val1 + val2;
  27.                    result.setText(answer.toString());
  28.                } catch (Exception e) {
  29.                    Log.e(LOG_TAG, “Failed to add numbers”, e);
  30.                }
  31.            }
  32.        });
  33.        Button multiplyButton = (Button) findViewById(R.id.multiplyValues);
  34.        multiplyButton.setOnClickListener(new OnClickListener() {
  35.            public void onClick(View v) {
  36.                try {
  37.                    int val1 = Integer.parseInt(value1.getText().toString());
  38.                    int val2 = Integer.parseInt(value2.getText().toString());
  39.                    Integer answer = val1 * val2;
  40.                    result.setText(answer.toString());
  41.                } catch (Exception e) {
  42.                    Log.e(LOG_TAG, “Failed to multiply numbers”, e);
  43.                }
  44.            }
  45.        });
  46.    }
  47. }
As you can see, the Java for this class is quite straightforward. It simply implements onClick() handlers for both the addition and multiplication Button controls.

When a Button is pressed, the Activity retrieves the values stored in the two EditText controls, calculates the result, and displays it in the TextView control called R.id.result.

Note: There are bugs in this code! These bugs have been designed specifically to illustrate unit testing.

Step 4: Creating an Android Test Project

You can add a test project to any Android project in two ways. You can add a test project while creating a new Android project with the Android Project Wizard or you can add a test project to an existing Android project. (The steps are basically the same.)

For this example, we have an existing project. To add a test project to the SimpleCalc project in Eclipse, take the following steps:

From the Project Explorer, choose the Android project you wish to add a test project to. Right-click on the project and choose Android Tools->New Test Project…

Junit Testing, Creating a Test Project

Step 5: Configuring the Android Test Project

Now you need to configure the test project settings, including the test project name, file location, Android project to test and build target (SDK version).

For this example, we can use the following settings:

  • Test project names generally end in “Test”, so let’s name this test project SimpleCalcTest
  • The project location can be wherever you normally store source files on your hard drive.
  • Choose the Android project to test: SimpleCalc
  • The appropriate build target will be selected automatically once you select the project to test. In this case, since the Android project is built for Android 2.1 + Google APIs (API Level 7), it makes sense to use the same build target for the test project.
  • It makes sense to name the test project accordingly: SimpleCalcTest, with the appropriate package name suffix simplecalc.test.
Configuring the project test

Hit Finish.

Step 6: Review the SimpleCalcTest Project

The SimpleCalcTest project is an Android project. You will notice that it has all the normal things you’d expect of an Android project, including a Manifest file and resources.

Junit Testing SimpleCalcTest Project Files

Step 7: Determine Unit Tests for the SimpleCalc Application

Now that you have a test project configured for the SimpleCalc application, it makes sense to determine some reasonable unit tests for the application.

Many software methodologies these days work compatibly with unit testing. Unit tests can greatly increase the stability and quality of your application and reduce testing costs. Unit tests come in many forms.

Unit tests can:

  • Improve testing coverage
  • Test application assumptions
  • Validate application functionality

Unit tests can be used to test core functionality, such as whether or not the SimpleCalc math is being performed correctly. They can also be used to verify if the user interface is displaying correctly. Now let’s look at some specific test cases.

Step 8: Create Your First Test Case

To create your first test case, right-click on the simplecalc.test package and choose New->JUnit Test Case.

Configuring test case settings.

Step 9: Configure Your First Test Case

Now you need to configure the test case settings.

For this example, we can use the following settings:

  • Both JUnit 3 and 4 are supported. We’ll use the default JUnit 3 here.
  • The source folder should be the location of the SimpleCalcTest project files.
  • The package should be the package name of the SimpleCalcTest project.
  • In this case, we will name the test case MathValidation.
  • For the SuperClass, choose “android.test.ActivityInstrumentationTestCase2.” This is the test case you use for testing activities.
  • Check the boxes to add method stubs for setUp() and constructor.
junit Testing, Configuring test case settings.

Hit Finish. (You can safely ignore the warning saying, “Superclass does not exist.”)

Step 10: Review the MathValidation Test Case

The MathValidation.java test case source file is then created.

The lifecycle of a test case is basically this: construction, setUp(), tests run, tearDown(), and destruction. The setUp() method is used to do any general initialization used by all of specific tests. Each test to be run in the test case is implemented as its own method, where the method name begins with “test”. The tearDown() method is then used to uninitialize any resources acquired by the setUp() method.

  1. package com.mamlambo.article.simplecalc.test;
  2. import android.test.ActivityInstrumentationTestCase2;
  3. public class MathValidation extends
  4.        ActivityInstrumentationTestCase2<MainActivity> {
  5.    public MathValidation(String name) {
  6.        super(name);
  7.    }
  8.    protected void setUp() throws Exception {
  9.        super.setUp();
  10.    }
  11. }

Now it’s time to implement the MathValidation Test Case

Step 11: Modify the MathValidation Class Constructor

First, modify the MathValidation class constructor. This constructor ties configures the internals of the Android test superclass we’re using.

  1. public MathValidation() {
  2.        super(“com.mamlambo.article.simplecalc”, MainActivity.class);
  3. }

Step 12: Implement the MathValidation setUp() method

Now you need to gather the data required for validating the SimpleCalc math calculations. Begin by implementing the setUp() method. You can retrieve the Activity being tested using the getActivity() method as follows:

  1. MainActivity mainActivity = getActivity();

Next, you need to retrieve an instance of the TextView control called R.id.result. This is the control that will hold the resulting sum or product from the math calculations used by the application.

The full updated code listing (MathValidation.java) with these modifications is shown below:

  1. package com.mamlambo.article.simplecalc.test;
  2. import android.test.ActivityInstrumentationTestCase2;
  3. import android.widget.TextView;
  4. import com.mamlambo.article.simplecalc.MainActivity;
  5. import com.mamlambo.article.simplecalc.R;
  6. public class MathValidation extends ActivityInstrumentationTestCase2<MainActivity> {
  7.    private TextView result;
  8.    public MathValidation() {
  9.        super (“com.mamlambo.article.simplecalc”, MainActivity.class);
  10.    }
  11.    @Override
  12.    protected void setUp() throws Exception {
  13.        super.setUp();
  14.        MainActivity mainActivity = getActivity();
  15.        result = (TextView) mainActivity.findViewById(R.id.result);
  16.    }
  17. }

Step 13: Consider Tests for the SimpleCalc Application

Now that everything is set up, what tests do you want to perform? Let’s begin by checking the math used by the SimpleCalc application. Specifically, let’s check that the numbers are retrieved correctly, as well as added and multiplied correctly. Did we set the right types for our number values? Are we retrieving and performing mathematical calculations using the correct types?

To answer these questions, we must add some testing code to the MathValidation class. Each specific test will have it’s own method beginning with “test” – the “test” method name prefix is case sensitive! This naming scheme is how JUnit determines what methods to run.

Step 14: Implement a Method to Test SimpleCalc’s Addition

Let’s begin by testing the addition calculation of SimpleCalc. To do this, add a method called testAddValues() to the MathValidation class.

This test will enter two numbers (24 and 74) into the screen and press Enter, which acts as a click on the first Button control which is in focus. Then it will retrieve the sum displayed by the application in the result TextView control and test to see if the result is the expected one (98).

To supply the EditText controls with two numbers to sum, use the sendKeys() method. This method mimics how keys are sent to Android applications. If you use the setText() method of the EditText control to set the text in each control, then you are bypassing the validation of the numeric entry that user’s would encounter. This method of providing key strokes assumes that the focus starts on the first control and that using the Enter key goes to the next one (you’ll see that the enter key is sent at the end of each number). If neither of those assumptions is true, the test will also fail. This is not a bad thing, but it might be failing for the wrong reasons (e.g. focus or layout issues, rather than math issues).

Finally, you use the assertTrue() method to compare the actual result displayed on the screen to the expected result. ). We compare against a string, since the result is displayed as a string. This way, we can also make sure we don’t duplicate any math or type errors in the application logic within the test framework.
Here is the full listing of the testAddValues() method:

  1. private static final String NUMBER_24 = “2 4 ENTER “;
  2. private static final String NUMBER_74 = “7 4 ENTER “;
  3. private static final String ADD_RESULT = “98”;
  4. public void testAddValues() {
  5.    sendKeys(NUMBER_24);
  6.    // now on value2 entry
  7.    sendKeys(NUMBER_74);
  8.    // now on Add button
  9.    sendKeys(“ENTER”);
  10.    // get result
  11.    String mathResult = result.getText().toString();
  12.    assertTrue(“Add result should be 98”, mathResult.equals(ADD_RESULT));
  13. }

Congratulations! You’ve created your first test!

Step 15: Enhancing the Tests for Addition

Now let’s add a few more tests to make sure all different types of numbers can be added, resulting in the display of the proper sum.

Because the activity is launched for each test, you do not need to clear the values or anything like that between tests. You also do not need to change the focus within the form, since it begins at value1. Therefore, you can simplify tests by concatenating key presses together in a single sendKeys() method call, like such:

  1. sendKeys(NUMBER_24 + NUMBER_74 + “ENTER”);

For example, here is the code for the testAddDecimalValues() method, which tests the addition of a decimal value 5.5 with the number 74, which should result in 79.5:

  1. public void testAddDecimalValues() {
  2.        sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + “ENTER”);
  3.        String mathResult = result.getText().toString();
  4.        assertTrue(“Add result should be ” + ADD_DECIMAL_RESULT + ” but was “
  5.                + mathResult, mathResult.equals(ADD_DECIMAL_RESULT));
  6.  }

Similarly, you can perform a test of adding a negative number -22 to the number 74, which should result in a sum of 52. This test is implemented in the testSubtractValues() method, as follows:

  1. public void testAddDecimalValues() {
  2.        sendKeys(NUMBER_5_DOT_5 + NUMBER_74 + “ENTER”);
  3.        String mathResult = result.getText().toString();
  4.        assertTrue(“Add result should be ” + ADD_DECIMAL_RESULT + ” but was “
  5.                + mathResult, mathResult.equals(ADD_DECIMAL_RESULT));
  6.    }

Step 16: Implement a Method to Test SimpleCalc’s Multiplication

It should be quite straightforward to implement a similar test for SimpleCalc’s multiplication called testMuliplyValues().

The only tricky part is that the Multiply Button control is not in focus when we’re done entering the numbers (instead, the Add Button is).
You might think to just call the requestFocus() method on the multiply button. Unfortunately, this won’t work because requestFocus() has to be run on the UI thread in Android. Running methods on the UI Thread can be done as part of a test case, but it’s done asynchronously so you can’t guarantee when it will be complete.

Instead, we’ll again use the sendKeys() method. Since we defined the Multiply Button to always display to the right of the Add Button, we can just send the “DPAD_RIGHT” key followed by “ENTER” to click the Multiply Button.

  1. public void testMultiplyValues() {
  2.    sendKeys(NUMBER_24+NUMBER_74+ ” DPAD_RIGHT ENTER”);
  3.    String mathResult = result.getText().toString();
  4.    assertTrue(“Multiply result should be ” + MULTIPLY_RESULT + ” but was “
  5.            + mathResult, mathResult.equals(MULTIPLY_RESULT));
  6. }

As an exercise, you might try adding more multiplication tests with various sizes of numbers. Try to engineer a test that might fail with the existing code. Can you guess if each test will be successful or not? (Hint: Look at the type of the variable that the string is being converted to.)

Step 17: Running Unit Tests with the Android Emulator or Device

Unit test frameworks such as the one you’re building are Android applications like any other. They must be installed on the emulator or device you wish to test, along with the application to be tested (in this case, SimpleCalc).

To run the unit tests you have created so far from Eclipse, choose the Debug drop down, then Debug As, then Android JUnit Test. Make sure the file you just created is the active file (shown in the window) as that is the test case that will be launched.

junit testing, Debugging JUnit Test

Step 18: Examining the Test Results

The tests may take some time to complete, especially if the emulator was not already running. When the tests have completed, you should see results similar to those shown here:

Junit Testing Examining the Test Results

You’ll notice that all four of the tests you’ve just created run. Two of them are successful, while two of them have failed. Do you know why they’ve failed? (Fixing these calculation bugs is left as a learning exercise for the reader.)

Besides successful tests and failed tests, errors are also shown. A failure is when a tested for assertion fails. An error, on the other hand, is a thrown exception. Errors can either be untested for edge cases or simply mistakes in the testing code. If you have errors, check your testing code carefully to make sure it is working correctly.

Step 19: Create a Test Case for Screen Display Testing

Unit tests need not be limited to validating core functionality such as the addition and multiplication of values. Tests can also validate whether or not a screen layout is displayed properly.

For example, you might want to validate that all of the layout controls display properly on all target screens. The SimpleCalc’s screen was designed in the layout designer in Eclipse for an 800×480 screen in either landscape or portrait mode, but will it work on other screen sizes and devices? Were we then too specific in our design? Automated testing can tell us the answer to this question very quickly.

To create another test case, right-click on the SimpleCalc.Test package and choose New->JUnit Test Case. Call this new test LayoutTests. Configure this test case much as you did the MathValidation class in Step 8.

Junit testing, Create a Test Case for Screen Display Testing.

Hit Finish.

Step 20: Review and Update the LayoutTests Test Case

The LayoutTests.java test case source file is then created. Modify the class to look like the code listing below, modifying the constructor, retrieving the Button controls and the layout as a whole:

  1. package com.mamlambo.article.simplecalc.test;
  2. import android.test.ActivityInstrumentationTestCase2;
  3. import android.view.View;
  4. import android.widget.Button;
  5. import com.mamlambo.article.simplecalc.MainActivity;
  6. import com.mamlambo.article.simplecalc.R;
  7. public class LayoutTests extends ActivityInstrumentationTestCase2<MainActivity> {
  8.    private Button addValues;
  9.    private Button multiplyValues;
  10.    private View mainLayout;
  11.    public LayoutTests() {
  12.        super(“com.mamlambo.article.simplecalc”, MainActivity.class);
  13.    }
  14.    protected void setUp() throws Exception {
  15.        super.setUp();
  16.        MainActivity mainActivity = getActivity();
  17.        addValues = (Button) mainActivity.findViewById(R.id.addValues);
  18.        multiplyValues = (Button) mainActivity
  19.                .findViewById(R.id.multiplyValues);
  20.        mainLayout = (View) mainActivity.findViewById(R.id.mainLayout);
  21.    }
  22. }
Now let’s implement some specific tests for LayoutTests.

Step 20: Consider Layout Tests for the SimpleCalc Application
Now that everything is set up, what tests do you want to perform? One common bug in application design is for controls not to display properly in all screen sizes and orientations. Therefore, it makes sense to try to build a test case to verify the location of certain controls. You can then add other checks to make sure other View controls display and behave appropriately.

Step 21: Implement a Method to Test Button Display

Let’s begin by testing that the Add Button control of the SimpleCalc screen is visible. To do this, add a method called testAddButtonOnScreen() to the LayoutTests class.

This test checks to see if the Add Button control is displayed within the visible rectangle representing the overall screen size.

To implement the testAddButtonOnScreen() method, you must first determine the screen size. There are a number of ways to do this. One simple way is to retrieve the View that represents the entire screen layout and use the getWidth() and getHeight() methods. Doing this also takes in to account any screen real estate being used by other items, such as the title bar or information bar that are often at the top of an Android screen.

Determining whether or not the Add Button control is drawn within those bounds is as simple as comparing the layout bounds to the bounds of the drawing rectangle for the Add Button control.

Here is the full listing of the testAddButtonOnScreen() method:

  1. public void testAddButtonOnScreen() {
  2.    int fullWidth = mainLayout.getWidth();
  3.    int fullHeight = mainLayout.getHeight();
  4.    int[] mainLayoutLocation = new int[2];
  5.    mainLayout.getLocationOnScreen(mainLayoutLocation);
  6.    int[] viewLocation = new int[2];
  7.    addValues.getLocationOnScreen(viewLocation);
  8.    Rect outRect = new Rect();
  9.    addValues.getDrawingRect(outRect);
  10.    assertTrue(“Add button off the right of the screen”, fullWidth
  11.            + mainLayoutLocation[0] > outRect.width() + viewLocation[0]);
  12.    assertTrue(“Add button off the bottom of the screen”, fullHeight
  13.            + mainLayoutLocation[1] > outRect.height() + viewLocation[1]);
  14. }

At this point, you can see how you could also test the display of the Multiply Button, or the Result text, or any other control on the SimpleCalc screen.

Step 22: Running the LayoutTests Test Case

In order for layout testing to provide useful results, we can’t just run the test once. Instead, the tests must be run on multiple emulator configurations and screen orientations. This is different from the logic tests of above where a messy layout or a layout that doesn’t match the design pattern doesn’t necessarily impede functionality.

For example, if you create emulator configurations (using AVDs) for the following configurations, the LayoutTests test case will yield the following results:

  1. 480×800, portrait mode (will pass)
  2. 800×480, landscape mode (will fail)
  3. 320×480, portrait mode (will fail)
  4. 480×320, landscape (will fail)
  5. 480×854, portrait mode (will pass)
  6. 854×480, landscape mode (will fail)

 Can you figure out why it fails in all landscape modes, but draws fine in the creator for the landscape mode (#2 above)?

Can you figure out why it fails in all landscape modes, but draws fine in the creator for the landscape mode (#2 above)?

Hint: What’s shown on the screen when the application actually runs (see the figure below)?

JUnit Testing Sample

Step 23: Where to Go From Here

Now that you have some tests in place—some of which pass and some of which fail—you can imagine how unit testing can improve the quality of your application.

The more thorough you are with your unit testing coverage, the better. You’ve seen how unit testing can uncover bugs in code and layout designs. The next step would be to identify the failure points and fix those bugs. Once you’ve fixed the bugs, you should re-run the unit tests to ensure that they pass in all test cases.

Conclusion

In this tutorial, you learned how to create unit tests using the Android JUnit framework for your Android projects. You also learned how to create different kinds of unit tests to test a variety of application features, including underlying program functions as well as display characteristics.

Calling Stored Procedures from ASP.NET and VB.NET

The Microsoft Visual Studio .NET logo.

Let us see how can we create and call Stored procedures, in a .NET Environment, i.e Visual Studio.We use .NET 2.0 and Visual Studio 2005 for all the examples.fs

Writing stored procedures has never been easy as Microsoft has almost integrated SQL Server with Visual Studio 2005. In the past most of the developers has wondered can’t we have a good editor for creating stored procedures. One of the main advantage of creating procedures in Visual Studio is it creates the basic stub for you and further more, it has inbuilt syntax checking which makes the job easier for us.

In order to create a stored procedure from Visual Studio, first you need to create a data connection from the Server Explorer and follow the below steps.

Step 1: Open Visual Studio 2005.

Step 2: Create a VB.NET / C# Windows / Web Application  Project.

Step 3: Open the Server Explorer by Selecting View -> Server Explorer.

stored_procedures_VB.NET

Step 4: Create a Data Connection to your server you can do this by Right Clicking on the Data Connection Tree and Selecting “Add New Connection”.

Step 5: It will Prompt for the Provider Type you can select .NET SQL Server Provider as it gives more performance.

Step 6: After giving all the credentials once the connection is active expand the database that you are having.

Step 7: Expand the Stored Procedure Tree.

Step 8: To Create a New Procedure Right Click and Select “Add New Procedure”.

Step 9: The IDE will give you a Stub where you can replace the Name of the Procedure and Arguments.

Those who are familiar with Visual Studio IDE would love to create procedures here rather then doing it in Query Analyzer or in SQL Enterprise Manager, though it doesn’t provide any fancy auto complete drop downs its still the best I believe to create stored procedures.

TIP: The Maximum number of parameters in a stored procedure is 2100.

Calling Stored Procedure

Hope everyone have used SQLCommand / OLEDB Command objects in .NET. Here we can call stored procedures in two different forms, one without using parameter objects which is not recommended for conventional development environments, the other one is the familiar model of using Parameters.

In the first method you can call the procedure using Exec command followed by the procedure name and the list of parameters, which doesn’t need any parameters.

Example:

Dim SQLCon As New SqlClient.SqlConnection
SQLCon.ConnectionString = “Data Source=Server;User ID=User;Password=Password;”
SQLCon.Open()

Calling Stored Procedures with Exec command

SQLCmd.CommandText = “Exec SelectRecords ‘Test’, ‘Test’, ‘Test'”
SQLCmd.Connection = SQLCon ‘Active Connection

The second most conventional method of calling stored procedures is to use the parameter objects and get the return values using them. In this method we need to set the “SQLCommandType” to “StoredProcedure” remember you need to set this explicitly as the the default type for SQLCommand is SQLQuery”.

Here is an example to call a simple stored procedure.

Example – I (A Stored Procedure Returns Single Value)

In order to get XML Results from the Stored Procedure you need to first ensure that your stored procedure is returning a valid XML. This can be achieved using FOR XML [AUTO | RAW | EXPLICIT] clause in the select statements. You can format XML using EXPLICIT Keyword, you need to alter your Query accordingly

‘Set up Connection object and Connection String for a SQL Client
Dim SQLCon As New SqlClient.SqlConnection
SQLCon.ConnectionString = “Data Source=Server;User ID=User;Password=Password;”
SQLCon.Open()SQLCmd.CommandText = “SelectRecords” ‘ Stored Procedure to Call
SQLCmd.CommandType = CommandType.StoredProcedure ‘Setup Command Type
SQLCmd.Connection = SQLCon ‘Active Connection

The procedure can be called by adding Parameters in at least two different methods, the simplest way to add parameters and respective values is using

SQLCmd.Parameters.AddWithValue(“S_Mobile”, “Test”)
SQLCmd.Parameters.AddWithValue(“S_Mesg”, “Test”)
SQLCmd.Parameters.AddWithValue(“LastMsgID”, “”)

In this above method, you doesn’t necessarily know the actually data type that you had in your procedure and all parameters are validated according to the type declared in your procedure but only thing is all the validations will occur in SQL and not in your client code.

We still need to declare the last parameter as Output and we need to do that explicitly as the default type is Input. So here we are going to declare the last parameter as Output by

SQLCmd.Parameters(“LastMsgID”).Direction = ParameterDirection.Outputfs

If you want to declare parameters properly then you need to use the below method to add all the parameters with its data type, direction. Also if you are using stored procedures to update all the rows in a dataset then you need to declare parameters in the below fashion and give SouceColumn value as the Column name in the DataTable.

SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“S_Mobile”, SqlDbType.VarChar, 10, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “91000000000”))SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“S_Mesg”, SqlDbType.VarChar, 160, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “Calling Stored Procedures from VB.NET”))

SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“LastMsgID”, SqlDbType.BigInt, 5, ParameterDirection.Output, False, 5, 0, “”, DataRowVersion.Current, 0))

‘ The Above Procedure has two input parameters and one output parameter you can notice the same in the “Parameter Direction”
SQLCmd.ExecuteNonQuery() ‘We are executing the procedure here by calling Execute Non Query.

MsgBox(SQLCmd.Parameters(“LastMsgID”).Value) ‘You can have the returned value from the stored procedure from this statement. Its all similar to ASP / VB as the only difference is the program structure.

Example – II (Stored Procedure to get Table Result Set)

In order to get the result sets from the stored procedure, the best way is to use a DataReader to get the results. In this example we are getting the results from the Stored Procedure and filling the same in a DataTable.

Here we need to additionally declare a SQLDataReader and DataTable

Dim SQLDBDataReader As SqlClient.SqlDataReader
Dim SQLDataTable As New DataTableSQLCmd.CommandText = “GetAuthors”
SQLCmd.CommandType = CommandType.StoredProcedure
SQLCmd.Connection = SQLCon
SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“AuthorName”, SqlDbType.VarChar, 100, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “Y%”)) SQLDBDataReader = SQLCmd.ExecuteReader() SQLDataTable.Columns.Add(“AuthorName”, GetType(Int32), “”) SQLDataTable.Columns.Add(“AuthorLocation”, GetType(String), “”)

Dim FieldValues(1) As Object ‘A Temporary Variable to retrieve all columns in a row and fill them in Object array

While (SQLDBDataReader.Read)
SQLDBDataReader.GetValues(FieldValues)
SQLDataTable.Rows.Add(FieldValues)

End While

Example – III (Calling Simple Stored Procedure to get XML Result Set)

In order to get XML Results from the Stored Procedure you need to first ensure that your stored procedure is returning a valid XML. This can be achieved using FOR XML [AUTO | RAW | EXPLICIT] clause in the select statements. You can format XML using EXPLICIT Keyword, you need to alter your Query accordingly.

CREATE PROCEDURE GetRecordsXML (@AuthorName varchar(100))
ASSelect Author_ID, Author_Name, Author_Location Where Author_Name LIKE  @AuthorName from Authors FOR XML AUTO

RETURN

When you use the above procedure you can get XML Results with TableName as Element and Fields as Attributes

Dim SQLXMLReader As Xml.XmlReader

SQLCmd.CommandText = “GetAuthorsXML”
SQLCmd.CommandType = CommandType.StoredProcedure
SQLCmd.Connection = SQLCon
SQLCmd.Parameters.Add(New SqlClient.SqlParameter(“AuthorName”, SqlDbType.VarChar, 100, ParameterDirection.Input, False, 30, 0, “”, DataRowVersion.Current, “Y%”))
SQLDBDataReader = SQLCmd.ExecuteReader()

SQLXMLReader = SQLCmd.ExecuteXmlReader()
While (SQLXMLReader.Read)
MsgBox(SQLXMLReader.ReadOuterXml)
End While

You can further process this XML or write XSL to display results in a formatted manner. But in order to get formatted XML Results, we need to use EXPLICIT case which we can see in our next article on SQL Queries & XML.

Spring Framework Architecture

Separation of concerns

Spring could potentially be a one-stop shop for all your enterprise applications, however, Spring is modular, allowing you to pick and choose which modules are applicable to you, without having to bring in the rest. Following section gives detail about all the modules available in Spring Framework.

The Spring Framework provides about 20 modules which can be used based on an application requirement.

Spring Framework Architecture

Core Container:

The Core Container consists of the Core, Beans, Context, and Expression Language modules whose detail is as follows:

  • The Core module provides the fundamental parts of the framework, including the IoC and Dependency Injection features.
  • The Bean module provides BeanFactory which is a sophisticated implementation of the factory pattern.
  • The Context module builds on the solid base provided by the Core and Beans modules and it is a medium to access any objects defined and configured. The ApplicationContext interface is the focal point of the Context module.
  • The Expression Language module provides a powerful expression language for querying and manipulating an object graph at runtime.

Data Access/Integration:

The Data Access/Integration layer consists of the JDBC, ORM, OXM, JMS and Transaction modules whose detail is as follows:

  • The JDBC module provides a JDBC-abstraction layer that removes the need to do tedious JDBC related coding.
  • The ORM module provides integration layers for popular object-relational mapping APIs, including JPA, JDO, Hibernate, and iBatis.
  • The OXM module provides an abstraction layer that supports Object/XML mapping implementations for JAXB, Castor, XMLBeans, JiBX and XStream.
  • The Java Messaging Service JMS module contains features for producing and consuming messages.
  • The Transaction module supports programmatic and declarative transaction management for classes that implement special interfaces and for all your POJOs.

Web:

The Web layer consists of the Web, Web-Servlet, Web-Struts, and Web-Portlet modules whose detail is as follows:

  • The Web module provides basic web-oriented integration features such as multipart file-upload functionality and the initialization of the IoC container using servlet listeners and a web-oriented application context.
  • The Web-Servlet module contains Spring’s model-view-controller (MVC) implementation for web applications.
  • The Web-Struts module contains the support classes for integrating a classic Struts web tier within a Spring application.
  • The Web-Portlet module provides the MVC implementation to be used in a portlet environment and mirrors the functionality of Web-Servlet module.

Miscellaneous:

There are few other important modules like AOP, Aspects, Instrumentation, Web and Test modules whose detail is as follows:

  • The AOP module provides aspect-oriented programming implementation allowing you to define method-interceptors and pointcuts to cleanly decouple code that implements functionality that should be separated.
  • The Aspects module provides integration with AspectJ which is again a powerful and mature aspect oriented programming (AOP) framework.
  • The Instrumentation module provides class instrumentation support and class loader implementations to be used in certain application servers.
  • The Test module supports the testing of Spring components with JUnit or TestNG frameworks

What Is JAX-RPC?

JAX-RPC stands for Java API for XML-based RPC. It’s an API for building Web services and clients that used remote procedure calls (RPC) and XML. Often used in a distributed client/server model, an RPC mechanism enables clients to execute procedures on other systems.

In JAX-RPC, a remote procedure call is represented by an XML-based protocol such as SOAP. The SOAP specification defines envelope structure, encoding rules, and a convention for representing remote procedure calls and responses. These calls and responses are transmitted as SOAP messages over HTTP. In this release, JAX-RPC relies on SOAP 1.1 and HTTP 1.1.

Although JAX-RPC relies on complex protocols, the API hides this complexity from the application developer. On the server side, the developer specifies the remote procedures by defining methods in an interface written in the Java programming language. The developer also codes one or more classes that implement those methods. Client programs are also easy to code. A client creates a proxy, a local object representing the service, and then simply invokes methods on the proxy.

With JAX-RPC, clients and Web services have a big advantage–the platform independence of the Java programming language. In addition, JAX-RPC is not restrictive: a JAX-RPC client can access a Web service that is not running on the Java platform and vice versa. This flexibility is possible because JAX-RPC uses technologies defined by the World Wide Web Consortium (W3C): HTTP, SOAP, and the Web Service Description Language (WSDL). WSDL specifies an XML format for describing a service as a set of endpoints operating on messages.

A Simple Example: HelloWorld

This example shows you how to use JAX-RPC to create a Web service named HelloWorld. A remote client of the HelloWorld service can invoke the sayHello method, which accepts a string parameter and then returns a string.

HelloWorld at Runtime

Figure 9-1 shows a simplified view of the HelloWorld service after it’s been deployed. Here’s a more detailed description of what happens at runtime:

  1. To call a remote procedure, the HelloClient program invokes a method on a stub, a local object that represents the remote service.
  2. The stub invokes routines in the JAX-RPC runtime system.
  3. The runtime system converts the remote method call into a SOAP message and then transmits the message as an HTTP request.
  4. When the server receives the HTTP request, the JAX-RPC runtime system extracts the SOAP message from the request and translates it into a method call.
  5. The JAX-RPC runtime system invokes the method on the tie object.
  6. The tie object invokes the method on the implementation of the HelloWorld service.
  7. The runtime system on the server converts the method’s response into a SOAP message and then transmits the message back to the client as an HTTP response.
  8. On the client, the JAX-RPC runtime system extracts the SOAP message from the HTTP response and then translates it into a method response for the HelloClient program.

Figure 9-1 The HelloWorld Example at Runtime

The application developer only provides the top layers in the stacks depicted by Figure 9-1. Table 9-1 shows where the layers originate.

Table 9-1 Who (or What) Provides the Layers 
Layer
Source
HelloClient Program
HelloWorld Service (definition interface and implementation class)
Provided by the application developer
Stubs Generated by the wscompile tool, which is run by the application developer
Ties Generated by the wsdeploy tool, which is run by the application developer
JAX-RPC Runtime
System
Included with the Java WSDP

HelloWorld Files

To create a service with JAX-RPC, an application developer needs to provide a few files. For the HelloWorld example, these files are in the <JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hello directory:

  • HelloIF.java – the service definition interface
  • HelloImpl.java – the service definition implementation class, it implements the HelloIF interface
  • HelloClient.java – the remote client that contacts the service and then invokes the sayHello method
  • config.xml – a configuration file read by the wscompile tool
  • jaxrpc-ri.xml – a configuration file read by the wsdeploy tool
  • web.xml – a deployment descriptor for the Web component (a servlet) that dispatches to the service

Setting Up

If you haven’t already done so, follow these instructions in the chapter Getting Started With Tomcat:

Building and Deploying the Service

The basic steps for developing a JAX-RPC Web service are as follows.

  1. Code the service definition interface and implementation class.
  2. Compile the service definition code of step 1.
  3. Package the code in a WAR file.
  4. Generate the ties and the WSDL file.
  5. Deploy the service.

The sections that follow describe each of these steps in more detail.

Coding the Service Definition Interface and Implementation Class

A service definition interface declares the methods that a remote client may invoke on the service. The interface must conform to a few rules:

  • It extends the java.rmi.Remote interface.
  • It must not have constant declarations, such as public final static.
  • The methods must throw the java.rmi.RemoteException or one of its subclasses. (The methods may also throw service-specific exceptions.)
  • Method parameters and return types must be supported JAX-RPC types. See the section Types Supported By JAX-RPC.

In this example, the service definition interface is HelloIF.java:

package hello;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface HelloIF extends Remote {
    public String sayHello(String s) throws RemoteException;
}

In addition to the interface, you’ll need to code the class that implements the interface. In this example, the implementation class is called HelloImpl:

package hello;

public class HelloImpl implements HelloIF {

    public String message ="Hello";

    public String sayHello(String s) {
        return message + s;
    }
}

Compiling the Service Definition Code

To compile HelloIF.java and HelloImpl.java, go to the <JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hello directory and type the following:

ant compile-server

This command places the resulting class files in the build/shared subdirectory.

Packaging the WAR File

To create the WAR file that contains the service code, type these commands:

ant setup-web-inf
ant package

The setup-web-inf target copies the class and XML files to the build/WEB-INF subdirectory. The package target runs the jar command and bundles the files into a WAR file named dist/hello-portable.war. This WAR file is not ready for deployment because it does not contain the tie classes. You’ll learn how to create a deployable WAR file in the next section. The hello-portable.war contains the following files:

WEB-INF/classes/hello/HelloIF.class
WEB-INF/classes/hello/HelloImpl.class
WEB-INF/jaxrpc-ri.xml
WEB-INF/web.xml

The class files were created by the compile-server target shown in the previous section. The web.xml file is the deployment descriptor for the Web application that implements the service. Unlike the web.xml file, the jaxrpc-ri.xml file is not part of the specifications and is implementation-specific. The jaxrpc-ri.xml file for this example follows:


<webServices
    xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/dd"
    version="1.0"
    targetNamespaceBase="http://com.test/wsdl"
    typeNamespaceBase="http://com.test/types"
    urlPatternBase="/ws">

Several of the webServices attributes, such as targetNamespaceBase, are used in the WSDL file, which you’ll create in the next section. (WSDL files can be complex and are not discussed in this tutorial. See Further Information.) Note that the urlPattern value (/hello) is part of the service’s URL, which is described in the section Verifying the Deployment).

For more information about the syntax of the jaxrpc-ri.xml file, see the XML Schema file: <JWSDP_HOME>/docs/tutorial/examples/jaxrpc/common/jax-rpc-ri-dd.xsd.

Generating the Ties and the WSDL File

To generate the ties and the WSDL file, type the following:

ant process-war

This command runs the wsdeploy tool as follows:

wsdeploy -tmpdir build/wsdeploy-generated 
-o dist/hello-deployable.war dist/hello-portable.war

This command runs the wsdeploy tool, which performs these tasks:

  • Reads the dist/hello-portable.war file as input
  • Gets information from the jaxrpc-ri.xml file that’s inside the hello-portable.war file
  • Generates the tie classes for the service
  • Generates a WSDL file named MyHello.wsdl
  • Packages the tie classes, the Hello.wsdl file, and the contents of hello-portable.war file into a deployable WAR file named dist/hello-jaxrpc.war

The –tmpdir option specifies the directory where wsdeploy stores the files that it generates, including the WSDL file, tie classes, and intermediate source code files. If you specify the –keep option, these files are not deleted.

There are several ways to access the WSDL file generated by wsdeploy:

  • Run wsdeploy with the –keep option and locate the WSDL file in the directory specified by the –tmpdir option.
  • Unpack (jar -x) the WAR file output by wsdeploy and locate the WSDL file in the WEB-INF directory.
  • Deploy and verify the service as described in the following sections. A link to the WSDL file is on the HTML page of the URL shown in Verifying the Deployment.

Note that the wsdeploy tool does not deploy the service; instead, it creates a WAR file that is ready for deployment. In the next section, you will deploy the service in the hello-jaxrpc.war file that was created by wsdeploy.

Deploying the Service

To deploy the service, type the following:

ant deploy 

For subsequent deployments , run ant redeploy as described in the section Iterative Development.

Verifying the Deployment

To verify that the service has been successfully deployed, open a browser window and specify the service endpoint’s URL:

http://localhost:8080/hello-jaxrpc/hello

The browser should display a page titled Web Services, which lists the port name MyHello with a status of ACTIVE. This page also has a URL to the service’s WSDL file.

The hello-jaxrpc portion of the URL is the context path of the servlet that implements the HelloWorld service. This portion corresponds to the prefix of the hello-jaxrpc.war file. The /hello string of the URL matches the value of the urlPattern attribute of the jaxrpc-ri.xml file. Note that the forward slash in the /hello value of urlPattern is required. For a full listing of the jaxrpc-ri.xml file, see Packaging the WAR File.

Undeploying the Service

At this point in the tutorial, do not undeploy the service. When you are finished with this example, you can undeploy the service by typing this command:

ant undeploy

Building and Running the Client

To develop a JAX-RPC client, you follow these steps:

  1. Generate the stubs.
  2. Code the client.
  3. Compile the client code.
  4. Package the client classes into a JAR file.
  5. Run the client.

The following sections describe each of these steps.

Generating the Stubs

Before generating the stubs, be sure to install the Hello.wsdl file according to the instructions in Deploying the Service. To create the stubs, go to the <JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hello directory and type the following:

ant generate-stubs

This command runs the wscompile tool as follows:

wscompile -gen:client -d build/client 
-classpath build/shared config.xml

The -gen:client option instructs wscompile to generate client-side classes such as stubs. The -d option specifies the destination directory of the generated files.

The wscompile tool generates files based on the information it reads from the Hello.wsdl and config.xml files. The Hello.wsdl file was intalled on Tomcat when the service was deployed. The location of Hello.wsdl is specified by the <wsdl> element of the config.xml file, which follows:


xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">

The tasks performed by the wscompile tool depend on the contents of the config.xml file. For more information about the syntax of the config.xml file, see the XML Schema file: <JWSDP_HOME>/docs/tutorial/examples/jaxrpc/common/jax-rpc-ri-config.xsd.

Coding the Client

HelloClient is a stand-alone program that calls the sayHello method of the HelloWorld service. It makes this call through a stub, a local object which acts as a proxy for the remote service. Because the stubs is created before runtime (by wscompile), it is usually called a static stub.

To create the stub, HelloClient invokes a private method named createProxy. Note that the code in this method is implementation-specific and might not be portable because it relies on the MyHello_Impl object. (The MyHello_Impl class was generated by wscompile in the preceding section.) After it creates the stub, the client program casts the stub to the type HelloIF, the service definition interface.

The source code for HelloClient follows:

package hello;

import javax.xml.rpc.Stub;

public class HelloClient {
    public static void main(String[] args) {
        try {
            Stub stub = createProxy(); HelloIF hello = (HelloIF)stub; System.out.println(hello.sayHello("Duke!"));         } catch (Exception ex) {
            ex.printStackTrace();
        }
    }    

    private static Stub createProxy() {
        // Note: MyHello_Impl is implementation-specific.
        return (Stub)(new MyHello_Impl().getHelloIFPort());
    }
}

Compiling the Client Code

Because the client code refers to the stub classes, be sure to follow the instructions in Generating the Stubs before compiling the client. To compile the client, go to the <JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hello directory and type the following:

ant compile-client 

Packaging the Client

To package the client into a JAR file, type the following command:

ant jar-client

This command creates the dist/hello-client.jar file.

Running the Client

To run the HelloClient program, type the following:

ant run

The program should display this line:

Hello Duke!

The ant run target executes this command:

java -classpath <cpath> hello.HelloClient

The classpath includes the hello-client.jar file that you created in the preceding section, as well as several JAR files that belong to the Java WSDP. In order to run the client remotely, all of these JAR files must reside on the remote client’s computer.

Iterative Development

In order to show you each step of development, the previous sections instructed you to type several ant commands. However, it would be inconvenient to type all of those commands during iterative development. To save time, after you’ve initially deployed the service, you can iterate through these steps:

  1. Test the application.
  2. Edit the source files.
  3. Execute ant build to create the deployable WAR file.
  4. Execute ant redeploy to undeploy and deploy the service.
  5. Execute ant build-static to create the JAR file for a client with static stubs.
  6. Execute ant run.

Implementation-Specific Features

To implement the JAX-RPC Specification, the Java WSDP requires some features that are not described in the specification. These features are specific to the Java WSDP and might not be compatible with implementations from other vendors. For JAX-RPC, the implementation-specific features of the Java WSDP follow:

  • config.xml – See Generating the Stubs for an example.
  • jaxrpc-ri.xml – See Packaging the WAR File for an example.
  • ties – In the preceding example, the ties are in the hello-jaxrpc.war file, which is implementation-specific. (The hello-portable.war file, however, is not implementation-specific.)
  • stubs – The stubs are in the hello-client.jar file. Note that the HelloClient program instantiates MyHelloImpl, a static stub class that is implementation-specific. Because they do not contain static stubs, dynamic clients do not have this limitation. For more information about dynamic clients, see the sections A Dynamic Proxy Client Example and A Dynamic Invocation Interface (DII) Client Example .
  • tools – The wsdeploy, wscompile, and deploytool utilities.
  • support for collections – See Table 9-1.

Using JMX within a spring application

Lately I have been doing a lot with JMX. I use it more and more to check what my application is doing. I use it to monitor tomcat, the cache, queue’s and other libraries and components. Now I wanted to use jmx to monitor my own application. Using the standard JMX stuff coming with the JDK is not hard, but since I use a lot of spring, I wanted to know more about spring support.

The most important question in the end will be, is it easier to use spring with jmx than the standard jmx stuff from the jdk.

Read on to find out about jmx and my answer to the question which is easier, the spring way or the standard jmx way.

 

Background

Java Management Extension was introduced to create a uniform way to manage your java applications. A very basic console was introduced jConsole. You can now monitor the cpu usage of the jvm, memory consumption and lots of other characteristics. Frameworks and tools like tomcat, ActiveMQ and EHcache provided a lot of information through jmx.

Allard has written a whitepaper about jmx that you can find on the jteam website:

http://www.jteam.nl/dms/whitepapers/JavaApplicationMonitoringAndManagement.pdf

I want to have a better look at providing your own management information through jmx. For a project I was interested in the internals of a connection pool. I wanted to learn about the amount of active connections, the idle connections, passivations and activations. For the Axon Framework we wanted to have a better insight in the amount of event listeners, command handlers, received events and handled commands. For Axon we want to use as little springframework as possible and for the other project with the connections pool I want the easiest solution.

I big advantage of jmx is that you are able to use a generic client to access it. Disadvantage is that you must have this generic client and that firewalls must enable you to connect to the jmx server. Therefore I want to have a very basic web client that provides the most basic jmx information through a web interface.

Introducing the example

The sample is a very basic service that is used to store contacts. The service provides a statistics object that keeps data about the amount of stored contacts. If you are looking for code, check the code at my source repository at google code.

http://code.google.com/p/gridshore/source/browse/#svn/trunk/JMXMonitor

MBeans the jdk way

The jdk comes with jmx out of the box. It is not hard to use. You must create an interface that ends with MXBean or use the annotation. Of course there must be an implementation as well. The implementation is than used to manage facets of your application. In our example we expose one parameter, the amount of registered contacts. The implementation uses the ContactServiceStatistics from the the ContactService. This statistics object exposes the amount of registered contacts.

Now we need to actually do something with jmx. There are two major steps:

  1. Obtain the platform mbeanserver
  2. Register the MXBean with the mbeanserver

Now we can interact with the service by adding contacts. Using the jdk provided jmx client, we can see the amount of registered contacts. The following code block shows the code for the Runner class that executes the example and provides the command line interface to add new contacts.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public class Runner {
    public static void main(String[] args) throws Exception {
        MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
        ContactService service = new InMemoryContactService();
        ContactServiceMonitorMXBean mbean = new ContactServiceMonitor(service);
        ObjectName monitorName = new ObjectName("Gridshore:name=contactServiceMonitor");
        mbeanServer.registerMBean(mbean, monitorName);
        String input = "";
        do {
            System.out.println("Type stop if you want to, well euh, stop !");
            input = (new BufferedReader(new InputStreamReader(System.in))).readLine();
            service.addContact(new Contact(0, input));
        } while (!"stop".equals(input));
    }
}

The amount of code is oke, not very hard to implement. The following image gives a screendump of jconsole with the MXBean in it. Notice the location of the MXBean. The ObjectName is used to determine the location for the bean. The configured name is “Gridshore:name=contactServiceMonitor” which can easily be identified in the jconsole image.

jconsole screendump from runner without jdk

MBeans the spring way

Now let us have a look at what spring can do for us when doing jmx. The support for jmx from spring is extensive. A complete section in the reference manual is dedicated to jmx. We are only touching a small part, but an important part. You can find out more about the spring jmx way here:

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jmx.html

If you know your way with spring, the first thing that comes to mind is xml. Oke, nowadays a lot of annotations make life easier. With spring, the jdk way to find the mbeanserver and to register the beans is made easier. The javacode is replaced with some xml and annotations. I agree that in this specific case with the very basic sample the jdk way might even look easier. Still it fit’s nice with our own spring applications and there is a very big advantage using spring. That is when you want to create your own client. Spring comes with something nice to support that, this is explained in the next section.

The spring solution again consists of an interface and an implementation. The interface is actually only used for the client, so we could do with only the java class. Than we need an xml config file with only two items:

1
2
3
4
<beans>
    <context:component-scan base-package="nl.gridshore.monitoring"/>
    <context:mbean-export registration="replaceExisting"/>
</beans>

The runner now becomes incredible easy. The following lines of code show the complete runner

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
public class Runner {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "nl/gridshore/monitoring/springannotation/spring-config.xml");
        ContactService service = context.getBean(ContactService.class);
        String name = "";
        do {
            System.out.println("Type stop if you want to, well euh, stop !");
            name = (new BufferedReader(new InputStreamReader(System.in))).readLine();
            service.addContact(new Contact(0,name));
        } while (!"stop".equals(name));
    }
}

Now the jconsole looks like the following image. Check that we now have an additional folder in the folder tree. This is the type of the bean that is registered with the mbeanserver. More on this name when we discuss the client.

jconsole while running the spring runner

JMX clients

Nice to show the data through the jconsole application. There is a catch. Of course you need to have java to start the console. But you also need to explicitly enable it for remote access. Usually this mean firewall changes. Not the easiest way. If you want basic information it might be easier to create a client yourself.

Of course the jdk comes with client capabilities as well. I did however not spend a lot of time looking at them. With spring it becomes so easy to create a client that I only look at the spring way to create a client. Check out the following page if you want more information.

http://java.sun.com/docs/books/tutorial/jmx/remote/custom.html

Spring proxy

Spring comes with a class that acts as a proxy to an MBean. This can be a bean of yourself, a bean provided by a library but also a bean running in a remote jmx server. The following lines show the addition xml configuration for the proxy. You need an interface that is implemented by the proxy. It is easy if the MXBean implements this interface, but as long as the methods are available it is not required. Using this interface you can inject the proxy into another class, the JMXTestClient. Which in itself can be a controller or a service in your own application.

1
2
3
4
5
<bean id="proxyContactServiceMonitor" class="org.springframework.jmx.access.MBeanProxyFactoryBean">
    <property name="objectName"
              value="nl.gridshore.monitoring.springannotation:name=contactServiceMonitorSpring,type=ContactServiceMonitorSpring"/>
    <property name="proxyInterface" value="nl.gridshore.monitoring.springannotation.ContactServiceMonitor"/>
</bean>

Have a good look at the value for objectName. It consists of the package name of the class that is registered as an mbean. The name is is the registeren spring bean name and the type is the actual class name.

Now the client becomes very easy. The following code block shows the client as well as the new Runner class that makes use of the client.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Component("client")
public class JmxTestClient {
    private ContactServiceMonitor contactServiceMonitor;
    public int obtainAmountOfContact() {
        return contactServiceMonitor.getAmountOfContacts();
    }
    @Autowired
    public void setContactServiceMonitor(@Qualifier("proxyContactServiceMonitor")ContactServiceMonitor contactServiceMonitor) {
        this.contactServiceMonitor = contactServiceMonitor;
    }
}
public class Runner {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("nl/gridshore/monitoring/springannotation/spring-config.xml");
        ContactService service = context.getBean(ContactService.class);
        String name = "";
        do {
            int amountOfContacts = context.getBean(JmxTestClient.class).obtainAmountOfContact();
            System.out.println("Amount of contacts now is : " + amountOfContacts);
            System.out.println("Type stop if you want to, well euh, stop !");
            name = (new BufferedReader(new InputStreamReader(System.in))).readLine();
            service.addContact(new Contact(0,name));
        } while (!"stop".equals(name));
    }
}

The following code block shows you a screendump of a jmx client that is used to monitor the amount of items and sessions in a connection pool as well as basic information about the cache in use.

Screen shot 2010-06-02 at 21.39.50.png

Conclusion

I like the way spring helps you in hiding some complexity. To be honest with these simple examples spring is not less code than with the plain jdk way of jmx interaction. But if the amount of beans increase, to my opinion spring becomes easier. If you are already creating a spring application I would also do the spring way, it just fits better.

What is Spring?

Spring is great framework for development of Enterprise grade applications. Spring is a light-weight framework for the development of enterprise-ready applications. Spring can be used to configure declarative transaction management, remote access to your logic using RMI or web services, mailing facilities and various options in persisting your data to a database. Spring framework can be used in modular fashion, it allows to use in parts and leave the other components which is not required by the application.

Features of Spring Framework:

  • Transaction Management: Spring framework provides a generic abstraction layer for transaction management. This allowing the developer to add the pluggable transaction managers, and making it easy to demarcate transactions without dealing with low-level issues. Spring’s transaction support is not tied to J2EE environments and it can be also used in container less environments.
  • JDBC Exception Handling: The JDBC abstraction layer of the Spring offers a meaningful exception hierarchy, which simplifies the error handling strategy
  • Integration with Hibernate, JDO, and iBATIS: Spring provides best Integration services with Hibernate, JDO and iBATIS.
  • AOP Framework: Spring is best AOP framework
  • MVC Framework: Spring comes with MVC web application framework, built on core Spring functionality. This framework is highly configurable via strategy interfaces, and accommodates multiple view technologies like JSP, Velocity, Tiles, iText, and POI. But other frameworks can be easily used instead of Spring MVC Framework..

Spring Architecture

Spring is well-organized architecture consisting  of seven modules. Modules in the Spring framework are:

  1. Spring AOP
    One of the key components of Spring is the AOP framework. AOP is used in Spring:

    • To provide declarative enterprise services, especially as a replacement for EJB declarative services. The most important such service is declarative transaction management, which builds on Spring’s transaction abstraction.
    • To allow users to implement custom aspects, complementing their use of OOP with AOP
  2. Spring ORM
    The ORM package is related to the database access. It provides integration layers for popular object-relational mapping APIs, including JDO, Hibernate and iBatis.
  3. Spring Web
    The Spring Web module is part of Spring?s web application development stack, which includes Spring MVC.
  4. Spring DAO
    The DAO (Data Access Object) support in Spring is primarily for standardizing the data access work using the technologies like JDBC, Hibernate or JDO.
  5. Spring Context
    This package builds on the beans package to add support for message sources and for the Observer design pattern, and the ability for application objects to obtain resources using a consistent API.
  6. Spring Web MVC
    This is the Module which provides the MVC implementations for the web applications.
  7. Spring Core
    The Core package is the most import component of the Spring Framework.
    This component provides the Dependency Injection features. The BeanFactory  provides a factory pattern which separates the dependencies like initialization, creation and access of the objects from your actual program logic.

The following diagram represents the Spring Framework Architecture


Spring Framework Architecture

MyEclipse for Spring 10.0: Spring 3.0 MVC Scaffolding

1. Introduction

One of the goals of MyEclipse for Spring (ME4S) is to help developers write less code from scratch and use code generation more broadly, and ME4S offers the richest set of code generation options available anywhere. ME4S can generate software components for Spring MVC, Spring Web Flow, Spring Security, REST, JAX-WS, Adobe Flex, Google Web Toolkit (GWT), JPA, DAO and JSF 2.0/Primefaces. As an alternative to writing software components from scratch, ME4S helps developers generate software components that are specific to their project. In many cases the software components may be used as-is, or they may be used as a starting point for further development. Furthermore the developer can edit the ME4S templates to further customize how the software components are generated.

Scaffolding refers to the superset of ME4S’s broad code generation functions, from generating a specific set of requested software components to generating fully implemented ready-to-run applications. Besides the obvious benefits of reducing application development effort and sparing developers from some of the chores of development, scaffolding is also frequently used for rapidly developing functional prototypes, learning new technologies, and application modernization projects. The ability to quickly generate a full application is very beneficial to prototyping because you can iterate on a domain model and regenerate a functional prototype in minutes. The prototype can be used with business analysts as a tool for elaborating requirements and as the starting point for development. ME4S helps many developers learn new technologies by generating contextual reference projects, which are personalized projects that are based on their own data model. This is a considerably better approach than hunting for sample projects that are often incomplete, don’t follow modern best practices, and are based on trivial data models. ME4S can also be used to jumpstart an application modernization effort by leveraging application artifacts from the current system for generating a significant portion of the application components for the new system.

The objective of this tutorial is to walk you through the generation of software components for Spring MVC, which is a web framework from the creators of the Spring framework. In addition to generating the Spring MVC software components, this tutorial will also generate the software components for the service, domain, and data access layers. This will result in a fully implemented ready-to-run Spring MVC application that can be immediately used for validating and testing the generated Spring MVC components, and it will also serve a reference implementation for how the generated Spring MVC components integrate with the other components of an application.

Figure 1. Application Layers – Spring MVC

 

Application Architecture:

  • Web Layer – Spring MVC (@Controller)
  • Service Layer – Spring (@Service)
  • Domain Layer – JPA (@Entity)
  • Data Access Layer – Spring (@Repository)

Spring MVC – Annotation-based Programming Model

Spring MVC supports multiple approaches for implementing the web layer, and Spring 2.5 added support for an annotation-based programming model. The annotation-based approach has quickly become the predominant way of using Spring MVC, and it’s generally regarded as the best practice in Spring MVC development. The scaffolding functions of MyEclipse for Spring will generate the web layer using the annotation-based programming model.

What about other web technologies?

This tutorial is focused on Spring MVC, but the scaffolding wizard can also generate the web layer implementation for Spring Web Flow, JavaServer Faces (JSF 2.0), Adobe Flex, Google Web Toolkit (GWT) and iPhone.

Figure 2. MyEclipse for Spring CRUD Scaffolding

MyEclipse for Spring uses the Create-Read-Update-Delete (CRUD) application pattern for generating applications that allows the end-user to manage application data. While CRUD isn’t the only application pattern, it’s a fairly typical application pattern. While not all web applications are satisfied solely by the CRUD application pattern, developers find that the resulting generated application artifacts lend themselves to being easily re-used, customized and extended. CRUD applications are tied to an application domain model that is used as the input into the scaffolding engine. The domain model can exist in many forms, and the MyEclipse for Spring scaffolding functionality supports the use of Java beans, JPA entities, or database tables as inputs.

2. Goal

This tutorial is going to walk you through producing a ready-to-run Spring MVC application that implements the CRUD application pattern for a domain model.

  • Domain model: CUSTOMERS table from the MyEclipse Derby database.
  • Target Container: MyEclipse Tomcat
  • Target Database: MyEclipse Derby

MyEclipse for Spring will be used to generate the entire Spring 3.0 application within a matter of minutes that includes:

  • A JPA entity corresponding to domain model (CUSTOMERS)
  • A DAO for managing the JPA entity,
  • Finder methods (JPA named queries) in the DAO based on domain model fields,
  • A Service with fully implemented CRUD operations for managing domain model,
  • A Controller with fully implemented request handlers for supporting web application,
  • All the necessary Spring annotations and configuration files for a Spring MVC app,
  • CRUD JSP pages using Spring Form tag library and JSTL
  • Layout managed user interface using Sitemesh,
  • Client-side validation implemented Spring JS with DOJO,
  • CSS for UI styling
  • JUnits for every Service and Controller,
  • SpringSource certified code and configuration files,
  • Generated code that follows Spring Recipes,

3. Prerequisites

The prerequisites needed to complete this tutorial are:

4. Create Web Project

  1. Create a MyEclipse Web Project (or Eclipse Dynamic Web Project) called CustomersApp.
    Figure 3. New Web Project

    Incompatible Compiler Compliance Level

    If you get a popup dialog regarding the project compiler compliance level not matching the workspace default, specify that you want to use a custom setting for the project [click the Yes button].

5. Scaffold from Database Tables

It’s now time to generate all the software components and configuration files required to implement the CRUD application.

  1. Right-click on the CustomersApp project, and choose MyEclipse > Scaffold Spring CRUD application…
    Figure 4. Scaffolding Wizard

  2. The first step is to select the type of artifact you want to scaffold from. As mentioned in the introduction there are a variety of possible inputs into scaffolding. For this tutorial we’re going to scaffold from a pre-existing database table that comes with the MyEclipse Derby database. Choose the Database Schema option on the Select Artifact Type(s) panel. Click the Next button.
    Figure 5. Select Artifact Type(s)

  3. The next step is to select the DB connection for accessing the MyEclipse Derby database. This panel will show you all configured DB connections in the MyEclipse workspace, and you must select the MyEclipse Derby connection, which is a preconfigured DB connection in MyEclipse. Click the Next button.
    Figure 6. Specify Persistence Connection Properties

  4. The next step is to specify which database table(s) to scaffold an application from. Start by selecting the desired schema, and the select the database table(s) that should be used for scaffolding. When the CLASSICCARS schema is selected, the tables list will be populated with a list of tables. The CUSTOMER table should be added to the scaffolding list. Click the Next button.
    Figure 7. Select Database Tables

  5. The next panel will prompt you to select parent objects, and this panel also lets you override the derived name of the Java Object that will be created from the database table. Since we’re only scaffolding from a single database table, the Customer Java object must be the parent. For this tutorial there’s nothing that needs to be changed on this panel. Just click the Next button.
    Figure 8. Database Scaffolding Options

    Overriding derived Java object names

    Java Object names are automatically derived from table names, but the name can be overridden by double-clicking on the name and typing a new name.

  6. The next step is to specify which layers of the application should be scaffolded and which package names should be used for each layer. All the layers are enabled by default. Enter org.customerapp as the base package. The package names for the different layers will be automatically derived from the base package. A sub-package (i.e. web, service, DAO, and domain) will be added to the end of the base package.
    Figure 9. Application Layers and Packages

  7. The next step is to specify which web clients should be generated for the web layer. As you can see, there are a variety of different web clients available, including Spring MVC, Spring Web Flow, Adobe Flex, GWT, and iPhone. This tutorial is focused on Spring MVC, so click on the Generate checkbox for Spring MVC.
    Figure 10. Select Web Client

  8. The next step is an optional step to specify the REST scaffolding options. Since REST scaffolding is beyond the scope of this tutorial, we’ll just skip to the next step of the wizard.
    Figure 11. REST options

  9. The next step is in an optional step to customize the UI. For this tutorial we’ll go with the defaults.
    Figure 12. Customize UI

    Overriding field names for user interface

    The field names are automatically derived from the column names of the selected database tables, but the field name can be overridden by double-clicking on the name and typing a new name.

  10. The next step is to specify where the application (source code, configuration files, JSP, etc…) should be generated to in the current project and a few additional scaffolding options. For this panel the defaults are fine. Click the Next button.
    Figure 13. Select Target Folders

  11. The final configuration step is to specify the libraries that should be added to the current project, how they should be added (classpath containers or copied into project), and the version of Spring MVC to use. For this panel the defaults are fine. Click the Next button.
    Figure 14. Runtime Dependencies

  12. The final panel will give you a summary of everything that will be generated for you. Click the Finish button to scaffold the application from the information you provided in the wizard.
    Figure 15. Summary

That’s it. Once the wizard is complete you have a ready-to-run Spring MVC application that implements the CRUD application pattern for the domain model (CUSTOMERS DB table).

Scaffold Spring DSL

If you want to use the Spring DSL, then you will need enable the project for Spring DSL support prior to scaffolding. See Enable Spring DSL in the reference guide for more info.

6. Deploy the App

The next step is to see the application in operation by deploying it to Tomcat. The running application can be used for validating the generated Spring MVC components and observing the integration with the other components of the application.

  1. To deploy the application, right-click on the CustomersApp project and select Run As –> MyEclipse Server Application.
    Figure 16. Run As –> MyEclipse Server Application

  2. MyEclipse Tomcat will start up. The first page will be a dashboard for accessing all scaffolded web clients. Since this tutorial only scaffolded a single database table for Spring MVC, the only option under Spring MVC is View Customers. Click on it to see generated Spring MVC application in operation.

    Run in a separate web browser?

    If you want to run the Spring MVC application in a separate browser, use the following URL: http://localhost/CustomersApp/

    Figure 17. Dashboard

  3. The Spring MVC application can be used to (a) list all customers, (b) view customer details, (c) edit customer details, (d) delete customers and (e) add new customers. The following screen shots show some of the views.
    Figure 18. CustomerApp – List

    Figure 19. CustomerApp – Edit Details

7. What’s generated?

The scaffolded application is compromised of many integrated software components, and the following diagrams provide an overview of which software components were generated and where they can be found in the project. Understanding what gets generated (and where) will help you find the individual or set of software components that you want use in your own developent projects.

Scaffolding Note

In order to ease your way into code generation with ME4S, this tutorial only involved scaffolding from a single database table. Therefore only the software components for managing a single entity were generated, and there were no entity relationships. When you start generating for multiple entities, potentially with entity relationships, there will be a lot more software components generated than what was generated with this tutorial. Even though there’s a lot more code, it will all be grouped and organized as shown in the following diagrams.

Figure 20. What’s generated with Spring MVC Scaffolding (part 1)

 

Figure 21. What’s generated with Spring MVC Scaffolding (part 2)

 

The Spring MVC scaffolding blueprint provides a snapshot of what gets generated during scaffolding. The Spring MVC blueprint and the blueprints for the other ME4S code generations capabilities are covered in more detail in the MyEclipse for Spring reference guide. (see Additional Developer Resources).

Figure 22. Spring MVC Scaffolding Blueprint

 

8. Conclusion

Now that you have a running Spring MVC application, you may want re-run the tutorial and scaffold different web clients, including Spring Web Flow, JavaServer Faces (JSF 2.0), Adobe Flex, Google Web Toolkit (GWT), and iPhone.

You may also want to try the Spring Annotator, JAX-WS Annotator and JPA annotator tutorials which are available in the Eclipse help system and online (see Additional Developer Resources).

What was your experience with this tutorial? Share your experience with us by completing a very brief survey.