Monday, January 19, 2015

Some useful links

Spring Tutorial http://www.javabeat.net/spring-tutorials/ Struts2 http://www.tutorialspoint.com/struts_2/struts_quick_guide.htm Dinesh on Java http://www.dineshonjava.com J2EE Patterns http://www.corej2eepatterns.com/ServiceActivator.htm Hadoop for Windows http://www.codeproject.com/Articles/757934/Apache-Hadoop-for-Windows-Platform (Beware: the downloads in this link don't work)

hacks

Hacks

linux
------

sudo /usr/sbin/tcpdump -nni any port 5060 -s0 -A

netstat -apnt


Asterisk CLI:
sudo /usr/sbin/asterisk -vvvgc
module reload chan_sip.so

core set verbose 3

dialplan reload

queue show

core show help

module show like cdr

cdr show status

sip show users

Asterix links
-------------

#asterisk queues

http://www.orderlyq.com/asteriskqueues.html

#beginners tutorial

http://apricot.net/apricot2006/slides/tutorial/tuesday/Jonny_Martin-Asterisk.pdf

#FastAGI
http://www.asterisk-java.org/development/tutorial.html

http://www.jcgonzalez.com/asterisk-handle-calls-with-java-example


SIPp links
----------

http://sipp.sourceforge.net/doc/reference.pdf

Android

See https://blog-emildesign.rhcloud.com/?p=435
on how to set up the Android maps project


jar signer

C:\Program Files (x86)\Java\jdk1.6.0_17\bin>jarsigner 
-verbose -sigalg SHA1withRSA -digestalg SHA1 
-keystore my-release-key.keystore 
c:\users\dgandikota\Desktop\Peble.apk alias_name


Adb installation

C:\eclipseworkspace\Peble\bin>"c:\Program Files 
(x86)\Android\android-sdk\platfo
rm-tools\adb.exe" install -r c:\users\dgandikota\desktop\Peble.apk

To fire up emulator

C:\eclipseworkspace\Peble\bin>"c:\Program Files (x86)\Android\android-sdk\platfo
rm-tools\adb.exe" shell
root@android:/ # input keyevent 82

Ftp with Android

FTP on Android

package com.example.peble;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.UnknownHostException;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class FtpActivity extends Activity {
    static Uri currImageURI;
    static TextView tv;
     public void upload( String ftpServer, String user, String password,
             String fileName, String source, String port ) throws MalformedURLException,
             IOException
       {
         Toast.makeText(getApplicationContext(),
                    "pinging",
                    Toast.LENGTH_LONG).show();
         int count = 0;
            String str = "";
            try {
                Process process = Runtime.getRuntime().exec(
                        "/system/bin/ping -c 8 " + ftpServer);
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        process.getInputStream()));
                int i;
                char[] buffer = new char[4096];
                StringBuffer output = new StringBuffer();
                while ((i = reader.read(buffer)) > 0)
                    output.append(buffer, 0, i);
                reader.close();

                // body.append(output.toString()+"\n");
                str = output.toString();
                Toast.makeText(getApplicationContext(),
                        str,
                        Toast.LENGTH_LONG).show();
                // Log.d(TAG, str);
            } catch (IOException e) {
                Toast.makeText(getApplicationContext(),
                        "exception in pingsystem",
                        Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                Toast.makeText(getApplicationContext(),
                        "error in pingsystem",
                        Toast.LENGTH_LONG).show();
            }
            Toast.makeText(getApplicationContext(),
                    "trying inet",
                    Toast.LENGTH_LONG).show();
             InetAddress in;
            in = null;
            // Definimos la ip de la cual haremos el ping
            try {
                in = InetAddress.getByName(ftpServer);
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                Toast.makeText(getApplicationContext(),
                        "unknown host " + e.getMessage(),
                        Toast.LENGTH_LONG).show();
            }    catch (Exception e) {
                Toast.makeText(getApplicationContext(),
                        "exception error unknown host " + e.getMessage(),
                        Toast.LENGTH_LONG).show();
            }
            // Definimos un tiempo en el cual ha de responder
            try {
                if (in.isReachable(5000)) {
                    Toast.makeText(getApplicationContext(),
                            "is reachable",
                            Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(),
                            "no response",
                            Toast.LENGTH_LONG).show();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                Toast.makeText(getApplicationContext(),
                        "exception " + e.getMessage(),
                        Toast.LENGTH_LONG).show();
            } catch (Exception e) {
                Toast.makeText(getApplicationContext(),
                        "exception error is reachable" + e.getMessage(),
                        Toast.LENGTH_LONG).show();
            }

         Toast.makeText(getApplicationContext(),
                    "uploading",
                    Toast.LENGTH_LONG).show();
          if (ftpServer != null)
          {

             BufferedInputStream bis = null;
             BufferedOutputStream bos = null;
             try
             {
                 FTPClient fc= new FTPClient();
                 Toast.makeText(getApplicationContext(),
                         "uploading2 " + fc.toString() + ";"+ ftpServer + ":"+port + "inet address:" + InetAddress.getByName(ftpServer),
                         Toast.LENGTH_LONG).show();
//                 fc.connect(InetAddress.getByName(ftpServer));
                 fc.connect(InetAddress.getByName(ftpServer), Integer.parseInt(port));
//                 fc.connect("ftp://test:test@10.0.85.120:2121;type=i", 2121);
                 Toast.makeText(getApplicationContext(),
                         "uploading3",
                         Toast.LENGTH_LONG).show();
                 fc.login(user, password);
                 Toast.makeText(getApplicationContext(),
                         "uploading4",
                         Toast.LENGTH_LONG).show();
                 //fc.setFileType(FTP.BINARY_FILE_TYPE);
                 Toast.makeText(getApplicationContext(),
                         "uploading5",
                         Toast.LENGTH_LONG).show();
                 bis = new BufferedInputStream( new FileInputStream(
                         source) );
                 Toast.makeText(getApplicationContext(),
                         "uploading6",
                         Toast.LENGTH_LONG).show();
                 fc.storeFile(fileName, bis);
                 bis.close();
             }  catch (UnknownHostException e) {
                 Toast.makeText(getApplicationContext(),
                            "unknown host" + e.getMessage(),
                            Toast.LENGTH_LONG).show();
             }
                 catch (SocketException e) {
                 Toast.makeText(getApplicationContext(),
                            "socket exception" + e.getMessage(),
                            Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    Toast.makeText(getApplicationContext(),
                            "ioexception" + e.getMessage(),
                            Toast.LENGTH_LONG).show();
                }
                 catch (Exception e) {
                 Toast.makeText(getApplicationContext(),
                            "error here" + e.getMessage(),
                            Toast.LENGTH_LONG).show();
             }
             finally
             {
                if (bis != null)
                   try
                   {
                      bis.close();
                   }
                   catch (IOException ioe)
                   {
                      ioe.printStackTrace();
                   }
                if (bos != null)
                   try
                   {
                      bos.close();
                   }
                   catch (IOException ioe)
                   {
                      ioe.printStackTrace();
                   }
             }
          }
          else
          {
              Toast.makeText(getApplicationContext(),
                        "error here2" ,
                        Toast.LENGTH_LONG).show();
          }
       }

       /**
        * Download a file from a FTP server. A FTP URL is generated with the
        * following syntax:
        * ftp://user:password@host:port/filePath;type=i.
        *
        * @param ftpServer , FTP server address (optional port ':portNumber').
        * @param user , Optional user name to login.
        * @param password , Optional password for user.
        * @param fileName , Name of file to download (with optional preceeding
        *            relative path, e.g. one/two/three.txt).
        * @param destination , Destination file to save.
        * @throws MalformedURLException, IOException on error.
        */
       public void download( String ftpServer, String user, String password,
             String fileName, String destination, String port ) throws MalformedURLException,
             IOException
       {
          if (ftpServer != null  && fileName != null  && destination != null)
          {
             BufferedInputStream bis = null;
             BufferedOutputStream bos = null;
             try
             {
                FTPClient fc= new FTPClient();
//                fc.connect(ftpServer, Integer.parseInt(port));
//                fc.login(user, password);
//                fc.setFileType(FTP.BINARY_FILE_TYPE);
                bos = new BufferedOutputStream( new FileOutputStream(
                        destination) );
//                fc.retrieveFile(fileName, bos);
                bos.close();
//                fc.deleteFile(fileName);
             }
             finally
             {
                if (bis != null)
                   try
                   {
                      bis.close();
                   }
                   catch (IOException ioe)
                   {
                      ioe.printStackTrace();
                   }
                if (bos != null)
                   try
                   {
                      bos.close();
                   }
                   catch (IOException ioe)
                   {
                      ioe.printStackTrace();
                   }
             }
          }
          else
          {
             System.out.println( "Input not available" );
          }
       }
       
       @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_ftp);
       }
    // To handle when an image is selected from the browser, add the following to your Activity 
        @Override 
        public void onActivityResult(int requestCode, int resultCode, Intent data) { 
         
         if (resultCode == RESULT_OK) { 
         
         if (requestCode == 1) { 
         
         // currImageURI is the global variable I’m using to hold the content:// URI of the image 
             Toast.makeText(getApplicationContext(),
                        "got currimage" ,
                        Toast.LENGTH_LONG).show();
         currImageURI = data.getData();
         Toast.makeText(getApplicationContext(),
                    "go currimageuri=" + currImageURI ,
                    Toast.LENGTH_LONG).show();
         } 
         } 
        } 
         
        // And to convert the image URI to the direct file system path of the image file 
        public String getRealPathFromURI(Uri contentUri) { 
         
         // can post image 
         String [] proj={MediaStore.Images.Media.DATA}; 
         Cursor cursor = getContentResolver().query(contentUri,
         proj, // Which columns to return 
         null, // WHERE clause; which rows to return (all rows) 
         null, // WHERE clause selection arguments (none) 
         null); // Order-by clause (ascending by name) 
         int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
         cursor.moveToFirst(); 
         
         return cursor.getString(column_index); 
        } 
        /** Called when the user clicks the Select File button */
        public void selectFile(View view) throws Exception {
                Intent picIntent = new Intent();
                picIntent.setType("image/*");
                picIntent.setAction(Intent.ACTION_GET_CONTENT); 
                startActivityForResult(Intent.createChooser(picIntent, "Select Picture"),1); 
        }
        public void uploadFile(View view) throws Exception {
            if (currImageURI != null)
            Toast.makeText(getApplicationContext(),
                    "currImageURI=" + currImageURI.toString(),
                    Toast.LENGTH_LONG).show();
            Toast.makeText(getApplicationContext(),
                    "calling upload" ,
                    Toast.LENGTH_LONG).show();
//            upload("10.0.99.99", "test", "test", currImageURI.toString(), currImageURI.toString(), "2121" );
//            upload("206.82.244.11", "test", "test", currImageURI.toString(), currImageURI.toString(), "2121" );
//            upload("10.0.85.120", "test", "test", null, null, "2121" );
//            upload("213.202.225.203", "test", "test", null, null, "2121" );
            ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);  
            NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();        
            if (networkInfo != null && networkInfo.isConnected()) {
                Toast.makeText(getApplicationContext(),
                        "starting async task",
                        Toast.LENGTH_LONG).show();
                 tv = (TextView) findViewById(R.id.uploadFilename);
                if (tv != null) tv.setText("hello");
                new DownloadWebpageTask().execute("test");       
            } else {  
                Toast.makeText(getApplicationContext(),
                        "not network",
                        Toast.LENGTH_LONG).show();
            }
            
        }
        
        private class DownloadWebpageTask extends AsyncTask {       
            String result="";
            @Override     
            protected String doInBackground(String... urls) {                          
                // params comes from the execute() call: params[0] is the url.   
                InetAddress in;
                in = null;
                 result += "entered doinbackground";
                 // Definimos la ip de la cual haremos el ping
                try {
                    in = InetAddress.getByName("10.0.85.120");
                    result += ";in done";
                } catch (UnknownHostException e) {
                    // TODO Auto-generated catch block
                    result += ";not reachable5!" + e.getMessage();
                }    catch (Exception e) {
                    result += ";not reachable4!" + e.getMessage();
                }
                // Definimos un tiempo en el cual ha de responder
                try {
                    
                    if (in != null && in.isReachable(5000)) {
                        result += ";reachable!";
                    } else {
                        result +=";not reachable";
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    result += ";not reachable!" + e.getMessage();
                } catch (Exception e) {
                    result += ";not reachable2!" + e.getMessage();
                }  
                FTPClient fc= new FTPClient();
                try
                 {
                     fc.connect("10.0.85.120", 2121); 
                     result += fc.getReplyString();
                     int reply = fc.getReplyCode();

                     result += "reply=" + reply;
                   if(!FTPReply.isPositiveCompletion(reply)) {
                     fc.disconnect();
                     result += "invalid reply code";
                   }
                       fc.enterLocalPassiveMode();
                     result += "local passive mode;connect sucess";
                     boolean b=fc.login("test", "test");
                     if (!b) {
                         result += ";login failed";
                     } else
                     result += ";login success";
                     if (fc.isConnected()) {
                         result += "; is connected";
                         FTPFile [] fileList=fc.listFiles();
                         reply = fc.getReplyCode();
                         fc.enterLocalPassiveMode();
                          result += "local passive mode;connect sucess";
                          result += "reply2=" + reply;
                          if(!FTPReply.isPositiveCompletion(reply)) {
                              fc.disconnect();
                              result += "invalid reply code2";
                          }
                         for(FTPFile f : fileList) {
                             result += ";" + f.getName();
                         }
                     }
                     result += ";disconnect";
                     fc.disconnect();
                    result +=";connect success";
                 } catch (Exception e) {
                     result += ";not reachable3!" + e.getMessage() + ";reply=" + fc.getReplyCode();
                 }
                
                return result;
            }
            // onPostExecute displays the results of the AsyncTask.        
            @Override        
            protected void onPostExecute(String result) {   
                tv.setText(result);
            }    
    }
}

Android sending text message with attachment

package com.example.peble;

import java.io.FileOutputStream;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.NavUtils;
import android.telephony.SmsManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.maps.MapActivity;

public class DisplayMessageActivity extends MapActivity {
 String message="";
 LocationManager locationManager; //<2>  
 Uri currImageURI;
 String smsText="";
 @Override
 protected boolean isRouteDisplayed() {
  return false;
 }
 @Override
 protected void onStart() {
  super.onStart();
  message="";
 }
 @Override
 protected void onRestart() {
  super.onRestart();
  message="";
 }
 public void onRestoreInstanceState(Bundle savedInstanceState) {    
  // Always call the superclass so it can restore the view hierarchy    
  super.onRestoreInstanceState(savedInstanceState);       // Restore state members from saved instance   
 }
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  if (savedInstanceState != null) {
   message = savedInstanceState.getString("message");
  }
    // Get the message from the intent
     Intent intent = getIntent();
     if (message.trim().equals(""))
     message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
     Toast.makeText(getApplicationContext(),
    "message="+message ,
    Toast.LENGTH_LONG).show();
     String filename = "peble_contacts.txt";
     FileOutputStream outputStream;
     try {
      outputStream = openFileOutput(filename, Context.CONTEXT_IGNORE_SECURITY);
      outputStream.write(message.getBytes());
      outputStream.close();
     } catch (Exception e) {
      System.out.println("cannot read file");
     }
     smsText="Please help!";
     try {
      locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
   Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
   
         if (location != null) {
             smsText += String.format(
                     "Current Location \n Longitude: %1$s \n Latitude: %2$s",
                     location.getLongitude(), location.getLatitude()
             );
         }
     } catch (Exception e) {
      Toast.makeText(getApplicationContext(),
     "Location faild, please try again later!",
     Toast.LENGTH_LONG).show();
     }
     try {
//   SmsManager smsManager = SmsManager.getDefault();
//   smsManager.sendTextMessage(message, null, smsText, null, null);
//   Intent sendIntent = new Intent(Intent.ACTION_SEND); 
//      Intent sendIntent = new Intent(Intent.ACTION_VIEW);
      
   //sendIntent.setClassName("com.android.mms", "com.android.mms.ui.ComposeMessageActivity");
//      sendIntent.setType("vnd.android-dir/mms-sms");
//   sendIntent.putExtra("address", message);
//   sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///users/public/pictures/sample pictures/chrysanthemum.jpg"));
//      Runnable myRunnable = new Thread(new Runnable() { public void run() {
//       Intent picIntent = new Intent();
//    picIntent.setType("image/*");
//    picIntent.setAction(Intent.ACTION_GET_CONTENT); 
//    startActivityForResult(Intent.createChooser(picIntent, "Select Picture"),1); 
//     this.notify();
//    }});
//      synchronized(myRunnable) {
//       runOnUiThread(myRunnable);
//       myRunnable.wait();
//      }
////   new Thread(new Runnable() { public void run() {
//    Uri uri = Uri.parse("smsto:" + message);
//       Intent sendIntent = new Intent(Intent.ACTION_SENDTO, uri);
//    sendIntent.putExtra(Intent.EXTRA_STREAM, currImageURI);
//    sendIntent.putExtra("sms_body", smsText); 
//    startActivity(sendIntent);
////   }}).start();
//   Toast.makeText(getApplicationContext(), smsText + " Sent!",
//      Toast.LENGTH_LONG).show();
   //sending audio or video
   /*
    * Intent sendIntent = new Intent(Intent.ACTION_SEND); 
sendIntent.setClassName("com.android.mms", "com.android.mms.ui.ComposeMessageActivity");
sendIntent.putExtra("address", "1213123123");
sendIntent.putExtra("sms_body", "if you are sending text");   
final File file1 = new File(mFileName);
if(file1.exists()){
  System.out.println("file is exist");
}
Uri uri = Uri.fromFile(file1);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri);
sendIntent.setType("video/*");
startActivity(sendIntent);
    */
    } catch (Exception e) {
   Toast.makeText(getApplicationContext(),
    "SMS faild, please try again later!" + e.getMessage(),
    Toast.LENGTH_LONG).show();
   e.printStackTrace();
    }
     // Create the text view
     TextView textView = new TextView(this);
     textView.setTextSize(40);
     textView.setText(message + " will be sent your help Message: " + smsText);
     // Set the text view as the activity layout
//     setContentView(textView);
     setContentView(R.layout.activity_display_message);
 }

 /**
  * Set up the {@link android.app.ActionBar}, if the API is available.
  */
 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
 private void setupActionBar() {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
   getActionBar().setDisplayHomeAsUpEnabled(true);
  }
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.display_message, menu);
  return true;
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {
  case android.R.id.home:
   // This ID represents the Home or Up button. In the case of this
   // activity, the Up button is shown. Use NavUtils to allow users
   // to navigate up one level in the application structure. For
   // more details, see the Navigation pattern on Android Design:
   //
   // http://developer.android.com/design/patterns/navigation.html#up-vs-back
   //
   NavUtils.navigateUpFromSameTask(this);
   return true;
  }
  return super.onOptionsItemSelected(item);
 }
 // To handle when an image is selected from the browser, add the following to your Activity 
 @Override 
 public void onActivityResult(int requestCode, int resultCode, Intent data) { 
  
  if (resultCode == RESULT_OK) { 
  
  if (requestCode == 1) { 
  
  // currImageURI is the global variable I’m using to hold the content:// URI of the image 
  currImageURI = data.getData(); 
  } 
  } 
 } 
  
 // And to convert the image URI to the direct file system path of the image file 
 public String getRealPathFromURI(Uri contentUri) { 
  
  // can post image 
  String [] proj={MediaStore.Images.Media.DATA}; 
  Cursor cursor = managedQuery( contentUri, 
  proj, // Which columns to return 
  null, // WHERE clause; which rows to return (all rows) 
  null, // WHERE clause selection arguments (none) 
  null); // Order-by clause (ascending by name) 
  int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
  cursor.moveToFirst(); 
  
  return cursor.getString(column_index); 
 } 
 /** Called when the user clicks the Send button */
 public void attachImage(View view) {
     // Do something in response to button
  Intent picIntent = new Intent();
  picIntent.setType("image/*");
  picIntent.setAction(Intent.ACTION_GET_CONTENT); 
  startActivityForResult(Intent.createChooser(picIntent, "Select Picture"),1); 
 }
 public void sendText(View view) {
  Intent intent = getIntent();
     message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
  Toast.makeText(getApplicationContext(),
    "phonenm=" + message ,
    Toast.LENGTH_LONG).show();
  Uri uri = Uri.parse("smsto:" + message);
     Intent sendIntent = new Intent(Intent.ACTION_SENDTO, uri);
//     sendIntent.setType("vnd.android-dir/mms-sms");
  sendIntent.putExtra("sms_body", smsText);
  sendIntent.putExtra("address", message);
  sendIntent.setData(Uri.parse("smsto:" + message)); 
  if (currImageURI != null)
  sendIntent.putExtra(Intent.EXTRA_STREAM, currImageURI);
  startActivity(sendIntent);
  Toast.makeText(getApplicationContext(),
    "SMS success" ,
    Toast.LENGTH_LONG).show();
 }
}


Freeswitch mod_java with Launcher

To dynamically load classes in Freeswitch use this Laucher:
/*
 * Launcher.java
 *
 * Created on 13 September 2007, 06:40
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.freeswitch;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 *
 * @author dacha
 */
public class Launcher
{
    static
    {
        // Find and load mod_java
        String javaLibraryPaths = System.getProperty("java.library.path");
        String pathSeparator = System.getProperty("path.separator");
        String libraryPaths[] = javaLibraryPaths.split(pathSeparator);
        
        String libraryName = System.mapLibraryName("mod_java");
        int modJavaIndex = libraryName.indexOf("mod_java");
        if (modJavaIndex >= 0)
            libraryName = libraryName.substring(modJavaIndex);
        
        for (String libraryPath : libraryPaths)
        {
            String fullLibraryPath = libraryPath + File.separatorChar + libraryName;
            if (new File(fullLibraryPath).exists())
            {
                System.load(fullLibraryPath);
                break;
            }
        }
    }

    public static void launch(String sessionUuid, String args) throws Exception
    {
        String argv[] = args.split("[ ]");
        if (argv.length == 0)
        {
            System.out.println("Too few arguments to mod java");
            System.out.println("Usage: java /path/to/file.jar fully.qualified.class arg1 arg2 arg3");
            System.out.println("Usage: java fully.qualified.class arg1 arg2 arg3");
            return;
        }
        
        Class klazz=null;

        int argsOffset;
 System.out.println("argv[0]=" + argv[0]);
        if (argv[0].endsWith(".jar") || argv[0].endsWith(".JAR"))
        {
  System.out.println("in jar");
            if (argv.length < 2)
                throw new Exception("Too few arguments: must specify fully qualified class name when loading from JAR file");
     MyClassLoaderFromJar mycjar = new MyClassLoaderFromJar(argv[0]);
     klazz=mycjar.findClass(argv[1]);
            argsOffset = argv[0].length() + argv[1].length() + 2;
        }
        else
        {
          

            //klazz = Class.forName(argv[0]);
          try{
                 ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();
                 MyClassLoader classLoader = new MyClassLoader(parentClassLoader);
                
                 klazz = classLoader.loadClass(argv[0]);
                 
                
          } catch (Exception e) {
                 System.out.println("notice cannot load class!!!" + e.getMessage());
         }

            argsOffset = argv[0].length() + 1;
        }
        
        Constructor constructor = klazz.getConstructor();
        Object object = constructor.newInstance();
        Method run = klazz.getMethod("run", String.class, String.class);
        String newArgs = "";
        if (argsOffset < args.length())
            newArgs = args.substring(argsOffset);
        run.invoke(object, sessionUuid, newArgs);
    }
}

MyClassLoader class is a helper class that goes into mod_java/src/org/freeswitch along with Launcher

 package org.freeswitch;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;

class MyClassLoader extends ClassLoader{

        public MyClassLoader(ClassLoader parent) {
            super(parent);
        }

        public Class loadClass(String name) throws ClassNotFoundException {
            System.setSecurityManager(null);

            try {
                System.out.println("in load class");
                String url = "file:/usr/local/freeswitch/scripts/" + name + ".class";
                URL myUrl = new URL(url);
                URLConnection connection = myUrl.openConnection();
                InputStream input = connection.getInputStream();
                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
                int data = input.read();

                while(data != -1){
                    buffer.write(data);
                    data = input.read();
                }

                input.close();

                byte[] classData = buffer.toByteArray();

                Class cl = defineClass(name,
                        classData, 0, classData.length);
                System.out.println("class defined!!!!!!!!!!");
                return cl;

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }
    }

MyClassLoaderFromJar is another helper class to load classes from Jar

 package org.freeswitch;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.util.zip.*;
public final class MyClassLoaderFromJar extends ClassLoader {
    private final ZipFile file;

    public MyClassLoaderFromJar(String filename) throws IOException {
        this.file = new ZipFile(filename);
    }

    @Override
    protected Class findClass(String name) throws ClassNotFoundException {
 System.out.println("in find class");
        ZipEntry entry = this.file.getEntry(name.replace('.', '/') + ".class");
        if (entry == null) {
            throw new ClassNotFoundException(name);
        }
 System.out.println("entry=" + entry);
        try {
            byte[] array = new byte[1024];
            InputStream in = this.file.getInputStream(entry);
            ByteArrayOutputStream out = new ByteArrayOutputStream(array.length);
            int length = in.read(array);
            while (length > 0) {
                out.write(array, 0, length);
                length = in.read(array);
            }
     System.out.println("returning class define");
            return defineClass(name, out.toByteArray(), 0, out.size());
        }
        catch (IOException exception) {
            throw new ClassNotFoundException(name, exception);
        }
    }
}

Put these files mod_java/src/org/freeswitch and do "make mod_java-install". The resulting mod_java.so is copied to /usr/local/freeswitch/mod. Note java.conf.xml sets the classpath for all the jars.


Scroller using Jquery



function scaleImage3(imageSrc, imageId, requiredWidth, requiredHeight) {
    // Create new off screen image to test
    var theImage = new Image();
    theImage.src = imageSrc;
    // Get accurate measurements from that.
    var width = theImage.width;
    var height = theImage.height;
    if ((width > 0) &&
        (height > 0)) {
     var horizontalMultiplier = requiredWidth / width;
     var verticalMultiplier = requiredHeight / height;
     var smallestMultiplier = Math.min(verticalMultiplier, horizontalMultiplier);

     // Get scaled sizes
     width *= smallestMultiplier;
     height *= smallestMultiplier;

     // Apply sizes to image
     $('#'+imageId).attr('width', width );
     $('#'+imageId).attr('height', height );
     $('#'+imageId).attr('src', imageSrc );
     $('#'+imageId).attr('style', {display :"inline"});
     var image_height=height;
     var arr = imageId.split("_");
     
     var accountId = arr[1];
     var originalListItemId = "listItem_" + accountId;
     var divHt=$("#scrollerDiv").css('height');
     divHt = divHt.replace('px', '');
     var top_margin = (divHt - image_height)/2;  
        //and change the margin-top css attribute to center the image
     if (imageId.indexOf("_clean") > -1) {
      var counter = arr[2];
         $("#listItem_" + accountId + "_" + counter + "_clean").css( 'margin-top' , top_margin);
     } else if (imageId.indexOf("_clone") > -1) {
      $("#listItem_" + accountId + "_clone").css( 'margin-top' , top_margin);
     } else {
      $("#listItem_" + accountId).css( 'margin-top' , top_margin);
     }
    }
}

/*
 * simplyScroll 2 - a scroll-tastic jQuery plugin
 *
 * http://logicbox.net/jquery/simplyscroll/
 *
 * Copyright (c) 2009-2012 Will Kelly - http://logicbox.net
 *
 * Dual licensed under the MIT and GPL licenses.
 *
 * Version: 2.0.5 Last revised: 10/05/2012
 *
 */
 
(function($,window,undefined) {

$.fn.simplyScroll = function(options) {
 return this.each(function() {
  new $.simplyScroll(this,options);
 });
};

var defaults = {
 customClass: 'simply-scroll',
 frameRate: 24, //No of movements per second
 speed: 1, //No of pixels per frame
 orientation: 'horizontal', //'horizontal or 'vertical' - not to be confused with device orientation
 auto: true,
 autoMode: 'loop', //auto = true, 'loop' or 'bounce',
 manualMode: 'end', //auto = false, 'loop' or 'end'
 direction: 'forwards', //'forwards' or 'backwards'.
 pauseOnHover: true, //autoMode = loop|bounce only
 pauseOnTouch: true, //" touch device only
 pauseButton: false, //" generates an extra element to allow manual pausing 
 startOnLoad: false, //use this to delay starting of plugin until all page assets have loaded
 //customization
 maxWidth: 650//customization: use this to set the width of the container for horizontal scrolling
};
 
$.simplyScroll = function(el,options) {
 
 var self = this;
 
 this.o = $.extend({}, defaults, options || {});
 this.isAuto = this.o.auto!==false && this.o.autoMode.match(/^loop|bounce$/)!==null;
 this.isHorizontal = this.o.orientation.match(/^horizontal|vertical$/)!==null && this.o.orientation==defaults.orientation; 
 this.isRTL = this.isHorizontal && $("html").attr('dir') == 'rtl';
 this.isForwards = !this.isAuto  || (this.isAuto && this.o.direction.match(/^forwards|backwards$/)!==null && this.o.direction==defaults.direction) && !this.isRTL;
 this.isLoop = this.isAuto && this.o.autoMode == 'loop' || !this.isAuto && this.o.manualMode == 'loop';
 // customization
 this.maxWidth = defaults.maxWidth || 650;
 this.supportsTouch = ('createTouch' in document);
 
 this.events = this.supportsTouch ? 
  {start:'touchstart MozTouchDown',move:'touchmove MozTouchMove',end:'touchend touchcancel MozTouchRelease'} : 
  {start:'mouseenter',end:'mouseleave'};
 
 this.$list = $(el); //called on ul/ol/div etc
 var $items = this.$list.children();
 
 //generate extra markup
 this.$list.addClass('simply-scroll-list')
  .wrap('
') .parent().wrap('
'); if (!this.isAuto) { //button placeholders this.$list.parent().parent() .prepend('
') .prepend('
'); } else { if (this.o.pauseButton) { this.$list.parent().parent() .prepend('
'); this.o.pauseOnHover = false; } } //wrap an extra div around the whole lot if elements scrolled aren't equal if ($items.length > 1) { var extra_wrap = false, total = 0; if (this.isHorizontal) { $items.each(function() { total+=$(this).outerWidth(true); }); extra_wrap = $items.eq(0).outerWidth(true) * $items.length !== total; } else { $items.each(function() { total+=$(this).outerHeight(true); }); extra_wrap = $items.eq(0).outerHeight(true) * $items.length !== total; } if (extra_wrap) { this.$list = this.$list.wrap('
').parent().addClass('simply-scroll-list'); if (this.isHorizontal) { this.$list.children().css({"float":'left',width: total + 'px'}); } else { this.$list.children().css({height: total + 'px'}); } } } if (!this.o.startOnLoad) { this.init(); } else { //wait for load before completing setup $(window).load(function() { self.init(); }); } }; $.simplyScroll.fn = $.simplyScroll.prototype = {}; $.simplyScroll.fn.extend = $.simplyScroll.extend = $.extend; $.simplyScroll.fn.extend({ init: function() { this.$items = this.$list.children(); this.$clip = this.$list.parent(); //this is the element that scrolls this.$container = this.$clip.parent(); this.$btnBack = $('.simply-scroll-back',this.$container); this.$btnForward = $('.simply-scroll-forward',this.$container); if (!this.isHorizontal) { this.itemMax = this.$items.eq(0).outerHeight(true); this.clipMax = this.$clip.height(); this.dimension = 'height'; this.moveBackClass = 'simply-scroll-btn-up'; this.moveForwardClass = 'simply-scroll-btn-down'; this.scrollPos = 'Top'; } else { this.itemMax = this.$items.eq(0).outerWidth(true); this.clipMax = this.$clip.width(); // customization var numClips = Math.round(this.maxWidth/this.clipMax); this.clipMax = numClips * this.clipMax; //if (this.clipMax > this.maxWidth) { //this.maxWidth = this.clipMax; //} this.dimension = 'width'; this.moveBackClass = 'simply-scroll-btn-left'; this.moveForwardClass = 'simply-scroll-btn-right'; this.scrollPos = 'Left'; } this.posMin = 0; this.posMax = this.$items.length * this.itemMax; var addItems = Math.ceil(this.clipMax / this.itemMax); //auto scroll loop & manual scroll bounce or end(to-end) if (this.isAuto && this.o.autoMode=='loop') { this.$list.css(this.dimension,this.posMax+(this.itemMax*addItems) +'px'); this.posMax += (this.clipMax - this.o.speed); if (this.isForwards) { this.resetPosition = 0; //customization //this.$items.slice(0,addItems).clone(false).appendTo(this.$list); var counter=1; var itemsToFix=this.$items.slice(0,addItems).clone(true); counter=1; //assign ids to img elements for the scroller to work in IE9 $(itemsToFix).find('img').attr('id', function(idx, oldId){ var arr = oldId.split("_");var accountId=arr[1]; return "img_" + accountId + "_" + counter++ + "_clean";}); counter =1; //assign ids to li elements for the scroller to work in IE9 $(itemsToFix).each(function() { $(this).attr('id', function(idx, oldId){ var arr = oldId.split("_");var accountId=arr[1]; return "listItem_" + accountId + "_" + counter++ + "_clean";}); }); $(itemsToFix).appendTo(this.$list); this.$list.find("img").each(function() { scaleImage3($(this).attr('src'), $(this).attr('id'), 80, 80); }); } else { this.$items.slice(-addItems).clone(true).prependTo(this.$list); this.resetPosition = this.$items.length * this.itemMax; //due to inconsistent RTL implementation force back to LTR then fake if (this.isRTL) { this.$clip[0].dir = 'ltr'; //based on feedback seems a good idea to force float right this.$items.css('float','right'); } } //manual and loop } else if (!this.isAuto && this.o.manualMode=='loop') { this.posMax += this.itemMax * addItems; this.$list.css(this.dimension,this.posMax+(this.itemMax*addItems) +'px'); this.posMax += (this.clipMax - this.o.speed); var items_append = this.$items.slice(0,addItems).clone(true).appendTo(this.$list); var items_prepend = this.$items.slice(-addItems).clone(true).prependTo(this.$list); this.resetPositionForwards = this.resetPosition = addItems * this.itemMax; this.resetPositionBackwards = this.$items.length * this.itemMax; //extra events to force scroll direction change var self = this; this.$btnBack.bind(this.events.start,function() { self.isForwards = false; self.resetPosition = self.resetPositionBackwards; }); this.$btnForward.bind(this.events.start,function() { self.isForwards = true; self.resetPosition = self.resetPositionForwards; }); } else { //(!this.isAuto && this.o.manualMode=='end') this.$list.css(this.dimension,this.posMax +'px'); if (this.isForwards) { this.resetPosition = 0; } else { this.resetPosition = this.$items.length * this.itemMax; //due to inconsistent RTL implementation force back to LTR then fake if (this.isRTL) { this.$clip[0].dir = 'ltr'; //based on feedback seems a good idea to force float right this.$items.css('float','right'); } } } this.resetPos() //ensure scroll position is reset this.interval = null; this.intervalDelay = Math.floor(1000 / this.o.frameRate); if (!(!this.isAuto && this.o.manualMode=='end')) { //loop mode //ensure that speed is divisible by item width. Helps to always make images even not odd widths! while (this.itemMax % this.o.speed !== 0) { this.o.speed--; if (this.o.speed===0) { this.o.speed=1; break; } } } var self = this; this.trigger = null; this.funcMoveBack = function(e) { if (e !== undefined) { e.preventDefault(); } self.trigger = !self.isAuto && self.o.manualMode=='end' ? this : null; if (self.isAuto) { self.isForwards ? self.moveBack() : self.moveForward(); } else { self.moveBack(); } }; this.funcMoveForward = function(e) { if (e !== undefined) { e.preventDefault(); } self.trigger = !self.isAuto && self.o.manualMode=='end' ? this : null; if (self.isAuto) { self.isForwards ? self.moveForward() : self.moveBack(); } else { self.moveForward(); } }; this.funcMovePause = function() { self.movePause(); }; this.funcMoveStop = function() { self.moveStop(); }; this.funcMoveResume = function() { self.moveResume(); }; if (this.isAuto) { this.paused = false; function togglePause() { if (self.paused===false) { self.paused=true; self.funcMovePause(); } else { self.paused=false; self.funcMoveResume(); } return self.paused; }; //disable pauseTouch when links are present if (this.supportsTouch && this.$items.find('a').length) { this.supportsTouch=false; } if (this.isAuto && this.o.pauseOnHover && !this.supportsTouch) { this.$clip.bind(this.events.start,this.funcMovePause).bind(this.events.end,this.funcMoveResume); } else if (this.isAuto && this.o.pauseOnTouch && !this.o.pauseButton && this.supportsTouch) { var touchStartPos, scrollStartPos; this.$clip.bind(this.events.start,function(e) { togglePause(); var touch = e.originalEvent.touches[0]; touchStartPos = self.isHorizontal ? touch.pageX : touch.pageY; scrollStartPos = self.$clip[0]['scroll' + self.scrollPos]; e.stopPropagation(); e.preventDefault(); }).bind(this.events.move,function(e) { e.stopPropagation(); e.preventDefault(); var touch = e.originalEvent.touches[0], endTouchPos = self.isHorizontal ? touch.pageX : touch.pageY, pos = (touchStartPos - endTouchPos) + scrollStartPos; if (pos < 0) pos = 0; else if (pos > self.posMax) pos = self.posMax; self.$clip[0]['scroll' + self.scrollPos] = pos; //force pause self.funcMovePause(); self.paused = true; }); } else { if (this.o.pauseButton) { this.$btnPause = $(".simply-scroll-btn-pause",this.$container) .bind('click',function(e) { e.preventDefault(); togglePause() ? $(this).addClass('active') : $(this).removeClass('active'); }); } } this.funcMoveForward(); } else { this.$btnBack .addClass('simply-scroll-btn' + ' ' + this.moveBackClass) .bind(this.events.start,this.funcMoveBack).bind(this.events.end,this.funcMoveStop); this.$btnForward .addClass('simply-scroll-btn' + ' ' + this.moveForwardClass) .bind(this.events.start,this.funcMoveForward).bind(this.events.end,this.funcMoveStop); if (this.o.manualMode == 'end') { !this.isRTL ? this.$btnBack.addClass('disabled') : this.$btnForward.addClass('disabled'); } } }, moveForward: function() { var self = this; this.movement = 'forward'; if (this.trigger !== null) { this.$btnBack.removeClass('disabled'); } self.interval = setInterval(function() { if (self.$clip[0]['scroll' + self.scrollPos] < (self.posMax-self.clipMax)) { self.$clip[0]['scroll' + self.scrollPos] += self.o.speed; } else if (self.isLoop) { self.resetPos(); } else { self.moveStop(self.movement); } },self.intervalDelay); }, moveBack: function() { var self = this; this.movement = 'back'; if (this.trigger !== null) { this.$btnForward.removeClass('disabled'); } self.interval = setInterval(function() { if (self.$clip[0]['scroll' + self.scrollPos] > self.posMin) { self.$clip[0]['scroll' + self.scrollPos] -= self.o.speed; } else if (self.isLoop) { self.resetPos(); } else { self.moveStop(self.movement); } },self.intervalDelay); }, movePause: function() { clearInterval(this.interval); }, moveStop: function(moveDir) { this.movePause(); if (this.trigger!==null) { if (typeof moveDir !== 'undefined') { $(this.trigger).addClass('disabled'); } this.trigger = null; } if (this.isAuto) { if (this.o.autoMode=='bounce') { moveDir == 'forward' ? this.moveBack() : this.moveForward(); } } }, moveResume: function() { this.movement=='forward' ? this.moveForward() : this.moveBack(); }, resetPos: function() { this.$clip[0]['scroll' + this.scrollPos] = this.resetPosition; } }); })(jQuery,window);

Use it in JSP




<div id="scrollerDiv">
      <ul class="myulclass" id="scroller">
        <s:iterator value="scrollerAccounts">
          <s:if test="profilePic != null && profilePic != ''">
           <li  id="listItem_${accountId}"><a href="host?number=${virtualNumber}"><img id="img_${accountId}" src="profile/${accountId}/${profilePic}" width="80" height="80"></a></li>
          </s:if>
          <s:elseif test="gender.description == \"Female\"">
           <li id="listItem_${accountId}"><a href="host?number=${virtualNumber}"><img id="img_${accountId}" src="img/noImageFemale.png" width="80" height="80"></a></li>
          </s:elseif>
          <s:else>
           <li id="listItem_${accountId}"><a href="host?number=${virtualNumber}"><img id="img_${accountId}" src="img/noImageMale.png" width="80" height="80"></a></li>
          </s:else>
        </s:iterator>
        <!--   called clones to ensure the clip is completely filled before the scrolling starts -->
        <s:iterator value="scrollerAccounts">
          <s:if test="profilePic != null && profilePic != ''">
           <li  id="listItem_${accountId}_clone"><a href="host?number=${virtualNumber}"><img id="img_${accountId}_clone" src="profile/${accountId}/${profilePic}" width="80" height="80"></a></li>
          </s:if>
          <s:elseif test="gender.description == \"Female\"">
           <li id="listItem_${accountId}_clone"><a href="host?number=${virtualNumber}"><img id="img_${accountId}" src="img/noImageFemale.png" width="80" height="80"></a></li>
          </s:elseif>
          <s:else>
           <li id="listItem_${accountId}_clone"><a href="host?number=${virtualNumber}"><img id="img_${accountId}" src="img/noImageMale.png" width="80" height="80"></a></li>
          </s:else>
        </s:iterator>
      </ul>
     </div>

Customizing ENUM in Hibernate


We create the GenericEnumUserType class as follows and use it like this in *.hbm.xml

<property name="responseCode" column="RESPONSE_CODE">
   <type name="net.mycompany.tps.domain.GenericEnumUserType">
    <param name="enumClass">net.mycompany.tps.domain.ExternalResponseCodeEnum</param>
   </type>
  </property>
Here is the net.mycompany.tps.domain.ExternalResponseCodeEnum NOTE the parseId method has to be a static
public enum ExternalResponseCodeEnum {
  ercNotSet(-1),
     ercInvalidCard(101),
     ercOTBDeclined(200),
     ercBlockedCard (210),
     ercBlockedANI(215),
     ercChargeback(220),
     ercBlockedRISK(222),
     ercExceededRiskParameters(230),
     ercCCWDeclined(271),
     ercFirstTimeCaller(280),
     ercSaleDeclined(300),
     ercOTBApproved(400),
     ercCCWTimeoutO(401),
     ercPositiveData(410),
     ercCCWApproved(421),
     ercSaleApproved(500),
     ercCCWTimeoutS(501);
     private int externalResponseCode;

    public static final Map lookupExternalResponseCodeEnum = new HashMap();

    static {
         //Create reverse lookup hash map 
         for(ExternalResponseCodeEnum d : ExternalResponseCodeEnum.values())
             lookupExternalResponseCodeEnum.put(d.getId(), d);
  }
  //constructor
  private ExternalResponseCodeEnum(int code) {
   this.externalResponseCode
   = code;
  }
  public int getId() {
   return externalResponseCode;
  }
  public static int parseId(int id) {
   return "set up the reverse lookup of enum based on id"
  }
}

import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.TypeResolver;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;


public class GenericEnumUserType implements UserType, ParameterizedType {

    private Class  enumClass;

    private Class  identifierType;

    private Method identifierMethod;

    private Method valueOfMethod;

    private static final String defaultIdentifierMethodName = "getId";

    private static final String defaultValueOfMethodName = "parseId";

    private AbstractSingleColumnStandardBasicType type;

    private int[] sqlTypes;

    @Override
    public void setParameterValues(Properties parameters) {
        String enumClassName = parameters.getProperty("enumClass");
        try {
            enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
        } catch (ClassNotFoundException exception) {
            throw new HibernateException("Enum class not found", exception);
        }

        String identifierMethodName =
                parameters.getProperty("identifierMethod",
                        defaultIdentifierMethodName);

        try {
            identifierMethod =
                    enumClass.getMethod(identifierMethodName, new Class[0]);
            identifierType = identifierMethod.getReturnType();
        } catch (Exception exception) {
            throw new HibernateException("Failed to optain identifier method",
                    exception);
        }

        TypeResolver tr = new TypeResolver();
        type =
                (AbstractSingleColumnStandardBasicType) tr.basic(identifierType
                        .getName());
        if (type == null) {
            throw new HibernateException("Unsupported identifier type "
                    + identifierType.getName());
        }
        sqlTypes = new int[] {type.sqlType()};

        String valueOfMethodName = parameters.getProperty("valueOfMethod",
                defaultValueOfMethodName);
        try {
            valueOfMethod = enumClass.getMethod(valueOfMethodName,
                            new Class[] {identifierType});
        } catch (Exception exception) {
            throw new HibernateException("Failed to optain valueOf method",
                    exception);
        }
    }

    @Override
    public Class returnedClass() {
        return enumClass;
    }

    public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
            throws HibernateException, SQLException {
        Object identifier = type.get(rs, names[0], null);
        if (identifier == null) {
            return null;
        }

        if (valueOfMethod == null) {

        }

        try {
            return valueOfMethod.invoke(enumClass, new Object[] {identifier});
        } catch (Exception exception) {
            throw new HibernateException(
                    "Exception while invoking valueOfMethod of enumeration class: ",
                    exception);
        }
    }

    public void nullSafeSet(PreparedStatement st, Object value, int index)
            throws HibernateException, SQLException {
        try {
            Object identifier =
                    value != null ? identifierMethod.invoke(value,
                            new Object[0]) : null;
            st.setObject(index, identifier);
        } catch (Exception exception) {
            throw new HibernateException(
                    "Exception while invoking identifierMethod of enumeration class: ",
                    exception);

        }
    }

    @Override
    public int[] sqlTypes() {
        return sqlTypes;
    }

    @Override
    public Object assemble(Serializable cached, Object owner)
            throws HibernateException {
        return cached;
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }

    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }

    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        return x == y;
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    public boolean isMutable() {
        return false;
    }

    public Object replace(Object original, Object target, Object owner)
            throws HibernateException {
        return original;
    }

 @Override
 public Object nullSafeGet(ResultSet arg0, String[] arg1,
   SessionImplementor arg2, Object arg3) throws HibernateException,
   SQLException {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public void nullSafeSet(PreparedStatement arg0, Object arg1, int arg2,
   SessionImplementor arg3) throws HibernateException, SQLException {
  // TODO Auto-generated method stub
  nullSafeSet(arg0, arg1, arg2);
 }
}

Selenium Javascript


Selenium Script for Chrome Driver
package net.mycom.myapp.selenium;

import static org.junit.Assert.assertEquals;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class TestPopcornMultipleFunctionsMobile {
  private static WebDriver driver;

  //private static String baseUrl = "http://localhost:8080/";
  //private static String context="mycommyappWebsite/";
  private static String context="home?mobile=true";
  private static String baseUrl = "http://qa.i.opentalk.com/";
  
  private static String login = "seleniumnewuser";
  private static String password = "welcome";
  private static String changePassword = "welcome2";
  private static String testNumber = "2565137992";
  private static String testTextMsg = "hello there...testing with selenium";
  private static String facebookUserName;
  private static String facebookPassword = "";
        private static int countTestUsers = 1;
  private static String loginAs;
  
  @BeforeClass
  public static void setUp() throws Exception {
            for (int i = 1; i <= countTestUsers; i++) {
                System.setProperty("webdriver.chrome.driver", "C:\\Users\\Chrome\\chromedriver.exe");
                driver = new ChromeDriver();
//                driver = new FirefoxDriver();
             driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
             driver.get(baseUrl + context);
//             driver.get(baseUrl);
             System.out.println(baseUrl);
              assertEquals("Phone call | opentalk | Feed", driver.getTitle());
       driver.findElement(By.xpath("//a[@href='loginPage']")).getAttribute("href");
       driver.findElement(By.xpath("//a[@href='loginPage']")).click();
       login(i);
            }
  }
  @AfterClass
  public static void tearDown() throws Exception {
   driver.navigate().to(driver.findElement(By.xpath("//a[@href='logout']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Login", driver.getTitle());
   driver.quit();
  }
  
  private static void login(int i) {
   loginAs = login + i + "@mycom.net";
   driver.findElement(By.id("emailOrPhone")).clear();
   driver.findElement(By.id("emailOrPhone")).sendKeys(loginAs);
   driver.findElement(By.id("password")).sendKeys(password);
   driver.findElement(By.name("submit")).click();
   assertEquals("Phone call |opentalk | Feed", driver.getTitle());
//   driver.findElement(By.id("menu")).click();
//         sendTextMessage();
        }
  
  //@Test
  public void checkTextHistory() throws Exception {
   driver.findElement(By.linkText("Text History")).click();
//   assertEquals("Text History", driver.getTitle().substring(0,12));
   //driver.findElement(By.xpath("//a[contains(@href,'popupMenu?')]")).click();
   List anchors = driver.findElememycom(By.xpath("//a[contains(@href,'popupMenu?')]"));
   Iterator j = anchors.iterator();
   while(j.hasNext()) {
    WebElement anchor = j.next();
    System.out.println(anchor.getAttribute("href"));
   }
  }
   
  //@Test
  public void sendTextMessage() throws Exception {
   driver.findElement(By.linkText("Call/Text")).click();
   assertEquals("Make Call / Send Text", driver.getTitle().substring(0,21));
   driver.findElement(By.id("sendText_to")).sendKeys(testNumber);
      driver.findElement(By.id("message")).sendKeys(testTextMsg);
   driver.findElement(By.id("sendTextButton")).click();
/*   for (String handle : driver.getWindowHandles()) {
       driver.switchTo().window(handle);
       if (driver.findElement(By.linkText("Send Text")).isDisplayed()) {
        driver.findElement(By.linkText("Send Text")).click();
        break;
       }
   } */
   // Check that we're back to the Text History screen. Don't rely on your variable
   assertEquals("Phone call | open Talk | Text History", driver.getTitle().substring(0,12));
  }
  
  @Test
  public void showHistory() throws Exception {
   driver.findElement(By.id("toggleButton")).click();
         driver.navigate().to(driver.findElement(By.xpath("//a[@href='callHistory']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Call History", driver.getTitle().substring(0,36));
   driver.findElement(By.id("toggleButton")).click();
         driver.navigate().to(driver.findElement(By.xpath("//a[@href='textHistory']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Text History", driver.getTitle().substring(0,36));
   
   driver.findElement(By.id("toggleButton")).click();
         driver.navigate().to(driver.findElement(By.xpath("//a[@href='voicemail']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Voicemail", driver.getTitle().substring(0,33));
   
   driver.findElement(By.id("toggleButton")).click();
         driver.navigate().to(driver.findElement(By.xpath("//a[@href='phoneBookListEntries']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Phonebook", driver.getTitle().substring(0,33));
   
   driver.findElement(By.id("toggleButton")).click();
         driver.navigate().to(driver.findElement(By.xpath("//a[@href='displaySettingsMobile?appActiveTab=tab7']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Review Purchase", driver.getTitle().substring(0,39));
         driver.navigate().to(driver.findElement(By.xpath("//a[@href='recentActiveAgemycomearch']")).getAttribute("href"));
      
   driver.findElement(By.id("toggleButton")).click();
         driver.navigate().to(driver.findElement(By.xpath("//a[@href='displaySettingsMobile?hasResponseAction=false']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Setttings", driver.getTitle().substring(0,33));

        }

  //@Test
  public void showProfile() throws Exception {
   driver.findElement(By.xpath("//a[@href='home']")).click();
   driver.navigate().to(driver.findElement(By.xpath("//a[@href='displaySettings']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Settings", driver.getTitle());
   driver.findElement(By.xpath("//li[@id='tab2Link']")).click(); //profile
   assertEquals("Phone call | open Talk | Settings", driver.getTitle());
   driver.findElement(By.xpath("//li[@id='tab3Link']")).click(); //phone & voicemail
   assertEquals("Phone call | open Talk | Settings", driver.getTitle());
   driver.findElement(By.xpath("//li[@id='tab4Link']")).click(); //time/date
   assertEquals("Phone call | open Talk | Settings", driver.getTitle());
   driver.findElement(By.xpath("//li[@id='tab5Link']")).click(); //privacy
   assertEquals("Phone call | open Talk | Settings", driver.getTitle());
   driver.findElement(By.xpath("//li[@id='tab6Link']")).click(); //profile picture
   assertEquals("Phone call | open Talk | Settings", driver.getTitle());
   driver.findElement(By.xpath("//li[@id='tab7Link']")).click(); //billing
   assertEquals("Phone call | open Talk | Settings", driver.getTitle());
  }

  @Test
  public void changePassword() throws Exception {
   //change password
   driver.findElement(By.id("toggleButton")).click();
         driver.navigate().to(driver.findElement(By.xpath("//a[@href='displaySettingsMobile?hasResponseAction=false']")).getAttribute("href"));
   driver.navigate().to(driver.findElement(By.xpath("//a[@href='changePassword']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Settings", driver.getTitle());
   driver.findElement(By.id("changePasswordConfirm_oldPassword")).sendKeys(password); 
   driver.findElement(By.id("changePasswordConfirm_newPassword")).sendKeys(changePassword); 
   driver.findElement(By.id("changePasswordConfirm_confirmNewPassword")).sendKeys(changePassword); 
   driver.findElement(By.id("blueButton")).click();
   assertEquals("Phone call |opentalk | Feed", driver.getTitle());
   
   //logout
   driver.findElement(By.id("toggleButton")).click();
   driver.navigate().to(driver.findElement(By.xpath("//a[@href='logout']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Login", driver.getTitle());
   
   //logback with new password
         driver.get(baseUrl + context);
   driver.findElement(By.xpath("//a[@href='loginPage']")).getAttribute("href");
   driver.findElement(By.xpath("//a[@href='loginPage']")).click();
   driver.findElement(By.id("emailOrPhone")).clear();
   driver.findElement(By.id("emailOrPhone")).sendKeys(loginAs);
   driver.findElement(By.id("password")).sendKeys(changePassword);
   driver.findElement(By.name("submit")).click();
   
   //revert password
   driver.findElement(By.id("toggleButton")).click();
         driver.navigate().to(driver.findElement(By.xpath("//a[@href='displaySettingsMobile?hasResponseAction=false']")).getAttribute("href"));
   driver.navigate().to(driver.findElement(By.xpath("//a[@href='changePassword']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Settings", driver.getTitle());
   driver.findElement(By.id("changePasswordConfirm_oldPassword")).sendKeys(changePassword); 
   driver.findElement(By.id("changePasswordConfirm_newPassword")).sendKeys(password); 
   driver.findElement(By.id("changePasswordConfirm_confirmNewPassword")).sendKeys(password);
   driver.findElement(By.id("blueButton")).click();   
   assertEquals("Phone call |opentalk | Feed", driver.getTitle());
//         System.out.println(driver.getTitle());
  }

  @Test
  public void forgotPassword() {
   //logback in
   driver.findElement(By.id("toggleButton")).click();
   driver.navigate().to(driver.findElement(By.xpath("//a[@href='logout']")).getAttribute("href"));
   driver.navigate().to(driver.findElement(By.xpath("//a[@href='passwordResetRequestInit']")).getAttribute("href"));
         System.out.println(loginAs);
   driver.findElement(By.name("emailOrPhone")).clear();
   driver.findElement(By.name("emailOrPhone")).sendKeys(loginAs);
   driver.findElement(By.name("Submit")).click();
   //logback in
         driver.get(baseUrl + context);
   driver.findElement(By.xpath("//a[@href='loginPage']")).getAttribute("href");
   driver.findElement(By.xpath("//a[@href='loginPage']")).click();
   driver.findElement(By.id("emailOrPhone")).clear();
   driver.findElement(By.id("emailOrPhone")).sendKeys(loginAs);
   driver.findElement(By.id("password")).sendKeys(password);
   driver.findElement(By.name("submit")).click();
   assertEquals("Phone call |opentalk | Feed", driver.getTitle());
  }

  //@Test
  public void facebookLogin() {
   facebookUserName = loginAs;
   driver.navigate().to(driver.findElement(By.xpath("//a[@href='logout']")).getAttribute("href"));
   assertEquals("opentalk Login", driver.getTitle());
   driver.findElement(By.xpath("//img[@src='img/facebook_signin3.png']")).click();
   for (String handle : driver.getWindowHandles()) {
       driver.switchTo().window(handle);
       if (driver.findElememycom(By.id("email")).size() != 0) {
        driver.findElement(By.id("email")).clear();
        driver.findElement(By.id("email")).sendKeys(facebookUserName);
     driver.findElement(By.id("pass")).sendKeys(facebookPassword);
     driver.findElement(By.name("login")).click();
        break;
       }
   }
   assertEquals("Phone call | open Talk | opentalk Feed", driver.getTitle());
   
   //logout
   driver.navigate().to(driver.findElement(By.xpath("//a[@href='logout']")).getAttribute("href"));
   assertEquals("Phone call | open Talk | Login", driver.getTitle());
   
   //logback in
   driver.findElement(By.id("login_emailOrPhone")).clear();
   driver.findElement(By.id("login_emailOrPhone")).sendKeys(loginAs);
   driver.findElement(By.id("login_password")).sendKeys(password);
   driver.findElement(By.name("Submit")).click();
   assertEquals("Phone call | open Talk | opentalk Feed", driver.getTitle());
   
  }

  //@Test
  public void showPagination() throws Exception {
//   driver.findElement(By.xpath("//a[@href='home']")).click();
   driver.findElement(By.id("toggleButton")).click();
   driver.findElement(By.cssSelector("a > strong")).click();
   assertEquals("Phone call | open Talk | opentalk Feed", driver.getTitle());
  }


}
Firefox Driver
package net.mycom.myapp.selenium;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.concurrent.TimeUnit;

import net.mycom.myapp.domain.Account;
import net.mycom.myapp.domain.AccountPending;
import net.mycom.myapp.domain.dao.AccountDao;
import net.mycom.myapp.domain.dao.AccountDaoImpl;
import net.mycom.myapp.util.HibernateUtil;
import net.mycom.myapp.vn.dao.VirtualNumberDao;
import net.mycom.myapp.vn.dao.VirtualNumberDaoImpl;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.chrome.ChromeDriver;

public class TestmystuffMultipleUser {
 int countTestUsers = 10;
 private static WebDriver driver;

 // private static String baseUrl = "http://localhost:8080/";
 // private static String context = "mycommyappWebsite/";
 private static String context = "";
 //private static String dbUrl = "//mydb/myapp";
 //private static String dbUrl = "//mydb/myapp";
 private static String baseUrl = "http://qa.i.opentalk.com/";
 private static String dbUrl = "//mydbqa.i.mystuff.com/myapp";

 private static String dbLogin = "myapp_web";
 private static String dbPassword = "welcome";
 private static String dbShowSql = "true";
 private static String firstName = "Selenium";
 private static String lastName = "Newuser";
 private static String email = "seleniumNewUser";
 private static String password = "welcome";
 private static String areaCode = "818";
 int terminal = 5555000;
 private static String terminalString = "";

 private static String gender[] = { "Male", "Female" };

 @BeforeClass
 public static void setUp() throws Exception {
  HibernateUtil.setConnectionParameters(dbUrl, dbLogin, dbPassword,dbShowSql);
     System.out.println("Before  FireFox");
        System.setProperty("webdriver.chrome.driver", "C:\\Users\\Chrome\\chromedriver.exe");
        driver = new ChromeDriver();
//  driver = new FirefoxDriver();
  driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
     System.out.println("After  FireFox");
 }

 @AfterClass
 public static void tearDown() throws Exception {
  driver.quit();
 }

 @Test
 public void newUserWithoutVN() throws Exception {
  // loop to check, delete, and create the accoumycom
     System.out.println("Before  Loop");

  for (int i = 0; i < countTestUsers; i++) {

   driver.get(baseUrl + context + "home");
   assertEquals("mystuff Login", driver.getTitle());
   terminal = terminal + i;
   terminalString = areaCode + terminal;
   System.out.println(terminalString);

   Session session = HibernateUtil.getCurremycomession();
   Criteria crit = session.createCriteria(Account.class);
   crit.add(Restrictions.eq("terminatingNumber", terminalString));
   Account ac = (Account) crit.uniqueResult();
   // Delete account if it exists
   if (ac != null) {
    Transaction tran = session.beginTransaction();
    VirtualNumberDao vnDao = new VirtualNumberDaoImpl(null);
    vnDao.deprovision(ac.getAccountId());
    AccountDao accountDao = new AccountDaoImpl();
    accountDao.deleteAccount(ac.getAccountId());
    tran.commit();
   }

   driver.findElement(By.id("signup_firstName")).clear();
   driver.findElement(By.id("signup_firstName")).sendKeys(
     firstName + i);
   driver.findElement(By.id("signup_lastName")).clear();
   driver.findElement(By.id("signup_lastName")).sendKeys(lastName + i);
   driver.findElement(By.id("signup_email")).clear();
   driver.findElement(By.id("signup_email")).sendKeys(
     email + i + "@mycom.net");
   driver.findElement(By.id("signup_email2")).clear();
   driver.findElement(By.id("signup_email2")).sendKeys(
     email + i + "@mycom.net");
   driver.findElement(By.id("signup_password")).clear();
   driver.findElement(By.id("signup_password")).sendKeys(password);
   driver.findElement(By.id("signup_gender")).sendKeys(password);
   Select select = new Select(driver.findElement(By
     .id("signup_gender")));
   // select.deselectAll();
   select.selectByVisibleText(gender[i % 2]);

   driver.findElement(By.xpath("//input[@value='Sign Up']")).click();
   session.close();

   // Reset connection so we can see new inserts
   session = HibernateUtil.getCurremycomession();

   // get from db account pending
   crit = session.createCriteria(AccountPending.class);
   crit.add(Restrictions.eq("email", (email + i + "@mycom.net")));
   crit.addOrder(Order.desc("idAccountPending"));
   crit.setMaxResults(1);
   AccountPending ap = (AccountPending) crit.uniqueResult();
   if (ap == null) {
    fail("could not read account pending");
   }

   // Generate url that the email would send
   String emailCode = ap.getEmailCode();
   driver.navigate().to(
     baseUrl + context + "/emailConfWoVn?id="
       + ap.getIdAccountPending() + "&emailCode="
       + emailCode);

   // terminatingNumber.jsp
   driver.findElement(By.name("areaCode")).sendKeys(areaCode);
   driver.findElement(By.name("teleport")).sendKeys(
     terminalString.substring(3, 6));
   driver.findElement(By.name("terminal")).sendKeys(
     terminalString.substring(6, 10));
   driver.findElement(By.xpath("//input[@value='Continue']")).click();

   // ivrTnVerification.jsp
   driver.findElement(By.xpath("//input[@value='Continue']")).click();

   long accountPendingId = ap.getIdAccountPending();
   session.evict(ap);
   session.close();
   session = HibernateUtil.getCurremycomession();
   ap = (AccountPending) session.get(AccountPending.class,
     accountPendingId);
   Transaction tran = session.beginTransaction();
   ap.setTnCodeVerified(true);
   session.saveOrUpdate(ap);
   tran.commit();

   // ivrTnVerificationConfirm.jsp
   driver.findElement(By.xpath("//input[@value='Continue']")).click();

   // chooseAreaCode.jsp
   driver.findElement(By.xpath("//input[@value='Continue']")).click();

   // chooseVn.jsp
   driver.findElement(By.xpath("//input[@value='Continue']")).click();

   // accountCreated.jsp
   driver.findElement(By.xpath("//input[@value='Go To My Account']"))
     .click();
   driver.navigate().to(
     driver.findElement(By.xpath("//a[@href='logout']"))
       .getAttribute("href"));
   assertEquals("mystuff Login", driver.getTitle());

  }
 }
}

FB Authentication


FB Authentication
•  User clicks on the FB button on home page
•  the user is redirected to https://graph.facebook.com/oauth/authorize with these parameters:

client_id FB App Id
type web_server
display Popup
redirect_uri /myServices/connectToFBCallback
response_type Token
auth_type Reauthenticate
state Test
scope Email

• Note that  is set up in the FB App at developers.facebook.com

• after the user logs successfully into FB, the callback URL (/myServices/connectToFBCallback) is invoked by FB we are interested in the 2 parameters that are passed into the callback URL.

1) code
2) state

•  if code is null or empty, we assume the user is not authorized by FB and send the user to registration

•  state should be same as the one we passed with the  URL https://graph.facebook.com/oauth/authorize 

•  if state is null or empty, we assume the user is not authorized by FB and send the user to  registration

• Note: if the callback URL is never invoked by FB, there is nothing that we can do
 to inform the user about the status of their login

• the next step is to get the access token

•  the URL is https://graph.facebook.com/oauth/access_token

• parameters:

client_id 
code 
type web_server
client_secret 

•  open the URL connection is https://graph.facebook.com/oauth/access_token using HTTPS protocol and read the input. We are interested in the access token that could be read in the input as access_token=xyz...

• Save the access token in the Database

• We then need to get the FB username of the user 

•  open HTTPS URL connection to https://graph.facebook.com/me

• with parameter

 access_token=

•  the response from FB is read into a Gson object 
•  the username and email are parsed and stored in the Gson object
•  we then look up the   Account table using the email of Gson object
1) if the account is found, we log the user in and we are done
2) if the account is not found, we send the user to registration

Logging in FB User

• We redirect the user to myWebsite/loginFB.action with the following parameters:

1) email (ex:abc@abc.com)
2) profilePic (ex: https://graph.facebook.com//picture)

• The loginFB method will store the profile pic in  Account.profile_pic.

• For example: https://graph.facebook.com/gandikotam/picture will  be the value stored in the Account.profile_pic for the FB user with username gandikotam

• To retrieve the image, the ProfilePicController needs to be modified to download the image using HTTPS protocol.

Sample mobile JSP


<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
 <head>
  <title><%= myappProperties.sitePageTitle() %> Action Menu</title>
  <s:head />
  <jsp:include page="/mobile/mobileScriptsAndStyles.jsp"></jsp:include>
  <style type="text/css">
   p img {
    max-width: 100%;
   }
  </style>
  
  <script type="text/javascript" src="js/mobile/scaleImage.js"></script>
  <script type="text/javascript">
   $("div[data-role='page']").live("pageshow", function(event, ui) {
    <s:if test="account.profilePic != null && account.profilePic != ''">
     scaleImage("profile/${account.accountId}/${account.profilePic}", "profilePicture2", 60, 60);
    </s:if>
    <s:elseif test="genderOfPhoneBookEntry == \"F\"">
     scaleImage("img/noImageFemale.png", "profilePicture2", 60, 60);
    </s:elseif>
    <s:else>
     scaleImage("img/noImageMale.png", "profilePicture2", 60, 60);
    </s:else>
   });
  </script>
 </head>

 <body>
  <div data-role="page" data-theme="c">
   <div data-role="content" style="background-color:#FFFFFF;">
    <!-- Menu button -->
    <div id="toggleButton" onclick="toggleMenu();" style="width: 26px; height: 26px; background: url(img/mobile/list.png) 0 0 no-repeat; cursor: pointer; float: left;"></div>
    <!-- Menu overlay -->
    <div id="menuClickOverlay">
     <%@ include file="/mobile/logo.jsp" %><br />
     
     <div data-role="content">
      <%@ include file="/mobile/popupCommon.jsp" %>
      <div id="agentProfile" style="width: 100%; min-width: 0px; line-height:auto; margin-top:0px;">
       ${account.profilePageHtml}
      </div>
     </div>
    </div>
    <!-- /Menu overlay -->
    <!-- Menu -->
    <%@ include file="/mobile/mobileMenu.jsp" %>
    <!-- /Menu -->
   </div>
   
   <jsp:include page="/mobile/navbar.jsp"></jsp:include>
  </div>
 </body>
</html>

mobileScriptsAndStyles.jsp
<%@page import="net.mycom.myapp.misc.myappProperties" %>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="format-detection" content="telephone=yes">

<link rel="apple-touch-icon-precomposed" href="img/mobile/apple-touch-icon.png" />
<link rel="apple-touch-startup-image" href="img/mobile/apple-touch-startup-image.png" />

<link rel="stylesheet" href="css/mobile/jquery.mobile-1.2.0.min.css" />
<link rel="stylesheet" href="css/mobile/jquery.mobile-1.1.0.c_mycom.css" />

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
 $(document).bind("mobileinit", function() {
  $.mobile.ajaxEnabled = false;
  $.mobile.hashListeningEnabled = false;
 });
</script>
<script type="text/javascript" src="js/mobile/jquery.mobile-1.2.0.min.js"></script>

<link href="css/style.css" rel="stylesheet" type="text/css" />
<link href="css/<%= myappProperties.siteTheme() %>.css" rel="stylesheet" type="text/css" />


<style type="text/css">
 /* Menu
  */
 .ui-btn-text,
 .ui-btn input, .ui-btn button,
 .ui-checkbox, .ui-radio,
 .ui-checkbox input, .ui-radio input,
 .ui-checkbox .ui-btn, .ui-radio .ui-btn,
 .ui-select .ui-btn select {
  z-index: 0;
 }
 
 /* Counters on menu */
 .ui-li-count {
  display: none;
 }
 /* /Menu
  */
  /* prevent zooming */
  .ui-select .ui-btn select{font-size: 50px;}
</style>

<jsp:include page="/analytics.jsp" />

Sample Ajax call using Jquery


function getNewAccountsHtml() {
 $.ajax({
     type: 'GET',
     cache: false,
     async: false,
     url: 'getXXX?hours=' + <%= Integer.parseInt(Properties.Hours())%>,
     data: $("#id").serialize(),
     success: function(data) {
      $("#newAccountsHtml").html(data.xyz); //the java method sets html.put("xyz", "value") and struts.xml has the action configured
      $("#newAccountsHtml").css("display", "block");
      $("#newAccountsUpdateTime").html(getCurrentTimestamp());
     },
     error: function(XMLHttpRequest, textStatus, errorThrown) {
         alert("Server Unavailable");
     },
     dataType: "json"
 });
}

Prestruts filter


import java.io.IOException;

import net.mycom.myapp.misc.myappProperties;

import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
import org.apache.struts2.dispatcher.ng.filter.*;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class PreStrutsFilter  implememycom Filter {
 private static Logger logger = Logger.getLogger(PreStrutsFilter.class);
 
 Filter strutsFilter = new StrutsPrepareAndExecuteFilter();
 private String bypassStrutsExp;
 private String bypassStrutsExpMobile;
 private String bypassVaadin;
 private ServletContext ctx;

 @Override
    public void destroy() {
  strutsFilter.destroy();    
    }

 @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
  if(req instanceof HttpServletRequest){
   HttpServletRequest httpReq = (HttpServletRequest)req;
   String uri = httpReq.getRequestURI();
   
   String ctxRoot = this.ctx.getContextPath();
   uri = uri.replace(ctxRoot, "");
   
   if(!uri.matches(bypassStrutsExp) &&
      !uri.matches(bypassStrutsExpMobile) &&
      !uri.matches(bypassVaadin)
      ){
    
    // Browser cache images
    int dot = uri.lastIndexOf(".");
    if ((dot > 0) &&
        (uri.substring(dot).equalsIgnoreCase(".jpg") ||
         uri.substring(dot).equalsIgnoreCase(".jpeg") ||
         uri.substring(dot).equalsIgnoreCase(".gif") ||
         uri.substring(dot).equalsIgnoreCase(".png"))) {
     try {
      ((HttpServletResponse)res).setHeader("Cache-Control", "max-age=" + myappProperties.getCacheControlMaxAge());
     }
     catch (Exception e) {
      ((HttpServletResponse)res).setHeader("Cache-Control", "max-age=120");
      logger.error("Error retrieving cacheControlMaxAge", e);
     }
    }
    
    putMDC(httpReq); // Log user
    strutsFilter.doFilter(req, res, chain);
    MDC.clear(); // Remove from Mapped Diagnostic Context
   }
   else{
    chain.doFilter(req, res);
   }
  }
  else{
   chain.doFilter(req, res);
  }
    }

 @Override
    public void init(FilterConfig cfg) throws ServletException {
  strutsFilter.init(cfg);
  this.bypassStrutsExp = cfg.getInitParameter("struts_bypass_expression");
  this.bypassStrutsExpMobile = cfg.getInitParameter("struts_bypass_expression_mobile");
  this.bypassVaadin = cfg.getInitParameter("struts_bypass_vaadin");
  this.ctx = cfg.getServletContext();
    }
 
 private void putMDC(HttpServletRequest request) {
  Long accountId = (Long)request.getSession().getAttribute("accountId");
  String sessionId = request.getSession().getId();
  
  // If parameter exist put into Mapped Diagnostic Context
  if (accountId != null) { MDC.put("accountId", accountId); }
  if (sessionId != null) { MDC.put("sessionId", sessionId); }
 }
}

Vaadin app


package net.mycom.vaadin;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.mycom.myapp.domain.Account;
import net.mycom.myapp.misc.myappProperties;
import net.mycom.myapp.util.HibernateUtil;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.HttpServletRequestListener;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.RichTextArea;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.CloseEvent;

public class mycomVaadinApplication extends Application implememycom HttpServletRequestListener {
 private static final long serialVersionUID = 1L;
 private static final String ERR_NITEFLIRT = "err_niteflirt";
 private static final String ERR_SCRIPT = "err_script";
 private static final String ERR_NONE = "err_none";
 private static final String ERR_NOACCOUNTID = "err_noAccountId";
 private static final String ERR_MAXSIZE = "err_maxsize";
 private static final String ERR_UNKNOWN = "err_unknown";
 private static ThreadLocal threadLocal = new ThreadLocal();
 public static Logger logger = Logger.getRootLogger();
 private static Integer dbProfilePageHtmlSize;
 Long accountId=0L;
 private transient HttpServletResponse response;
 private transient HttpServletRequest request;
 @Override
 public void init() {
  if (accountId == null || accountId == 0L) {
   try {
    String req = request.getRequestURI();
    response.sendRedirect(req.substring(0, req.indexOf("/VAADIN")) + "/home");
   } catch (IOException io) {
    
   }
   return;
  }
  String req = request.getRequestURL().toString();
  req = req.substring(0, req.indexOf("/VAADIN"));
    
  Window mainWindow = new Window("My Profile " + accountId);
  final RichTextArea ta = new RichTextArea();
  ta.setHeight("500");
  ta.setWidth("800");
  ta.setValue(getTextAreaContent());
  VerticalLayout layout=new VerticalLayout();
  Button saveButton = new Button();
  saveButton.addListener(new ClickListener() { 
   @Override
   public void buttonClick(ClickEvent event) {
    switch(saveTextAreaContent((String)ta.getValue())) {
    case ERR_NONE:
     logger.info("saving rich text area content=" + ta.getValue());
     getMainWindow().showNotification("Content saved");
     break;
    case ERR_SCRIPT:
     getMainWindow().showNotification("Not Saved. Cannot use script or javascript tags");
     break;
    case ERR_NITEFLIRT:
     getMainWindow().showNotification("Not Saved. Cannot use NITEFLIRT");
     break;
    case ERR_MAXSIZE:
     getMainWindow().showNotification("Not Saved. Content size exceeded maximum size. Reduce and try again");
     break;
    case ERR_UNKNOWN:
     getMainWindow().showNotification("Not Saved. Unknown error; please contact system administrator");
     break;
    default:
     getMainWindow().showNotification("Not Saved. No account Id...could not save");
    }
   } 
          });
  saveButton.setStyleName("vaadinButton");
  layout.addComponent(ta);
  layout.addComponent(saveButton);
  mainWindow.addComponent(layout);
  // Close the application if the main window is closed.
  mainWindow.addListener(new Window.CloseListener(){
     @Override
      public void windowClose(CloseEvent e) {
         logger.info("Closing the application");
         close();
      } 
  });
  setMainWindow(mainWindow);
 }
  @Override     
   public void onRequestStart(HttpServletRequest request, HttpServletResponse response) {
   accountId = (Long) request.getSession().getAttribute("accountId");
   this.response = response;
   this.request = request;
      mycomVaadinApplication.setInstance(this);   
   }  
  @Override     
   public void onRequestEnd(HttpServletRequest request, HttpServletResponse response) {
     threadLocal.remove();     
   } 
  // Set the current application instance  
   public static void setInstance(mycomVaadinApplication application) {      
       threadLocal.set(application);   
   }
   // @return the current application instance    
   public static mycomVaadinApplication getInstance() {   
     return threadLocal.get();  
   } 
   
   private String getTextAreaContent() {
     if ((Long)request.getSession().getAttribute("accountId") == null) {
    logger.info("no account id");
    return null;
   }
   logger.info("Retrieving html for accountId=" + (Long)request.getSession().getAttribute("accountId"));
   Session session = HibernateUtil.getCurremycomession();
   Account myAcc = (Account)session.get(Account.class, (Long)request.getSession().getAttribute("accountId"));
   session.close();
   
   return myAcc.getProfilePageHtml() == null ? "" : myAcc.getProfilePageHtml();
   }
   private String saveTextAreaContent(String html) {
     if ((Long)request.getSession().getAttribute("accountId") == null) {
    logger.info("no account id");
    return ERR_NOACCOUNTID;
   }
     try {
      if (!StringUtils.isEmpty(html) && html.length() > getDbProfilePageHtmlSize()) {
       logger.info("profile page too large");
       return ERR_MAXSIZE;
      }
     } catch (Exception e) {
      logger.error("max size property", e);
      return ERR_UNKNOWN;
     }
     String htmlNoWhiteSpaces = StringUtils.deleteWhitespace(html);
     if (htmlNoWhiteSpaces.toLowerCase().indexOf("javascript") > -1 || 
       htmlNoWhiteSpaces.toLowerCase().indexOf(" -1 || 
       htmlNoWhiteSpaces.toLowerCase().indexOf("/script") > -1) {
      logger.info("validation failed; found script tag");
      return ERR_SCRIPT;
     }
     if (htmlNoWhiteSpaces.toLowerCase().indexOf("niteflirt") > -1) {
      logger.info("validation failed; found niteflirt");
      return ERR_NITEFLIRT;
     }
     logger.info("saving -->" + html);
   Session session = HibernateUtil.getCurremycomession();
   Account myAcc = (Account)session.get(Account.class, (Long)request.getSession().getAttribute("accountId"));
   myAcc.setProfilePageHtml(html);
   Transaction tran = session.beginTransaction();
   session.saveOrUpdate(myAcc);
   tran.commit();
   session.close();
   return ERR_NONE;
   }
   public Integer getDbProfilePageHtmlSize () throws Exception {
     if (dbProfilePageHtmlSize == null) {
      dbProfilePageHtmlSize = retrieveDbProfilePageHtmlSize();
     }
      return dbProfilePageHtmlSize;
     
  }
   private synchronized Integer retrieveDbProfilePageHtmlSize()  {
    return 10000;
    /*
     Connection connection = null;
         int size =0;
         ResultSet rs=null;
         Statement st=null;
      try {
          Class.forName( "com.mysql.jdbc.Driver");
          connection = DriverManager.getConnection("jdbc:mysql:" + myappProperties.myappConnectionUrl(), myappProperties.myappUsername(), myappProperties.myappPassword());
          st = connection.createStatement();
          String sql = "select * from ACCOUNT LIMIT 1";
          rs = st.executeQuery(sql);
          ResultSetMetaData metadata = rs.getMetaData();
          int colCount = metadata.getColumnCount();
          for(int i=0; i < colCount; i++) {
           String name = metadata.getColumnName(i + 1);
           size = metadata.getColumnDisplaySize(i+1);
           String type =metadata.getColumnTypeName(i+1); 
           logger.debug("Column name: [" + name + "]; type: [" + type
               + "]; size: [" + size + "]");
           if (!StringUtils.isEmpty(name) && name.trim().equalsIgnoreCase("profile_page_html"))
            return new Integer(size);
          }
      } catch (SQLException e) {
          logger.error("sqlexception ", e);
      } catch (ClassNotFoundException e) {
       logger.error("classnotfoundexception ", e);
      } catch (Exception e) {
       logger.error("exception", e);
      } finally {
       try{
        st.close();
        rs.close();
        connection.close();
       } catch (Exception e) {}
      }
      return new Integer(size);
      */
   }
}

Hibernateutil


import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateUtil {
 private static Logger logger = Logger.getRootLogger();
 
    private static SessionFactory sessionFactory;
    private static ServiceRegistry serviceRegistry;
 public static final String serviceUpdateUserName = "MYDOMAIN-SRVC";
 public static final String webUpdateUserName = "MYDOMAIN-WEB";
 public static final String customerServiceUpdateUserName = "MYDOMAIN-CS";
 public static final String batchUpdateUserName = "MYDOMAIN-BATCH";
 public static final ThreadLocal threadBoundSession = new ThreadLocal();
 
    public static void setConnectionParameters(String connectionUrl, String username, String password, String showSql) {
        logger.info("Hibernate connection: url=" + connectionUrl + " username=" + username);
        
  Configuration config = new Configuration();
  config.configure("hibernate_MYDOMAIN.cfg.xml");
  config.setProperty("hibernate.connection.url","jdbc:mysql:"+connectionUrl);
  config.setProperty("hibernate.connection.username",username);
  config.setProperty("hibernate.connection.password",password);
  config.setProperty("hibernate.show_sql", showSql);
  
  serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();  
  sessionFactory = config.buildSessionFactory(serviceRegistry);
  
        logger.info("Hibernate connection completed");
 }

    public static SessionFactory getSessionFactory() {
     return sessionFactory;
    }
    
    public static Session getCurreMYCOMession(){
     Session session = threadBoundSession.get();
     if(session == null || session.isOpen() == false){
      session = sessionFactory.openSession();
      threadBoundSession.set(session);
     }
     return session;
    }

 public static Session getCurreMYCOMessionIfNotNull() {
  return threadBoundSession.get();
 }
 
 public static void removeCurreMYCOMession(){
  threadBoundSession.remove();
 }

 public static void closeCurreMYCOMession(){
     Session session = threadBoundSession.get();
  if ((session != null) && session.isOpen())
   session.close();
 }
}

hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
 <session-factory>
  <!-- Database connection settings -->
  <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="connection.url">x</property>
  <property name="connection.username">x</property>
  <property name="connection.password">x</property>

  <!-- SQL dialect -->
  <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
  
  <!-- Enable Hibernate's automatic session context management -->
  <property name="current_session_context_class">thread</property>
  
  <!-- Second-level cache http://ehcache.org/documentation/integrations/hibernate -->
  <property name="hibernate.cache.use_second_level_cache">true</property>
  <property name="hibernate.cache.use_query_cache">true</property>
  <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
  <property name="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</property>
  
  
  <!-- Setup C3P0 pooling -->
  <property name="connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
  <property name="hibernate.c3p0.acquire_increment">1</property> <!-- Batched connection creates -->
  <property name="hibernate.c3p0.initialPoolSize">0</property>
  <property name="hibernate.c3p0.min_size">0</property>
  <property name="hibernate.c3p0.max_size">50</property>
  <property name="hibernate.c3p0.timeout">300</property> <!-- seconds a Connection can remain pooled but unused before being discarded -->

  <!-- Echo all executed SQL to stdout -->
  <property name="show_sql">true</property>

  <mapping resource="net/mycom/myapp/domain/SmsType.hbm.xml" />
  
 </session-factory>
</hibernate-configuration>

ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
         updateCheck="false" monitoring="autodetect"
         dynamicConfig="true">
 <!-- timeToIdleSeconds & timeToLiveSeconds are not used if eternal is true --> 
 <defaultCache
  maxElementsInMemory="10000"
        eternal="true"
        overflowToDisk="false"
        diskPersistent="false"
        memoryStoreEvictionPolicy="LRU"/>
 <cache name="net.mycom.myapp.domain.Parameter"
  maxElementsInMemory="200" 
  eternal="true"
  overflowToDisk="false" />    
 <cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
  maxElementsInMemory="3000000" eternal="true" timeToIdleSeconds="0"
  timeToLiveSeconds="0" overflowToDisk="false" />
 <cache name="org.hibernate.cache.internal.StandardQueryCache"
  maxElementsInMemory="3000000" eternal="true" timeToIdleSeconds="0"
  timeToLiveSeconds="0" overflowToDisk="false" />
</ehcache>

ehcache.xsd
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.7">

    <xs:element name="ehcache">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="1" minOccurs="0" ref="diskStore"/>
                <xs:element maxOccurs="1" minOccurs="0" ref="transactionManagerLookup"/>
                <xs:element maxOccurs="1" minOccurs="0" ref="cacheManagerEventListenerFactory"/>
                <xs:element maxOccurs="unbounded" minOccurs="0" ref="cacheManagerPeerProviderFactory"/>
                <xs:element maxOccurs="unbounded" minOccurs="0" ref="cacheManagerPeerListenerFactory"/>
                <xs:element maxOccurs="1" minOccurs="0" ref="terracottaConfig"/>
                <xs:element maxOccurs= "1" minOccurs="0" ref="defaultCache"/>
                <xs:element maxOccurs="unbounded" minOccurs="0" ref="cache"/>
            </xs:sequence>
            <xs:attribute name="name" use="optional"/>
            <xs:attribute default="true" name="updateCheck" type="xs:boolean" use="optional"/>
            <xs:attribute default="autodetect" name="monitoring" type="monitoringType" use="optional"/>
            <xs:attribute default="true" name="dynamicConfig" type="xs:boolean" use="optional"/>
            <xs:attribute default="15" name="defaultTransactionTimeoutInSeconds" type="xs:integer" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalHeap" type="memoryUnitOrPercentage" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalOffHeap" type="memoryUnit" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalDisk" type="memoryUnit" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="diskStore">
        <xs:complexType>
            <xs:attribute name="path" use="optional"/>
        </xs:complexType>
    </xs:element>
     <xs:element name="transactionManagerLookup">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheManagerEventListenerFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheManagerPeerProviderFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheManagerPeerListenerFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="terracottaConfig">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="1" minOccurs="0" name="tc-config">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:any maxOccurs="unbounded" minOccurs="0" processContents="skip"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute default="localhost:9510" name="url" use="optional"/>
            <xs:attribute name="rejoin" type="xs:boolean" use="optional" default="false"/>
        </xs:complexType>
    </xs:element>
    <!-- add clone support for addition of cacheExceptionHandler. Important! -->
    <xs:element name="defaultCache">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheLoaderFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheDecoratorFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="pinning"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="terracotta"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheWriter"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="copyStrategy"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="elementValueComparator"/>
            </xs:sequence>
            <xs:attribute name="diskExpiryThreadIntervalSeconds" type="xs:integer" use="optional"/>
            <xs:attribute name="diskSpoolBufferSizeMB" type="xs:integer" use="optional"/>
            <xs:attribute name="diskPersistent" type="xs:boolean" use="optional"/>
            <xs:attribute name="diskAccessStripes" type="xs:integer" use="optional" default="1"/>
            <xs:attribute name="eternal" type="xs:boolean" use="required"/>
            <xs:attribute name="maxElementsInMemory" type="xs:integer" use="optional"/>
            <xs:attribute name="maxEntriesLocalHeap" type="xs:integer" use="optional"/>
            <xs:attribute name="clearOnFlush" type="xs:boolean" use="optional"/>
            <xs:attribute name="memoryStoreEvictionPolicy" type="xs:string" use="optional"/>
            <xs:attribute name="overflowToDisk" type="xs:boolean" use="required"/>
            <xs:attribute name="timeToIdleSeconds" type="xs:integer" use="optional"/>
            <xs:attribute name="timeToLiveSeconds" type="xs:integer" use="optional"/>
            <xs:attribute name="maxElementsOnDisk" type="xs:integer" use="optional"/>
            <xs:attribute name="maxEntriesLocalDisk" type="xs:integer" use="optional"/>
            <xs:attribute name="transactionalMode" type="transactionalMode" use="optional" default="off"/>
            <xs:attribute name="statistics" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="copyOnRead" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="copyOnWrite" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="cacheLoaderTimeoutMillis" type="xs:integer" use="optional" default="0"/>
            <xs:attribute name="overflowToOffHeap" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="maxMemoryOffHeap" type="xs:string" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cache">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheLoaderFactory"/>
                <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheDecoratorFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="pinning"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="terracotta"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheWriter"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="copyStrategy"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="searchable"/>
                <xs:element minOccurs="0" maxOccurs="1" ref="elementValueComparator"/>
            </xs:sequence>
            <xs:attribute name="diskExpiryThreadIntervalSeconds" type="xs:integer" use="optional"/>
            <xs:attribute name="diskSpoolBufferSizeMB" type="xs:integer" use="optional"/>
            <xs:attribute name="diskPersistent" type="xs:boolean" use="optional"/>
            <xs:attribute name="diskAccessStripes" type="xs:integer" use="optional" default="1"/>
            <xs:attribute name="eternal" type="xs:boolean" use="required"/>
            <xs:attribute name="maxElementsInMemory" type="xs:integer" use="optional"/>
            <xs:attribute name="maxEntriesLocalHeap" type="xs:integer" use="optional"/>
            <xs:attribute name="memoryStoreEvictionPolicy" type="xs:string" use="optional"/>
            <xs:attribute name="clearOnFlush" type="xs:boolean" use="optional"/>
            <xs:attribute name="name" type="xs:string" use="required"/>
            <xs:attribute name="overflowToDisk" type="xs:boolean" use="required"/>
            <xs:attribute name="timeToIdleSeconds" type="xs:integer" use="optional"/>
            <xs:attribute name="timeToLiveSeconds" type="xs:integer" use="optional"/>
            <xs:attribute name="maxElementsOnDisk" type="xs:integer" use="optional"/>
            <xs:attribute name="maxEntriesLocalDisk" type="xs:integer" use="optional"/>
            <xs:attribute name="transactionalMode" type="transactionalMode" use="optional" default="off" />
            <xs:attribute name="statistics" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="copyOnRead" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="copyOnWrite" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="logging" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="cacheLoaderTimeoutMillis" type="xs:integer" use="optional" default="0"/>
            <xs:attribute name="overflowToOffHeap" type="xs:boolean" use="optional" default="false"/>
            <xs:attribute name="maxMemoryOffHeap" type="xs:string" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalHeap" type="memoryUnitOrPercentage" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalOffHeap" type="memoryUnitOrPercentage" use="optional"/>
            <xs:attribute default="0" name="maxBytesLocalDisk" type="memoryUnitOrPercentage" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheEventListenerFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
            <xs:attribute name="listenFor" use="optional" type="notificationScope" default="all"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="bootstrapCacheLoaderFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheExtensionFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheExceptionHandlerFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheLoaderFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="cacheDecoratorFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="searchAttribute">
        <xs:complexType>
            <xs:attribute name="name" use="required" type="xs:string"/>
            <xs:attribute name="expression" type="xs:string"/>
            <xs:attribute name="class" type="xs:string"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="searchable">
      <xs:complexType>
        <xs:sequence>
          <xs:element minOccurs="0" maxOccurs="unbounded" ref="searchAttribute"/>
        </xs:sequence>
        <xs:attribute name="keys" use="optional" type="xs:boolean" default="true"/>
        <xs:attribute name="values" use="optional" type="xs:boolean" default="true"/>
      </xs:complexType>
    </xs:element>

    <xs:element name="pinning">
        <xs:complexType>
            <xs:attribute name="store" use="required" type="pinningStoreType"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="terracotta">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="1" ref="nonstop"/>
            </xs:sequence>
            <xs:attribute name="clustered" use="optional" type="xs:boolean" default="true"/>
            <xs:attribute name="valueMode" use="optional" type="terracottaCacheValueType" default="serialization"/>
            <xs:attribute name="coherentReads" use="optional" type="xs:boolean" default="true"/>
            <xs:attribute name="localKeyCache" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="localKeyCacheSize" use="optional" type="xs:positiveInteger" default="300000"/>
            <xs:attribute name="orphanEviction" use="optional" type="xs:boolean" default="true"/>
            <xs:attribute name="orphanEvictionPeriod" use="optional" type="xs:positiveInteger" default="4"/>
            <xs:attribute name="copyOnRead" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="coherent" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="consistency" use="optional" type="consistencyType" default="eventual"/>
            <xs:attribute name="synchronousWrites" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="storageStrategy" use="optional" type="storageStrategyType" default="DCV2"/>
            <xs:attribute name="concurrency" use="optional" type="xs:nonNegativeInteger" default="0"/>
            <xs:attribute name="localCacheEnabled" use="optional" type="xs:boolean" default="true"/>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="consistencyType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="strong" />
            <xs:enumeration value="eventual" />
        </xs:restriction>
    </xs:simpleType>
    <xs:element name="nonstop">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" maxOccurs="1" ref="timeoutBehavior"/>
            </xs:sequence>
            <xs:attribute name="enabled" use="optional" type="xs:boolean" default="true"/>
            <xs:attribute name="immediateTimeout" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="timeoutMillis" use="optional" type="xs:positiveInteger" default="30000"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="timeoutBehavior">
        <xs:complexType>
            <xs:attribute name="type" use="optional" type="timeoutBehaviorType" default="exception"/>
            <xs:attribute name="properties" use="optional" default=""/>
            <xs:attribute name="propertySeparator" use="optional" default=","/>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="timeoutBehaviorType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="noop" />
            <xs:enumeration value="exception" />
            <xs:enumeration value="localReads" />
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="monitoringType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="autodetect"/>
            <xs:enumeration value="on"/>
            <xs:enumeration value="off"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="pinningStoreType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="localHeap" />
            <xs:enumeration value="localMemory" />
            <xs:enumeration value="inCache" />
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="terracottaCacheValueType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="serialization" />
            <xs:enumeration value="identity" />
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="storageStrategyType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="classic" />
            <xs:enumeration value="DCV2" />
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="transactionalMode">
        <xs:restriction base="xs:string">
            <xs:enumeration value="off"/>
            <xs:enumeration value="xa_strict"/>
            <xs:enumeration value="xa"/>
            <xs:enumeration value="local"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:element name="cacheWriter">
        <xs:complexType>
            <xs:sequence >
                <xs:element minOccurs="0" maxOccurs="1" ref="cacheWriterFactory"/>
            </xs:sequence>
            <xs:attribute name="writeMode" use="optional" type="writeModeType" default="write-through"/>
            <xs:attribute name="notifyListenersOnException" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="minWriteDelay" use="optional" type="xs:nonNegativeInteger" default="1"/>
            <xs:attribute name="maxWriteDelay" use="optional" type="xs:nonNegativeInteger" default="1"/>
            <xs:attribute name="rateLimitPerSecond" use="optional" type="xs:nonNegativeInteger" default="0"/>
            <xs:attribute name="writeCoalescing" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="writeBatching" use="optional" type="xs:boolean" default="false"/>
            <xs:attribute name="writeBatchSize" use="optional" type="xs:positiveInteger" default="1"/>
            <xs:attribute name="retryAttempts" use="optional" type="xs:nonNegativeInteger" default="0"/>
            <xs:attribute name="retryAttemptDelaySeconds" use="optional" type="xs:nonNegativeInteger" default="1"/>
            <xs:attribute name="writeBehindConcurrency" use="optional" type="xs:nonNegativeInteger" default="1"/>
            <xs:attribute name="writeBehindMaxQueueSize" use="optional" type="xs:nonNegativeInteger" default="0"/>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="writeModeType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="write-through" />
            <xs:enumeration value="write-behind" />
        </xs:restriction>
    </xs:simpleType>
    <xs:element name="cacheWriterFactory">
        <xs:complexType>
            <xs:attribute name="class" use="required"/>
            <xs:attribute name="properties" use="optional"/>
            <xs:attribute name="propertySeparator" use="optional"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="copyStrategy">
        <xs:complexType>
            <xs:attribute name="class" use="required" type="xs:string" />
        </xs:complexType>
    </xs:element>

    <xs:element name="elementValueComparator">
        <xs:complexType>
            <xs:attribute name="class" use="required" type="xs:string" />
        </xs:complexType>
    </xs:element>

    <xs:simpleType name="notificationScope">
        <xs:restriction base="xs:string">
            <xs:enumeration value="local"/>
            <xs:enumeration value="remote"/>
            <xs:enumeration value="all"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="memoryUnit">
        <xs:restriction base="xs:token">
            <xs:pattern value="[0-9]+[bBkKmMgG]?"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="memoryUnitOrPercentage">
        <xs:restriction base="xs:token">
            <xs:pattern value="([0-9]+[bBkKmMgG]?|100%|[0-9]{1,2}%)"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

Application Listener
package net.mycom.myapp.application.listener;

import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import net.mycom.myapp.misc.MycomCsProperties;
import net.mycom.myapp.util.HibernateUtil;

@WebListener
public class MycomApplicationListener implements ServletContextListener {
 public static Logger logger;
 private ServletContext ctx;

 public void contextInitialized(ServletContextEvent ctxEv) {
  PropertyConfigurator.configure("/Mycom/customerservice/log4j.properties");
  logger = Logger.getRootLogger();
        this.ctx = ctxEv.getServletContext();
  
        // Setup Mycom database
        try {
         net.mycom.myapp.util.HibernateUtil.setConnectionParameters(MycomCsProperties.MycomConnectionUrl(),
           MycomCsProperties.MycomUsername(),
           MycomCsProperties.MycomPassword(),
           MycomCsProperties.MycomShowSql());
         net.nts.cos.util.HibernateUtil.setConnectionParameters(MycomCsProperties.cosConnectionUrl(),
           MycomCsProperties.cosUsername(),
           MycomCsProperties.cosPassword(), 
           MycomCsProperties.MycomShowSql());
        } catch (Exception e) { logger.error("Failed to setup parameters",e); }
    }

 public void contextDestroyed(ServletContextEvent ctxEv) {
     net.mycom.myapp.util.HibernateUtil.getSessionFactory().close();
     net.mycom.cos.util.HibernateUtil.getSessionFactory().close();
     deregisterJdbcConnections();        
    }
 
 private void deregisterJdbcConnections() {
  // This manually de-registers JDBC driver, which prevents Tomcat 7 from
  // complaining about memory leaks wrto this class
  logger.info("Shutting down JDBC drivers");
  Enumeration drivers = DriverManager.getDrivers();
  while (drivers.hasMoreElements()) {
   Driver driver = drivers.nextElement();
   try {
    DriverManager.deregisterDriver(driver);
    logger.info(String.format("deregistering jdbc driver: %s",
      driver));
   } catch (SQLException e) {
    logger.warn(
      String.format("Error deregistering driver %s", driver),
      e);
   }
  }
 }

}

web.xml
<?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>MyWebsite</display-name>
  <listener>
   <listener-class>net.mycom.myapp.application.listener.MycomApplicationListener</listener-class>
  </listener>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <filter>
    <filter-name>connectionFilter</filter-name>
    <filter-class>net.mycom.myapp.filter.HibernateSessionRequestFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>connectionFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter>
    <filter-name>preStruts2</filter-name>
    <filter-class>net.mycom.myapp.filter.PreStrutsFilter</filter-class>
    <init-param>
     <param-name>struts_bypass_expression</param-name>
     <param-value>^(/img/.*)$</param-value>
    </init-param>
    <init-param>
     <param-name>struts_bypass_expression_mobile</param-name>
     <param-value>^(/css/mobile/images/.*)$</param-value>
    </init-param>
   <init-param>
     <param-name>struts_bypass_vaadin</param-name>
     <param-value>^(/VAADIN/.*)$</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>preStruts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <context-param>
   <description>Vaadin production mode</description>
   <param-name>productionMode</param-name>
   <param-value>true</param-value>
  </context-param>
   <servlet>
  <servlet-name>Vaadin Application</servlet-name>
   <servlet-class>
     com.vaadin.terminal.gwt.server.ApplicationServlet
   </servlet-class>
   <init-param>
      <description>Vaadin application class to start</description>
      <param-name>application</param-name>
      <param-value>
        net.nts.vaadin.NtsVaadinApplication
      </param-value>
  </init-param>
 </servlet>
 
 <servlet-mapping>
 <servlet-name>Vaadin Application</servlet-name>
 <url-pattern>/VAADIN/*</url-pattern>
 </servlet-mapping>

  <distributable/>
    <error-page>
    <error-code>404</error-code>
    <location>/error.html</location>
  </error-page>
    <error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/error.html</location>
  </error-page>
</web-app>