diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/AndroidAnnotationProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/AndroidAnnotationProcessor.java
index 3f43bc20fa..6c39f1da1f 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/AndroidAnnotationProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/AndroidAnnotationProcessor.java
@@ -54,6 +54,7 @@
import com.googlecode.androidannotations.annotations.FragmentByTag;
import com.googlecode.androidannotations.annotations.FromHtml;
import com.googlecode.androidannotations.annotations.Fullscreen;
+import com.googlecode.androidannotations.annotations.HttpsClient;
import com.googlecode.androidannotations.annotations.InstanceState;
import com.googlecode.androidannotations.annotations.ItemClick;
import com.googlecode.androidannotations.annotations.ItemLongClick;
@@ -132,6 +133,7 @@
import com.googlecode.androidannotations.processing.FragmentByTagProcessor;
import com.googlecode.androidannotations.processing.FromHtmlProcessor;
import com.googlecode.androidannotations.processing.FullscreenProcessor;
+import com.googlecode.androidannotations.processing.HttpsClientProcessor;
import com.googlecode.androidannotations.processing.InstanceStateProcessor;
import com.googlecode.androidannotations.processing.ItemClickProcessor;
import com.googlecode.androidannotations.processing.ItemLongClickProcessor;
@@ -188,6 +190,7 @@
import com.googlecode.androidannotations.validation.FragmentByTagValidator;
import com.googlecode.androidannotations.validation.FromHtmlValidator;
import com.googlecode.androidannotations.validation.FullscreenValidator;
+import com.googlecode.androidannotations.validation.HttpsClientValidator;
import com.googlecode.androidannotations.validation.InstanceStateValidator;
import com.googlecode.androidannotations.validation.ItemClickValidator;
import com.googlecode.androidannotations.validation.ItemLongClickValidator;
@@ -288,7 +291,8 @@
FragmentByTag.class, //
BeforeTextChange.class, //
TextChange.class, //
- AfterTextChange.class //
+ AfterTextChange.class, //
+ HttpsClient.class //
})
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class AndroidAnnotationProcessor extends AnnotatedAbstractProcessor {
@@ -456,6 +460,7 @@ private ModelValidator buildModelValidator(IRClass rClass, AndroidSystemServices
modelValidator.register(new BeforeTextChangeValidator(processingEnv, rClass));
modelValidator.register(new TextChangeValidator(processingEnv, rClass));
modelValidator.register(new AfterTextChangeValidator(processingEnv, rClass));
+ modelValidator.register(new HttpsClientValidator(processingEnv, rClass));
return modelValidator;
}
@@ -533,6 +538,7 @@ private ModelProcessor buildModelProcessor(IRClass rClass, AndroidSystemServices
modelProcessor.register(new TextChangeProcessor(processingEnv, rClass));
modelProcessor.register(new BeforeTextChangeProcessor(processingEnv, rClass));
modelProcessor.register(new AfterTextChangeProcessor(processingEnv, rClass));
+ modelProcessor.register(new HttpsClientProcessor(rClass));
return modelProcessor;
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/annotations/HttpsClient.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/annotations/HttpsClient.java
new file mode 100644
index 0000000000..a8736bce5d
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/annotations/HttpsClient.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2010-2011 eBusiness Information, Excilys Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed To in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.googlecode.androidannotations.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Use this annotation to get an HttpClient instance with the specified KeyStore
+ * and TrustStore configured to perform an HTTPS request
+ *
+ *
+ * All the parameters are optional
+ *
+ *
+ * trustStore: int, Resource id of your trust store file ex
+ * R.raw.cacerts.bks Typically your servers trusted certificates
+ * (public key, Root Chain Authority etc)
+ *
+ *
+ * trustStorePwd: String, Your trust store password (default is
+ * changeit)
+ *
+ *
+ * keyStore: int, Resource id of your keystore Usually your private key
+ * (client certificate)
+ *
+ *
+ * keyStorePwd: String, Your KeyStore password (default is
+ * changeit)
+ *
+ *
+ * allowAllHostnames: boolean, if true, authorizes any TLS/SSL hostname
+ * (default true) If false, Hostname in certificate (DN) must match
+ * the URL.
+ *
+ *
+ * Note:
+ * Prior to ICS, Android accepts [Key|Trust]store only in BKS format
+ * (Bouncycastle Key Store)
+ *
+ * @author Nabil Hachicha
+ */
+@Retention(RetentionPolicy.SOURCE)
+@Target(ElementType.FIELD)
+public @interface HttpsClient {
+ public static final String DEFAULT_PASSWD = "changeit";
+
+ int trustStore() default Id.DEFAULT_VALUE;
+
+ String trustStorePwd() default DEFAULT_PASSWD;
+
+ int keyStore() default Id.DEFAULT_VALUE;
+
+ String keyStorePwd() default DEFAULT_PASSWD;
+
+ boolean allowAllHostnames() default true;
+}
\ No newline at end of file
diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/CanonicalNameConstants.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/CanonicalNameConstants.java
index 041524a68c..9c095ce393 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/CanonicalNameConstants.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/CanonicalNameConstants.java
@@ -22,7 +22,7 @@
public final class CanonicalNameConstants {
/*
- * Java classes
+ * Java
*/
public static final String URI = URI.class.getCanonicalName();
public static final String SET = Set.class.getCanonicalName();
@@ -31,7 +31,7 @@ public final class CanonicalNameConstants {
public static final String CHAR_SEQUENCE = CharSequence.class.getCanonicalName();
/*
- * Android classes
+ * Android
*/
public static final String LOG = "android.util.Log";
public static final String PARCELABLE = "android.os.Parcelable";
@@ -74,16 +74,17 @@ public final class CanonicalNameConstants {
public static final String BROADCAST_RECEIVER = "android.content.BroadcastReceiver";
public static final String CONTENT_PROVIDER = "android.content.ContentProvider";
public static final String SQLITE_DATABASE = "android.database.sqlite.SQLiteDatabase";
+ public static final String KEY_STORE = "java.security.KeyStore";
/*
- * Sherlock classes
+ * Sherlock
*/
public static final String SHERLOCK_MENU = "com.actionbarsherlock.view.Menu";
public static final String SHERLOCK_MENU_ITEM = "com.actionbarsherlock.view.MenuItem";
public static final String SHERLOCK_MENU_INFLATER = "com.actionbarsherlock.view.MenuInflater";
/*
- * SpringFramework classes
+ * SpringFramework
*/
public static final String RESPONSE_ENTITY = "org.springframework.http.ResponseEntity";
public static final String HTTP_HEADERS = "org.springframework.http.HttpHeaders";
@@ -113,6 +114,16 @@ public final class CanonicalNameConstants {
public static final String ON_CONTENT_VIEW_AVAILABLE_EVENT = "roboguice.activity.event.OnContentViewAvailableEvent";
public static final String ON_CREATE_EVENT = "roboguice.activity.event.OnCreateEvent";
+ /*
+ * HttpClient
+ */
+ public static final String CLIENT_CONNECTION_MANAGER = "org.apache.http.conn.ClientConnectionManager";
+ public static final String DEFAULT_HTTP_CLIENT = "org.apache.http.impl.client.DefaultHttpClient";
+ public static final String SSL_SOCKET_FACTORY = "org.apache.http.conn.ssl.SSLSocketFactory";
+ public static final String SCHEME = "org.apache.http.conn.scheme.Scheme";
+ public static final String SCHEME_REGISTRY = "org.apache.http.conn.scheme.SchemeRegistry";
+ public static final String SINGLE_CLIENT_CONN_MANAGER = "org.apache.http.impl.conn.SingleClientConnManager";
+
private CanonicalNameConstants() {
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/IdValidatorHelper.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/IdValidatorHelper.java
index 8b60e792f4..b48b7cde8d 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/IdValidatorHelper.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/IdValidatorHelper.java
@@ -49,6 +49,13 @@ public void idExists(Element element, Res res, boolean defaultUseName, boolean a
idExists(element, res, defaultUseName, allowDefault, valid, idValue);
}
+ public void idExists(Element element, Res res, boolean defaultUseName, boolean allowDefault, IsValid valid, String methodName) {
+
+ Integer idValue = annotationHelper.extractAnnotationValue(element, methodName);
+
+ idExists(element, res, defaultUseName, allowDefault, valid, idValue);
+ }
+
public void idsExists(Element element, Res res, IsValid valid) {
int[] idsValues = annotationHelper.extractAnnotationValue(element);
diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/TargetAnnotationHelper.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/TargetAnnotationHelper.java
index e01422f5a3..89fe3ec393 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/TargetAnnotationHelper.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/helper/TargetAnnotationHelper.java
@@ -35,13 +35,17 @@ public TargetAnnotationHelper(ProcessingEnvironment processingEnv, Class exten
this.target = target;
}
- @SuppressWarnings("unchecked")
public T extractAnnotationValue(Element element) {
+ return extractAnnotationValue(element, "value");
+ }
+
+ @SuppressWarnings("unchecked")
+ public T extractAnnotationValue(Element element, String methodName) {
Annotation annotation = element.getAnnotation(target);
Method method;
try {
- method = annotation.getClass().getMethod("value");
+ method = annotation.getClass().getMethod(methodName);
return (T) method.invoke(annotation);
} catch (Exception e) {
throw new RuntimeException(e);
diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/ClickProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/ClickProcessor.java
index 42332dfac4..ecaa46d319 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/ClickProcessor.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/ClickProcessor.java
@@ -34,7 +34,6 @@
import com.sun.codemodel.JBlock;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
-import com.sun.codemodel.JExpr;
import com.sun.codemodel.JExpression;
import com.sun.codemodel.JFieldRef;
import com.sun.codemodel.JInvocation;
diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/EBeansHolder.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/EBeansHolder.java
index 57762b20c9..7f6ebdf7e9 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/EBeansHolder.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/EBeansHolder.java
@@ -15,6 +15,8 @@
*/
package com.googlecode.androidannotations.processing;
+import java.io.FileInputStream;
+import java.io.InputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
@@ -30,17 +32,20 @@ public class EBeansHolder {
public class Classes {
/*
- * Java classes
+ * Java
*/
public final JClass RUNTIME_EXCEPTION = refClass(RuntimeException.class);
+ public final JClass EXCEPTION = refClass(Exception.class);
public final JClass CHAR_SEQUENCE = refClass(CharSequence.class);
public final JClass CLASS_CAST_EXCEPTION = refClass(ClassCastException.class);
public final JClass SERIALIZABLE = refClass(Serializable.class);
public final JClass STRING = refClass(String.class);
public final JClass SYSTEM = refClass(System.class);
+ public final JClass INPUT_STREAM = refClass(InputStream.class);
+ public final JClass FILE_INPUT_STREAM = refClass(FileInputStream.class);
/*
- * Android classes
+ * Android
*/
public final JClass LOG = refClass(CanonicalNameConstants.LOG);
public final JClass BUNDLE = refClass(CanonicalNameConstants.BUNDLE);
@@ -76,9 +81,10 @@ public class Classes {
public final JClass MOTION_EVENT = refClass(CanonicalNameConstants.MOTION_EVENT);
public final JClass ON_TOUCH_LISTENER = refClass(CanonicalNameConstants.ON_TOUCH_LISTENER);
public final JClass HANDLER = refClass(CanonicalNameConstants.HANDLER);
+ public final JClass KEY_STORE = refClass(CanonicalNameConstants.KEY_STORE);
/*
- * Sherlock classes
+ * Sherlock
*/
public final JClass SHERLOCK_MENU = refClass(CanonicalNameConstants.SHERLOCK_MENU);
public final JClass SHERLOCK_MENU_ITEM = refClass(CanonicalNameConstants.SHERLOCK_MENU_ITEM);
@@ -105,6 +111,16 @@ public class Classes {
public final JClass ON_CONTENT_VIEW_AVAILABLE_EVENT = refClass(CanonicalNameConstants.ON_CONTENT_VIEW_AVAILABLE_EVENT);
public final JClass ON_CREATE_EVENT = refClass(CanonicalNameConstants.ON_CREATE_EVENT);
+ /*
+ * HttpClient
+ */
+ public final JClass CLIENT_CONNECTION_MANAGER = refClass(CanonicalNameConstants.CLIENT_CONNECTION_MANAGER);
+ public final JClass DEFAULT_HTTP_CLIENT = refClass(CanonicalNameConstants.DEFAULT_HTTP_CLIENT);
+ public final JClass SSL_SOCKET_FACTORY = refClass(CanonicalNameConstants.SSL_SOCKET_FACTORY);
+ public final JClass SCHEME = refClass(CanonicalNameConstants.SCHEME);
+ public final JClass SCHEME_REGISTRY = refClass(CanonicalNameConstants.SCHEME_REGISTRY);
+ public final JClass SINGLE_CLIENT_CONN_MANAGER = refClass(CanonicalNameConstants.SINGLE_CLIENT_CONN_MANAGER);
+
}
private final Map EBeanHolders = new HashMap();
diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/HttpsClientProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/HttpsClientProcessor.java
new file mode 100644
index 0000000000..7bc4b3ffd5
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/processing/HttpsClientProcessor.java
@@ -0,0 +1,191 @@
+/**
+ * Copyright (C) 2010-2011 eBusiness Information, Excilys Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed To in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Nabil Hachicha
+ */
+package com.googlecode.androidannotations.processing;
+
+import static com.sun.codemodel.JExpr._new;
+import static com.sun.codemodel.JExpr._null;
+import static com.sun.codemodel.JExpr._super;
+import static com.sun.codemodel.JExpr.cast;
+import static com.sun.codemodel.JExpr.invoke;
+import static com.sun.codemodel.JExpr.lit;
+import static com.sun.codemodel.JExpr.ref;
+
+import java.lang.annotation.Annotation;
+
+import javax.lang.model.element.Element;
+
+import com.googlecode.androidannotations.annotations.HttpsClient;
+import com.googlecode.androidannotations.annotations.Id;
+import com.googlecode.androidannotations.processing.EBeansHolder.Classes;
+import com.googlecode.androidannotations.rclass.IRClass;
+import com.googlecode.androidannotations.rclass.IRClass.Res;
+import com.googlecode.androidannotations.rclass.IRInnerClass;
+import com.sun.codemodel.JBlock;
+import com.sun.codemodel.JCatchBlock;
+import com.sun.codemodel.JCodeModel;
+import com.sun.codemodel.JDefinedClass;
+import com.sun.codemodel.JExpression;
+import com.sun.codemodel.JFieldRef;
+import com.sun.codemodel.JInvocation;
+import com.sun.codemodel.JMethod;
+import com.sun.codemodel.JMod;
+import com.sun.codemodel.JTryBlock;
+import com.sun.codemodel.JVar;
+
+public class HttpsClientProcessor implements ElementProcessor {
+
+ private final IRClass rClass;
+
+ public HttpsClientProcessor(IRClass rClass) {
+ this.rClass = rClass;
+ }
+
+ @Override
+ public Class extends Annotation> getTarget() {
+ return HttpsClient.class;
+ }
+
+ @Override
+ public void process(Element element, JCodeModel codeModel, EBeansHolder eBeansHolder) {
+ EBeanHolder holder = eBeansHolder.getEnclosingEBeanHolder(element);
+
+ HttpsClient annotation = element.getAnnotation(HttpsClient.class);
+ int trustStoreRawId = annotation.trustStore();
+ String trustStorePwd = annotation.trustStorePwd();
+
+ int keyStoreRawId = annotation.keyStore();
+ String keyStorePwd = annotation.keyStorePwd();
+
+ boolean allowAllHostnames = annotation.allowAllHostnames();
+
+ boolean useCustomTrustStore = Id.DEFAULT_VALUE != trustStoreRawId ? true : false;
+ boolean useCustomKeyStore = Id.DEFAULT_VALUE != keyStoreRawId ? true : false;
+
+ String fieldName = element.getSimpleName().toString();
+ JBlock methodBody = holder.init.body();
+
+ Classes classes = holder.classes();
+
+ JDefinedClass jAnonClass = codeModel.anonymousClass(classes.DEFAULT_HTTP_CLIENT);
+
+ JMethod method = jAnonClass.method(JMod.PROTECTED, classes.CLIENT_CONNECTION_MANAGER, "createClientConnectionManager");
+ method.annotate(Override.class);
+
+ JTryBlock jTryBlock = method.body()._try();
+ JVar jVarTrusted = null;
+ JVar jVarKeystore = null;
+
+ if (useCustomKeyStore) {
+ jVarKeystore = jTryBlock.body().decl(classes.KEY_STORE, "keystore");
+ jVarKeystore.init(classes.KEY_STORE.staticInvoke("getInstance").arg("BKS"));
+ }
+
+ if (useCustomTrustStore || !useCustomTrustStore && useCustomKeyStore) {
+ /*
+ * use default trust store
+ */
+ jVarTrusted = jTryBlock.body().decl(classes.KEY_STORE, "trusted");
+ jVarTrusted.init(classes.KEY_STORE.staticInvoke("getInstance").arg("BKS"));
+
+ }
+
+ JVar jVarRes = null;
+ JVar jVarTrstFile = null;
+ JVar jVarKeyFile = null;
+
+ if (useCustomKeyStore || useCustomTrustStore) {
+ jVarRes = jTryBlock.body().decl(classes.RESOURCES, "res", invoke("getResources"));
+ }
+
+ IRInnerClass rInnerClass = rClass.get(Res.RAW);
+ if (useCustomKeyStore) {
+ JFieldRef rawIdRef = rInnerClass.getIdStaticRef(keyStoreRawId, holder);
+ JInvocation jInvRawKey = jVarRes.invoke("openRawResource").arg(rawIdRef);
+ jVarKeyFile = jTryBlock.body().decl(classes.INPUT_STREAM, "inKeystore", jInvRawKey);
+ }
+
+ if (useCustomTrustStore) {
+ JFieldRef rawIdRef = rInnerClass.getIdStaticRef(trustStoreRawId, holder);
+ JInvocation jInvRawTrust = jVarRes.invoke("openRawResource").arg(rawIdRef);
+ jVarTrstFile = jTryBlock.body().decl(classes.INPUT_STREAM, "inTrustStore", jInvRawTrust);
+
+ } else if (useCustomKeyStore) {
+ jVarTrstFile = jTryBlock.body().decl(classes.INPUT_STREAM, "inTrustStore", _new(classes.FILE_INPUT_STREAM).arg("/system/etc/security/cacerts.bks"));
+ }
+
+ // try load
+ if (useCustomKeyStore || useCustomTrustStore) {
+ JTryBlock jTryLoad = jTryBlock.body()._try();
+
+ if (useCustomKeyStore) {
+ jTryLoad.body().add(invoke(jVarKeystore, "load").arg(jVarKeyFile).arg(invoke(lit(keyStorePwd), "toCharArray")));
+ }
+
+ if (useCustomTrustStore || !useCustomTrustStore && useCustomKeyStore) {
+ jTryLoad.body().add(invoke(jVarTrusted, "load").arg(jVarTrstFile).arg(invoke(lit(trustStorePwd), "toCharArray")));
+ }
+ // finally load
+ JBlock jFinally = jTryLoad._finally();
+ if (useCustomKeyStore) {
+ jFinally.add(invoke(jVarKeyFile, "close"));
+ }
+
+ if (useCustomTrustStore || !useCustomTrustStore && useCustomKeyStore) {
+ jFinally.add(invoke(jVarTrstFile, "close"));
+ }
+ }
+
+ if (null == jVarKeystore && null == jVarTrusted) {
+ JVar jVarCcm = jTryBlock.body().decl(classes.CLIENT_CONNECTION_MANAGER, "ccm");
+ jVarCcm.init(_super().invoke("createClientConnectionManager"));
+
+ if (allowAllHostnames) {
+ JExpression jCast = cast(classes.SSL_SOCKET_FACTORY, jVarCcm.invoke("getSchemeRegistry").invoke("getScheme").arg("https").invoke("getSocketFactory"));
+ jTryBlock.body().add(jCast.invoke("setHostnameVerifier").arg(classes.SSL_SOCKET_FACTORY.staticRef("ALLOW_ALL_HOSTNAME_VERIFIER")));
+ }
+
+ jTryBlock.body()._return(jVarCcm);
+
+ } else {
+ JVar jVarSslFact = jTryBlock.body().decl(classes.SSL_SOCKET_FACTORY, "newSslSocketFactory");
+ jVarSslFact.init(_new(classes.SSL_SOCKET_FACTORY).arg(null == jVarKeystore ? _null() : jVarKeystore).arg(keyStorePwd).arg(null == jVarTrusted ? _null() : jVarTrusted));
+
+ if (allowAllHostnames) {
+ jTryBlock.body().add(invoke(jVarSslFact, "setHostnameVerifier").arg(classes.SSL_SOCKET_FACTORY.staticRef("ALLOW_ALL_HOSTNAME_VERIFIER")));
+ }
+
+ JVar jVarSchemeReg = jTryBlock.body().decl(classes.SCHEME_REGISTRY, "registry");
+ jVarSchemeReg.init(_new(classes.SCHEME_REGISTRY));
+ jTryBlock.body().add(invoke(jVarSchemeReg, "register").arg(_new(classes.SCHEME).arg("https").arg(jVarSslFact).arg(lit(443))));
+
+ JVar jVarCcm = jTryBlock.body().decl(classes.CLIENT_CONNECTION_MANAGER, "ccm");
+ jVarCcm.init(_new(classes.SINGLE_CLIENT_CONN_MANAGER).arg(invoke("getParams")).arg(jVarSchemeReg));
+ jTryBlock.body()._return(jVarCcm);
+ }
+
+ // catch block
+ JCatchBlock jCatchBlock = jTryBlock._catch(classes.EXCEPTION);
+ JVar jVarExceptionParam = jCatchBlock.param("e");
+ jCatchBlock.body().add(jVarExceptionParam.invoke("printStackTrace"));
+ jCatchBlock.body()._return(_super().invoke("createClientConnectionManager"));
+
+ methodBody.assign(ref(fieldName), _new(jAnonClass));
+
+ }
+
+}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/rclass/IRClass.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/rclass/IRClass.java
index 3f210e35a1..b631ee1c24 100644
--- a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/rclass/IRClass.java
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/rclass/IRClass.java
@@ -18,7 +18,7 @@
public interface IRClass {
public enum Res {
- LAYOUT, ID, STRING, ARRAY, COLOR, ANIM, BOOL, DIMEN, DRAWABLE, INTEGER, MOVIE, MENU;
+ LAYOUT, ID, STRING, ARRAY, COLOR, ANIM, BOOL, DIMEN, DRAWABLE, INTEGER, MOVIE, MENU, RAW;
public String rName() {
return toString().toLowerCase();
}
diff --git a/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/validation/HttpsClientValidator.java b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/validation/HttpsClientValidator.java
new file mode 100644
index 0000000000..be977908a1
--- /dev/null
+++ b/AndroidAnnotations/androidannotations/src/main/java/com/googlecode/androidannotations/validation/HttpsClientValidator.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (C) 2010-2011 eBusiness Information, Excilys Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed To in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * @author Nabil Hachicha
+ */
+package com.googlecode.androidannotations.validation;
+
+import java.lang.annotation.Annotation;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+
+import com.googlecode.androidannotations.annotations.HttpsClient;
+import com.googlecode.androidannotations.helper.IdAnnotationHelper;
+import com.googlecode.androidannotations.helper.IdValidatorHelper;
+import com.googlecode.androidannotations.model.AnnotationElements;
+import com.googlecode.androidannotations.rclass.IRClass;
+import com.googlecode.androidannotations.rclass.IRClass.Res;
+
+public class HttpsClientValidator implements ElementValidator {
+
+ private IdValidatorHelper validatorHelper;
+
+ public HttpsClientValidator(ProcessingEnvironment processingEnv, IRClass rClass) {
+ IdAnnotationHelper annotationHelper = new IdAnnotationHelper(processingEnv, getTarget(), rClass);
+ validatorHelper = new IdValidatorHelper(annotationHelper);
+ }
+
+ @Override
+ public Class extends Annotation> getTarget() {
+ return HttpsClient.class;
+ }
+
+ @Override
+ public boolean validate(Element element, AnnotationElements validatedElements) {
+
+ IsValid valid = new IsValid();
+
+ validatorHelper.enclosingElementHasEnhancedComponentAnnotation(element, validatedElements, valid);
+
+ validatorHelper.idExists(element, Res.RAW, false, true, valid, "keyStore");
+ validatorHelper.idExists(element, Res.RAW, false, true, valid, "trustStore");
+
+ validatorHelper.isNotPrivate(element, valid);
+
+ return valid.isValid();
+ }
+
+}
diff --git a/AndroidAnnotations/functional-test-1-5-tests/pom.xml b/AndroidAnnotations/functional-test-1-5-tests/pom.xml
index a08842b740..4979f3a950 100644
--- a/AndroidAnnotations/functional-test-1-5-tests/pom.xml
+++ b/AndroidAnnotations/functional-test-1-5-tests/pom.xml
@@ -46,6 +46,13 @@
junit
test
+
+
+ bouncycastle
+ bcprov-jdk16
+ 140
+
+
diff --git a/AndroidAnnotations/functional-test-1-5-tests/src/test/java/com/googlecode/androidannotations/test15/SSLConnectionTest.java b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/com/googlecode/androidannotations/test15/SSLConnectionTest.java
new file mode 100644
index 0000000000..feed9aa06e
--- /dev/null
+++ b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/com/googlecode/androidannotations/test15/SSLConnectionTest.java
@@ -0,0 +1,70 @@
+package com.googlecode.androidannotations.test15;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.security.Security;
+
+import junit.framework.Assert;
+
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SocketFactory;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidAnnotationsTestRunner.class)
+public class SSLConnectionTest {
+
+ private SSLConnection_ activity;
+
+ @BeforeClass
+ public static void addSecurityProvider() {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ @Before
+ public void setup() {
+ activity = new SSLConnection_();
+ activity.onCreate(null);
+ }
+
+ @Test
+ public void truststoreProvided() {
+ assertNotNull(activity.mHttpsClientTest1);
+ ClientConnectionManager ccm = activity.mHttpsClientTest1.getConnectionManager();
+ assertNotNull(ccm);
+
+ Scheme httpsScheme = ccm.getSchemeRegistry().getScheme("https");
+ assertNotNull(httpsScheme);
+
+ assertEquals(443, httpsScheme.getDefaultPort());
+ SocketFactory socketFactHttps = httpsScheme.getSocketFactory();
+
+ if (!(socketFactHttps instanceof SSLSocketFactory)) {
+ Assert.fail("wrong instance should be org.apache.http.conn.ssl.SSLSocketFactory, getting " + socketFactHttps);
+ }
+ assertEquals(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER, ((SSLSocketFactory) socketFactHttps).getHostnameVerifier());
+ }
+
+ @Test
+ public void strictHostnameVerifier() {
+ assertNotNull(activity.mHttpsClientTest2);
+ ClientConnectionManager ccm = activity.mHttpsClientTest2.getConnectionManager();
+ Scheme httpsScheme = ccm.getSchemeRegistry().getScheme("https");
+ SSLSocketFactory socketFactHttps = (SSLSocketFactory) httpsScheme.getSocketFactory();
+
+ assertEquals(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER, ((SSLSocketFactory) socketFactHttps).getHostnameVerifier());
+ }
+
+ @Test
+ public void noOptions() {
+ assertNotNull(activity.mHttpsClientTest3);
+ ClientConnectionManager ccm = activity.mHttpsClientTest3.getConnectionManager();
+ assertNotNull(ccm);
+ }
+}
diff --git a/AndroidAnnotations/functional-test-1-5/AndroidManifest.xml b/AndroidAnnotations/functional-test-1-5/AndroidManifest.xml
index 68e32206c7..59d6f23e79 100644
--- a/AndroidAnnotations/functional-test-1-5/AndroidManifest.xml
+++ b/AndroidAnnotations/functional-test-1-5/AndroidManifest.xml
@@ -65,6 +65,7 @@
+
diff --git a/AndroidAnnotations/functional-test-1-5/res/raw/cacerts.bks b/AndroidAnnotations/functional-test-1-5/res/raw/cacerts.bks
new file mode 100644
index 0000000000..ca45764aff
Binary files /dev/null and b/AndroidAnnotations/functional-test-1-5/res/raw/cacerts.bks differ
diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/com/googlecode/androidannotations/test15/SSLConnection.java b/AndroidAnnotations/functional-test-1-5/src/main/java/com/googlecode/androidannotations/test15/SSLConnection.java
new file mode 100644
index 0000000000..e15cbbb29d
--- /dev/null
+++ b/AndroidAnnotations/functional-test-1-5/src/main/java/com/googlecode/androidannotations/test15/SSLConnection.java
@@ -0,0 +1,22 @@
+package com.googlecode.androidannotations.test15;
+
+import org.apache.http.client.HttpClient;
+
+import android.app.Activity;
+
+import com.googlecode.androidannotations.annotations.EActivity;
+import com.googlecode.androidannotations.annotations.HttpsClient;
+
+@EActivity
+public class SSLConnection extends Activity {
+
+ @HttpsClient(trustStore = R.raw.cacerts)
+ HttpClient mHttpsClientTest1;
+
+ @HttpsClient(trustStore = R.raw.cacerts, allowAllHostnames = false)
+ HttpClient mHttpsClientTest2;
+
+ @HttpsClient
+ HttpClient mHttpsClientTest3;
+
+}