Friday 26 October 2012

Generic adapter for all ListView in android

When using a custom list adapter, you have to do the same work: load row xml, get view by id, map logic data to view, then set adapter for ListView. Some thing like this:
public class CommonAdapter extends BaseAdapter {
 private Context context;
 private List lst;
 int layoutID;

 public CommonAdapter(Context context, List lstData, int layoutID) {
  this.context = context;
  this.lst = lstData;
  this.layoutID = layoutID;
 }

 public static class ViewHolder {
  public TextView Text;
  public TextView SubText;
 }

 public View getView(int position, View convertView, ViewGroup parent) {
  View v = convertView;
  ViewHolder viewHolder;
  if (v == null) {
   LayoutInflater inflater = (LayoutInflater) context
           .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   v = inflater.inflate(layoutID, parent, false);
   viewHolder = new ViewHolder();
   viewHolder.Text = (TextView) v.findViewById(R.id.lstmText);
   viewHolder.SubText = (TextView) v.findViewById(R.id.lstmSub);
   v.setTag(viewHolder);
  } else {
   viewHolder = (ViewHolder) v.getTag();
  }
  viewHolder.Text.setText(lst.get(position).Text);
  viewHolder.SubText.setText(lst.get(position).SubText);

  Static.setiFont(viewHolder.Text);
  Static.setiFont(viewHolder.SubText);
  return v;
 }

 public int getCount() {
  return lst.size();
 }

 public Object getItem(int position) {
  return lst.get(position);
 }

 public long getItemId(int position) {
  return position;
 }
 
 public class CommonAdapterData {
  public int id;
  public String Text;
  public String SubText;
 }

}

For many kinds of list view 's row (difference template), we have to create an suitable adapter.
Now, we have another way which can make your work is easy.
First, we need the interface define the way to build row view.
public interface Adaptable {
 public View buildView(View v, LayoutInflater inflater, ViewGroup parent);
}

Then, we create a Generic adapter to use this interface above. There is no magic.
public class GenericAdapter extends BaseAdapter {
 private LayoutInflater inflater;
 private List items;

 @SuppressWarnings("unchecked")
 public GenericAdapter(List items, Context c) {
  this.items = (List) items;
  inflater = LayoutInflater.from(c);
 }

 @Override
 public int getCount() {  
  return items.size();
 }

 @Override
 public Object getItem(int position) {
  return items.get(position);
 }

 @Override
 public long getItemId(int position) {
  return position;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  return items.get(position).buildView(convertView, inflater, parent); }

}

After that, we create an view holder which holder the control in row view (TextView, ImageView, EditText...) and we will map it with an id by using annotation.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InvokeView {
 int viewId();
}
Assume we have an entity:
public class Mobile {
 public String name;
 public int image;
 
 public Mobile(){}
 
 public Mobile(String name, int image){
  this.name = name;
  this.image = image;
 }
}
Now we create an BaseView abstract class, which can be load row xml layout, map view id to viewhoder by using reflect.
public abstract class BaseView implements Adaptable{
 private static final String TAG = "BaseView";
 protected int layoutId;
 protected T viewHolder;
 protected E entity;
 public BaseView(){
  
 }
 
 public BaseView(E entity, int layoutId){
  this.entity = entity;
  this.layoutId = layoutId;
 }
 protected void invokeView(View v){
  try {
   Field fs[] = viewHolder.getClass().getFields();
   for (Field f : fs) {

      InvokeView a = (InvokeView)
                              f.getAnnotation(InvokeView.class);
      int id = a.viewId();
      Log.d(TAG, "field name: " + f.getName());
      Log.d(TAG, "view id: " + id);
      Log.d(TAG, "class: " + f.getClass());
      f.set(viewHolder, v.findViewById(id));

   }
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }
 
 @SuppressWarnings("unchecked")
 @Override
 public View buildView(View v, LayoutInflater inflater, ViewGroup parent) {
  // load the view
  if (null == v) {
   v = inflater.inflate(layoutId, parent, false);
   // get the view
   invokeView(v);
   v.setTag(viewHolder);
  } else {
   viewHolder = (T) v.getTag();
  }

  // binding logic data to view
  mappingData(viewHolder, entity);

  return v;
 }
 
 protected abstract void mappingData(T viewHolder, E entity);
}
Then we define how to map data from entity to the view through view holder. This is a sub class of BaseView.
public class MobileView extends BaseView {
 public MobileView(Mobile mobile, int layoutId) {
  super(mobile, layoutId);
  this.viewHolder = new MobileViewHolder();
 }

 @Override
 public void mappingData(MobileViewHolder viewHolder, Mobile entity) {
  viewHolder.text.setText(entity.name);
  viewHolder.image.setBackgroundResource(entity.image);
 }

}
Finally, we can use our adapter for list view.
public class ListMobileActivity extends ListActivity {

 private static final int FRUIT_ID = 0;
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  List lst = new ArrayList();
  for(int i = 0; i < 10; i++){
   MobileView mv = new MobileView(new Mobile(String.valueOf(i), R.drawable.android_logo), R.layout.list_mobile);
   lst.add(mv);
  }
  setListAdapter(new GenericAdapter(lst, getApplicationContext()));
 }
}
Also, I give an source code, which can be found here

Sunday 12 August 2012

What You Should Know About MonoTouch

After talking to many people about MonoTouch and Mono for Android I’ve found there are a lot of misconceptions surrounding them. These tools have great potential which could be overlooked if they are not understood. This blog post provides background information you need to decide if you want to dig deeper into MonoTouch or Mono for Android.

What is MonoTouch?

MonoTouch is a software development kit for Mac OS X that enables using the C# programming language and common .NET libraries to create native applications for Apple iPhone, iPad and iPod Touch (iOS) devices. MonoTouch has access to all native iOS APIs and UI elements.
MonoTouch can deploy and run iOS applications on the iPhone simulator, as well as physical hardware. iOS applications created by MonoTouch can be distributed on Apple’s App Store.

What MonoTouch is Not

“MonoTouch brings the C# language and the core of .NET to the iPhone, but does nothing to provide a cross-platform UI experience or for that matter any sort of mobile device cross-platform APIs.” – Miguel de Icaza
MonoTouch and Mono for Android are not multi-platform mobile solutions though they have been used as a component to enable multiplatform solutions.

The Mono Open Source Project

Mono Open Source Project LogoMono is an open source implementation of Microsoft’s .NET Framework. It is based on the ECMA standards for C# and the Common Language Runtime. The Mono project is led by Miguel de Icaza (pronounced like “Meegell they eekaza”), a renowned open source programmer from Mexico. The name Mono comes from the spanish word for Monkey.
The Mono open source project was launched in July, 2001 at Ximian. Novell purchased Ximian in 2003. Mono 1.0 was released in June, 2004. Mono was initially focused on Linux desktop applications but has expanded to supporting a wide range of architectures and operating systems. MonoTouch 1.0 was released in September 2009 and Mono for Android in April 2011.
Attachmate acquired Novell in April 2011. In May 2011, the Mono development team was laid off. Miguel de Icaza created Xamarin to continue development of Mono.
Miguel announced at the MonoSpace conference in July 2011 that Xamarian would focus their efforts on MonoTouch and Mono for Android. Xamarian would lead the Mono open source project but much of the development would be accomplished by the Mono open source community.
I believe Xamarin is in a better position now than when they were as part of Novell. Xamarin can now focus on its flagship products, MonoTouch and Mono for Android.

MonoTouch Compilation

MonoTouch compiles C# code down to a native binary. As MonoTouch evolves it will become increasingly difficult to tell the difference between a binary compiled in Xcode vs MonoTouch.
Apple does not allow implemention of runtime engines on iOS. This means that an application cannot run from memory it has written to. MonoTouch does Ahead of Time (AOT) compilation of C# code. Microsoft has a similar technology called NGen.
Apple restricts others from creating runtime engines on iOS because they want the best quality user experience. Steve Jobs published a statement explaining this in April 2010. The contraints Apple published in April 2010 were targeted at Adobe Flash and were later relaxed to avoid alienating products like MonoTouch. Apple will not hinder MonoTouch because this technology fully enables all features of iOS. Joseph Hill, the COO of Xamarin, gave a great interview covering this topic.
Performance is equivalent between C# code compiled with MonoTouch and Objective C code compiled with Xcode. Performance of an app created in MonoTouch can degrade if frequent calls are made to a native iOS library such as within a loop. This is due to marshaling. MonoTouch adds approximately 4 mg to the file size of an iOS executable (according to Joseph Hill in September, 2011 ).
MonoTouch will only run from within the MonoDevelop IDE running on Mac OS (This is different from Mono for Android which runs on Mac or Windows and can be run from MonoDevelop or an add-in to Visual Studio 2010). Xcode is a prerequisite for MonoTouch though MonoTouch does not use Xcode for compilation. MonoTouch uses the following components of Xcode:
  • iOS simulator
  • Code signing tools
  • Interface Builder
  • Profiler

Interface Builder

Interface Builder is an Xcode tool that creates UI interfaces for iOS and Max OS X. Prior to Xcode 4 it was a separate executable. Starting with Xcode 4, Interface Builder is incorporated into Xcode. Interface Builder stores an interface as a .nib file (short for NeXT Interface Builder) which is a Mac OS X package. A .xib file is a newer XML formatted version of a .nib and is converted to a .nib file at compile time.
As of MonoDevelop 2.8, MonoTouch projects support using Xcode 4 to edit Interface Builder files. Prior to that only the standalone executable version of Interface Builder included with Xcode 3 could be used with MonoTouch.
To use Interface Builder within Xcode 4, MonoDevelop generates a temporary Xcode project containing stub Objective-C classes for the C# classes that are registered with Objective-C, which allows these classes to be accessed from Interface Builder in Xcode. Outlets and actions created in these stub classes using Interface Builder are synchronized back to MonoDevelop.

MonoTouch Limitations

Since MonoTouch cannot implement a runtime engine like the .NET CLR, it cannot implement dynamic features like Reflection. Incidentally GetType() is available in MonoTouch. This works because metadata is preserved during compilation.
I have encountered a few instances where a feature or method from .NET compiled but did not run. I expect these issues to be fewer as time goes on. An example was that the Linq related methodThenBy would compile but not run.

MonoTouch & Mono for Android Viability

The team at Xamarin are effective, quick and very motivated. They deploy updates regularly, sometimes many times in one week. When a minor iOS 4 update was released, the MonoTouch team at Novell released a corresponding update in a day or two. Xamarian appears to be even quicker. MonoTouch support for iOS 5 was released on the day that iOS 5 was released, October 12, 2011.
I understand the Mono community will finish implementing features from the next version of C# many months before Microsoft does (based on the spec). Then they test what Microsoft releases and they retrofit in the same bugs as found in Microsoft’s implementation to stay compatible.
Xamarin is on good terms with Microsoft since the MonoSpace conference I attended in Boston was held at the Boston Microsoft office. Xamarin’s products benefit Microsoft by promoting use of .NET and benefit Apple and Google by making it easier for a pool of .NET developers to target their platforms.
MonoTouch/Mono for Android are not faddish tools that are going to blow over or be crushed by Microsoft, Apple or Google. The Mono project has been around almost as long as .NET. Mono and related tools have a long history and a lot of momentum.
MonoTouch and Mono for Android are impressive but not too good to be true. These tools expose the complete native API to a development environment that uses C# language and supporting .NET libraries. They don’t promise creating an app by dragging and dropping a few shapes and clicking a button. You cannot share environment specific UI code between platforms and you have to understand the UI paradigm and API’s within the target environment. This is still a lot of work!

Why Use MonoTouch & Mono for Android

  • Your developers are more familiar with C#.net than Objective C (for iOS) or Java (for Android).
  • To allow sharing business logic between Windows, Windows Phone, ASP.net, iOS and Android platforms.
  • To enable a C#.NET developer to become productive more quickly on iOS or Android. Much of what they learn about the native API will be transferable to developing with that environment’s default toolset and language should they decide to switch later.
  • You view C# as a more productive language than Objective C.
  • To have a common programming language for mobile development across the leading platforms.

Why not call it MonoDroid?

Mono for Android was originally referred to as “MonoDroid” however, the word “droid” is a registered trademark of Lucasfilm Ltd. I assume Novell did not want to pay license fees for use of this name.

.NET Assemblies Available in MonoTouch

The following .NET assemblies are part of MonoTouch:
  • mscorlib.dll
  • System.dll
  • System.Core.dll
  • System.Json.dll
  • System.Runtime.Serialization.dll
  • System.ServiceModel.dll
  • System.ServiceModel.Web.dll
  • System.Web.Services.dll
  • System.Xml.dll
  • System.Xml.Linq.dll

MonoTouch Requirements

  • A Macintosh Computer running SnowLeopard or Lion
  • Xcode and the iOS SDK (you must be a registered Apple Developer to download Xcode)
  • Mono framework for Mac OS X – Intel Runtime
  • MonoDevelop IDE
  • MonoTouch

MonoTouch Cost

The Mono framework and MonoDevelop are open source and free. MonoTouch and Mono for Android extend the Mono framework to iOS and Android operating systems. These products are not free.
See MonoTouch and Mono for Android pricing here by selecting “Add to Cart” (you will not be obligated to buy anything unless you choose to).
*What are your impressions or experiences with MonoTouch or Mono for Android?

Thursday 12 July 2012

Android: Trusting SSL certificates - Exchange Web Service



Previous post from crazybob doesn't work for me. The problem is I want to authenticate Exchange Web Service from Android.  And the long story has begun.

You will need the following tools:





Use the following command to create keystore:

keytool -importcert -v -trustcacerts -file "YourCerFile.cer" -al

ias parkgroup_restful -keystore "Output.bks" -provider org.bounc

ycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-145.jar

" -storetype BKS -storepass "YourPass"
 It should show some result, then ask (choose yes):

Trust this certificate? [no]: yes
 Then verify if the certificates were imported correctly into the keystore:

keytool -list -keystore  "Output.bks"  -provi

der org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-145.jar" -storetype BKS -storepass "YourPass"
If success, result will be show like this:

Keystore type: BKS

Keystore provider: BC

Your keystore contains 1 entry

parkgroup_restful, Apr 10, 2012, trustedCertEntry,

Certificate fingerprint (MD5): 36:47:88:62:23:1C:F3:52:17:BE:7A:A9:94:56:19:18


Use keystore in your app.

Create custom trust manager

import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import android.util.Log;

/**
 * Manage trust certificate
 *
 * @author ductran
 *
 */
public class CustomTrustManager implements X509TrustManager
{
   
 private static final String TAG = CustomTrustManager.class.getSimpleName();

 static class LocalStoreX509TrustManager implements X509TrustManager
 {

  private X509TrustManager trustManager;

  LocalStoreX509TrustManager(KeyStore localTrustStore)
  {
   try
   {
    TrustManagerFactory tmf = TrustManagerFactory
      .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(localTrustStore);

    trustManager = findX509TrustManager(tmf);
    if (trustManager == null)
    {
     throw new IllegalStateException("Couldn't find X509TrustManager");
    }
   } catch (GeneralSecurityException e)
   {
    throw new RuntimeException(e);
   }

  }

  @Override
  public void checkClientTrusted(X509Certificate[] chain, String authType)
    throws CertificateException
  {
   trustManager.checkClientTrusted(chain, authType);
  }

  @Override
  public void checkServerTrusted(X509Certificate[] chain, String authType)
    throws CertificateException
  {
   trustManager.checkServerTrusted(chain, authType);
  }

  @Override
  public X509Certificate[] getAcceptedIssuers()
  {
   return trustManager.getAcceptedIssuers();
  }
 }

 static X509TrustManager findX509TrustManager(TrustManagerFactory tmf)
 {
  TrustManager tms[] = tmf.getTrustManagers();
  for (int i = 0; i < tms.length; i++)
  {
   if (tms[i] instanceof X509TrustManager)
   {
    return (X509TrustManager) tms[i];
   }
  }

  return null;
 }

 private X509TrustManager defaultTrustManager;
 private X509TrustManager localTrustManager;

 private X509Certificate[] acceptedIssuers;

 public CustomTrustManager(KeyStore localKeyStore)
 {
  try
  {
   TrustManagerFactory tmf = TrustManagerFactory
     .getInstance(TrustManagerFactory.getDefaultAlgorithm());
   tmf.init((KeyStore) null);

   defaultTrustManager = findX509TrustManager(tmf);
   if (defaultTrustManager == null)
   {
    throw new IllegalStateException("Couldn't find X509TrustManager");
   }

   localTrustManager = new LocalStoreX509TrustManager(localKeyStore);

   List<x509certificate> allIssuers = new ArrayList<x509certificate>();
   for (X509Certificate cert : defaultTrustManager.getAcceptedIssuers())
   {
    allIssuers.add(cert);
   }
   for (X509Certificate cert : localTrustManager.getAcceptedIssuers())
   {
    allIssuers.add(cert);
   }
   acceptedIssuers = allIssuers.toArray(new X509Certificate[allIssuers
     .size()]);
  } catch (GeneralSecurityException e)
  {
   throw new RuntimeException(e);
  }

 }

 public void checkClientTrusted(X509Certificate[] chain, String authType)
   throws CertificateException
 {
  try
  {
   Log.d(TAG, "checkServerTrusted() with default trust manager...");
   defaultTrustManager.checkClientTrusted(chain, authType);
  } catch (CertificateException ce)
  {
   Log.d(TAG, "checkServerTrusted() with local trust manager...");
   localTrustManager.checkClientTrusted(chain, authType);
  }
 }

 public void checkServerTrusted(X509Certificate[] chain, String authType)
   throws CertificateException
 {
  try
  {
   Log.d(TAG, "checkServerTrusted() with default trust manager...");
   defaultTrustManager.checkServerTrusted(chain, authType);
  } catch (CertificateException ce)
  {
   Log.d(TAG, "checkServerTrusted() with local trust manager...");
   localTrustManager.checkServerTrusted(chain, authType);
  }
 }

 public X509Certificate[] getAcceptedIssuers()
 {
  return acceptedIssuers;
 }

}

Create MySSLSocketFactory






import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.scheme.LayeredSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

/**
 *  loosely based on org.apache.http.conn.ssl.SSLSocketFactory
 * @author ductran
 *
 */
public class MySSLSocketFactory implements LayeredSocketFactory {

   // private SSLContext sslCtx;
    private SSLSocketFactory socketFactory;
    private X509HostnameVerifier hostnameVerifier;

    public MySSLSocketFactory(SSLContext sslCtx,
            X509HostnameVerifier hostnameVerifier) {
        //this.setSslCtx(sslCtx);
        this.socketFactory = sslCtx.getSocketFactory();
        this.hostnameVerifier = hostnameVerifier;
    }

    @Override
    public Socket connectSocket(Socket sock, String host, int port,
            InetAddress localAddress, int localPort, HttpParams params)
            throws IOException, UnknownHostException, ConnectTimeoutException {
        if (host == null) {
            throw new IllegalArgumentException("Target host may not be null.");
        }
        if (params == null) {
            throw new IllegalArgumentException("Parameters may not be null.");
        }

        SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());

        if ((localAddress != null) || (localPort > 0)) {
            if (localPort < 0)
                localPort = 0;

            InetSocketAddress isa = new InetSocketAddress(localAddress,
                    localPort);
            sslsock.bind(isa);
        }

        int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
        int soTimeout = HttpConnectionParams.getSoTimeout(params);

        InetSocketAddress remoteAddress = new InetSocketAddress(host, port);

        sslsock.connect(remoteAddress, connTimeout);

        sslsock.setSoTimeout(soTimeout);
        try {
            hostnameVerifier.verify(host, sslsock);
        } catch (IOException iox) {
            try {
                sslsock.close();
            } catch (Exception x) {
            }

            throw iox;
        }

        return sslsock;
    }

    @Override
    public Socket createSocket() throws IOException {
        return socketFactory.createSocket();
    }

    @Override
    public boolean isSecure(Socket sock) throws IllegalArgumentException {
        if (sock == null) {
            throw new IllegalArgumentException("Socket may not be null.");
        }

        if (!(sock instanceof SSLSocket)) {
            throw new IllegalArgumentException(
                    "Socket not created by this factory.");
        }

        if (sock.isClosed()) {
            throw new IllegalArgumentException("Socket is closed.");
        }
        return true;

    }
    @Override
    public Socket createSocket(Socket socket, String host, int port,
            boolean autoClose) throws IOException, UnknownHostException {
        SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(socket,
                host, port, autoClose);
        hostnameVerifier.verify(host, sslSocket);

        return sslSocket;
    }
}
And make request with HttpsClient:


public class HttpsClient
{
    private static final String KEYSTORE_PASSWORD = "1234567";
    private static final int MAX_CONN_PER_ROUTE = 30;
    private static final int MAX_CONNECTIONS = 30;
    private static final int TIMEOUT = 10 * 1000;
    private static DefaultHttpClient theClient = null;
    private HttpResponse  response = null;
    private static DefaultHttpClient getHttpClient() throws GeneralSecurityException{
  if (theClient == null)
  {
   SSLContext sslContext = createSslContext();
   MySSLSocketFactory socketFactory = new MySSLSocketFactory(sslContext,
     new BrowserCompatHostnameVerifier());
   theClient = createDefaultHttpClient(socketFactory);
  }
  return theClient;
 }

  public HttpResponse  getResponse(){
    return response;
 }

  /**
  * Excute the request
  */
  public void excuteRequest(String url, String username, String password, String requestBody){
  DefaultHttpClient client = getHttpClient();
  HttpPost httpPost = new HttpPost(url);
  httpPost.setHeader("Content-type", "text/xml; charset=utf-8");
  httpPost.setHeader("Keep-Alive", "300");
  httpPost.setHeader("Connection", "Keep-Alive");
  StringEntity se = new StringEntity(requestBody, "UTF-8");
  httpPost.setEntity(se);
  se.setContentType("text/xml");
  se.setContentEncoding("gzip,deflate");
  // Authentication
  client.addRequestInterceptor(preemptiveAuth, 0);
  // Set the proxy
  ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(
    client.getConnectionManager().getSchemeRegistry(),
    ProxySelector.getDefault());
  client.setRoutePlanner(routePlanner);

  List<string> authPrefs = new ArrayList<string>();
  authPrefs.add(AuthPolicy.DIGEST);
  authPrefs.add(AuthPolicy.BASIC);
  authPrefs.add(AuthPolicy.NTLM);
  client.getParams().setParameter(HTTP_AUTH_SCHEME_PRIORITY, authPrefs);
             
                // Basic authentication
  httpPost.addHeader(
    "Authorization",
    "Basic "
      + Base64.encodeToString(
        (username() + ":" + password())
          .getBytes(), Base64.NO_WRAP));
  BasicHttpContext localContext = new BasicHttpContext();
  BasicScheme basicAuth = new BasicScheme();
  localContext.setAttribute("preemptive-auth", basicAuth);
  response = client.execute(httpPost, localContext);
           
     }

  /**
  * Authentication with preemptive
  */
 HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor()
 {
  public void process(final HttpRequest request, final HttpContext context)
    throws HttpException, IOException
  {
   AuthState authState = (AuthState) context
     .getAttribute(ClientContext.TARGET_AUTH_STATE);
   CredentialsProvider credsProvider = (CredentialsProvider) context
     .getAttribute(ClientContext.CREDS_PROVIDER);
   HttpHost targetHost = (HttpHost) context
     .getAttribute(ExecutionContext.HTTP_TARGET_HOST);

   if (authState.getAuthScheme() == null)
   {
    AuthScope authScope = new AuthScope(targetHost.getHostName(),
      targetHost.getPort());
    Credentials creds = credsProvider.getCredentials(authScope);
    if (creds != null)
    {
     authState.setAuthScheme(new BasicScheme());
     authState.setCredentials(creds);
    }
   }
  }
 };

          private static DefaultHttpClient createDefaultHttpClient(
   SocketFactory socketFactory)
 {
  HttpParams params = new BasicHttpParams();
  HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
  // HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
  HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
  // Set the parameters for timeout, max connection
  HttpConnectionParams.setConnectionTimeout(params, TIMEOUT);
  ConnPerRoute connPerRoute = new ConnPerRouteBean(MAX_CONN_PER_ROUTE);
  ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute);
  ConnManagerParams.setMaxTotalConnections(params, MAX_CONNECTIONS);

  // Register the scheme for Http and Https
  SchemeRegistry schemeRegistry = new SchemeRegistry();
  schemeRegistry.register(new Scheme("http", PlainSocketFactory
    .getSocketFactory(), 80));
  SocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
  if (socketFactory != null)
  {
   sslSocketFactory = socketFactory;
  }
  schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
  ClientConnectionManager cm = new ThreadSafeClientConnManager(params,
    schemeRegistry);
  return new DefaultHttpClient(cm, params);
 }


        /**
  * Create SSL Context from X509TrustManager
  *
  * @param clientAuth
  * @return
  * @throws GeneralSecurityException
  */
 private static SSLContext createSslContext() throws GeneralSecurityException
 {
  KeyStore trustStore = loadTrustStore();
  KeyStore keyStore = loadKeyStore();

  // CustomTrustManager myTrustManager = new CustomTrustManager(trustStore);
  EwsX509TrustManager myTrustManager = new EwsX509TrustManager(trustStore,
    null);
  TrustManager[] tms = new TrustManager[]
  { myTrustManager };

  KeyManager[] kms = null;
  KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
    .getDefaultAlgorithm());
  kmf.init(keyStore, KEYSTORE_PASSWORD.toCharArray());
  kms = kmf.getKeyManagers();

  SSLContext context = SSLContext.getInstance("TLS");
  context.init(kms, tms, null);

  return context;
 }
}