4444import com .sun .codemodel .JMethod ;
4545import com .sun .codemodel .JMod ;
4646import com .sun .codemodel .JVar ;
47- import com .sun .tools .javac .util .Pair ;
4847
4948public class IntentBuilder {
5049
51- private static final int MIN_SDK_WITH_FRAGMENT_SUPPORT = 11 ;
50+ private static final int MIN_SDK_WITH_FRAGMENT_SUPPORT = 11 ;
5251
5352 protected HasIntentBuilder holder ;
54- protected AndroidManifest androidManifest ;
53+ protected AndroidManifest androidManifest ;
5554 protected JFieldVar contextField ;
5655 protected JClass contextClass ;
5756 protected JClass intentClass ;
58- protected JFieldVar fragmentField ;
59- protected JFieldVar fragmentSupportField ;
60- protected Map <Pair <TypeMirror , String >, JMethod > putExtraMethods = new HashMap <Pair <TypeMirror , String >, JMethod >();
57+ protected JFieldVar fragmentField ;
58+ protected JFieldVar fragmentSupportField ;
59+ protected Map <Pair <TypeMirror , String >, JMethod > putExtraMethods = new HashMap <Pair <TypeMirror , String >, JMethod >();
6160
62- protected Elements elementUtils ;
63- protected Types typeUtils ;
64- protected APTCodeModelHelper codeModelHelper = new APTCodeModelHelper ();
61+ protected Elements elementUtils ;
62+ protected Types typeUtils ;
63+ protected APTCodeModelHelper codeModelHelper = new APTCodeModelHelper ();
6564
6665 public IntentBuilder (HasIntentBuilder holder , AndroidManifest androidManifest ) {
6766 this .holder = holder ;
68- this .androidManifest = androidManifest ;
69- elementUtils = holder .processingEnvironment ().getElementUtils ();
70- typeUtils = holder .processingEnvironment ().getTypeUtils ();
67+ this .androidManifest = androidManifest ;
68+ elementUtils = holder .processingEnvironment ().getElementUtils ();
69+ typeUtils = holder .processingEnvironment ().getTypeUtils ();
7170 contextClass = holder .classes ().CONTEXT ;
7271 intentClass = holder .classes ().INTENT ;
7372 }
7473
7574 public void build () throws JClassAlreadyExistsException {
7675 createClass ();
7776 createConstructor ();
78- createAdditionalConstructor (); // See issue #541
77+ createAdditionalConstructor (); // See issue #541
7978 createGet ();
8079 createFlags ();
8180 createIntent ();
@@ -95,14 +94,14 @@ private void createConstructor() {
9594 constructorBody .assign (holder .getIntentField (), _new (intentClass ).arg (constructorContextParam ).arg (holder .getGeneratedClass ().dotclass ()));
9695 }
9796
98- private void createAdditionalConstructor () {
99- if (hasFragmentInClasspath ()) {
100- fragmentField = addFragmentConstructor (holder .classes ().FRAGMENT , "fragment_" );
101- }
102- if (hasFragmentSupportInClasspath ()) {
103- fragmentSupportField = addFragmentConstructor (holder .classes ().SUPPORT_V4_FRAGMENT , "fragmentSupport_" );
104- }
105- }
97+ private void createAdditionalConstructor () {
98+ if (hasFragmentInClasspath ()) {
99+ fragmentField = addFragmentConstructor (holder .classes ().FRAGMENT , "fragment_" );
100+ }
101+ if (hasFragmentSupportInClasspath ()) {
102+ fragmentSupportField = addFragmentConstructor (holder .classes ().SUPPORT_V4_FRAGMENT , "fragmentSupport_" );
103+ }
104+ }
106105
107106 private void createGet () {
108107 JMethod method = holder .getIntentBuilderClass ().method (PUBLIC , intentClass , "get" );
@@ -122,82 +121,83 @@ private void createIntent() {
122121 JVar contextParam = method .param (contextClass , "context" );
123122 method .body ()._return (_new (holder .getIntentBuilderClass ()).arg (contextParam ));
124123
125- if (hasFragmentInClasspath ()) {
126- // intent() with android.app.Fragment param
127- method = holder .getGeneratedClass ().method (STATIC | PUBLIC , holder .getIntentBuilderClass (), "intent" );
128- JVar fragmentParam = method .param (holder .classes ().FRAGMENT , "fragment" );
129- method .body ()._return (_new (holder .getIntentBuilderClass ()).arg (fragmentParam ));
130- }
131- if (hasFragmentSupportInClasspath ()) {
132- // intent() with android.support.v4.app.Fragment param
133- method = holder .getGeneratedClass ().method (STATIC | PUBLIC , holder .getIntentBuilderClass (), "intent" );
134- JVar fragmentParam = method .param (holder .classes ().SUPPORT_V4_FRAGMENT , "supportFragment" );
135- method .body ()._return (_new (holder .getIntentBuilderClass ()).arg (fragmentParam ));
136- }
124+ if (hasFragmentInClasspath ()) {
125+ // intent() with android.app.Fragment param
126+ method = holder .getGeneratedClass ().method (STATIC | PUBLIC , holder .getIntentBuilderClass (), "intent" );
127+ JVar fragmentParam = method .param (holder .classes ().FRAGMENT , "fragment" );
128+ method .body ()._return (_new (holder .getIntentBuilderClass ()).arg (fragmentParam ));
129+ }
130+ if (hasFragmentSupportInClasspath ()) {
131+ // intent() with android.support.v4.app.Fragment param
132+ method = holder .getGeneratedClass ().method (STATIC | PUBLIC , holder .getIntentBuilderClass (), "intent" );
133+ JVar fragmentParam = method .param (holder .classes ().SUPPORT_V4_FRAGMENT , "supportFragment" );
134+ method .body ()._return (_new (holder .getIntentBuilderClass ()).arg (fragmentParam ));
135+ }
136+ }
137+
138+ private JFieldVar addFragmentConstructor (JClass fragmentClass , String fieldName ) {
139+ JFieldVar fragmentField = holder .getIntentBuilderClass ().field (PRIVATE , fragmentClass , fieldName );
140+ JMethod constructor = holder .getIntentBuilderClass ().constructor (JMod .PUBLIC );
141+ JVar constructorFragmentParam = constructor .param (fragmentClass , "fragment" );
142+ JBlock constructorBody = constructor .body ();
143+ constructorBody .assign (fragmentField , constructorFragmentParam );
144+ constructorBody .assign (contextField , constructorFragmentParam .invoke ("getActivity" ));
145+ constructorBody .assign (holder .getIntentField (), _new (holder .classes ().INTENT ).arg (contextField ).arg (holder .getGeneratedClass ().dotclass ()));
146+ return fragmentField ;
147+ }
148+
149+ private boolean hasFragmentInClasspath () {
150+ boolean fragmentExistsInSdk = androidManifest .getMinSdkVersion () >= MIN_SDK_WITH_FRAGMENT_SUPPORT ;
151+ return fragmentExistsInSdk && elementUtils .getTypeElement (CanonicalNameConstants .FRAGMENT ) != null ;
152+ }
153+
154+ private boolean hasFragmentSupportInClasspath () {
155+ return elementUtils .getTypeElement (CanonicalNameConstants .SUPPORT_V4_FRAGMENT ) != null ;
156+ }
157+
158+ public JMethod getPutExtraMethod (TypeMirror elementType , String parameterName , JFieldVar extraKeyField ) {
159+ Pair <TypeMirror , String > signature = new Pair <TypeMirror , String >(elementType , parameterName );
160+ JMethod putExtraMethod = putExtraMethods .get (signature );
161+ if (putExtraMethod == null ) {
162+ putExtraMethod = addPutExtraMethod (elementType , parameterName , extraKeyField );
163+ putExtraMethods .put (signature , putExtraMethod );
164+ }
165+ return putExtraMethod ;
166+ }
167+
168+ private JMethod addPutExtraMethod (TypeMirror elementType , String parameterName , JFieldVar extraKeyField ) {
169+ boolean castToSerializable = false ;
170+ boolean castToParcelable = false ;
171+ if (elementType .getKind () == TypeKind .DECLARED ) {
172+ Elements elementUtils = holder .processingEnvironment ().getElementUtils ();
173+ TypeMirror parcelableType = elementUtils .getTypeElement (PARCELABLE ).asType ();
174+ if (!typeUtils .isSubtype (elementType , parcelableType )) {
175+ TypeMirror stringType = elementUtils .getTypeElement (STRING ).asType ();
176+ if (!typeUtils .isSubtype (elementType , stringType )) {
177+ castToSerializable = true ;
178+ }
179+ } else {
180+ TypeMirror serializableType = elementUtils .getTypeElement (SERIALIZABLE ).asType ();
181+ if (typeUtils .isSubtype (elementType , serializableType )) {
182+ castToParcelable = true ;
183+ }
184+ }
185+ }
186+
187+ JMethod method = holder .getIntentBuilderClass ().method (PUBLIC , holder .getIntentBuilderClass (), parameterName );
188+ JClass parameterClass = codeModelHelper .typeMirrorToJClass (elementType , holder );
189+ JVar extraParameterVar = method .param (parameterClass , parameterName );
190+ JBlock body = method .body ();
191+ JInvocation invocation = body .invoke (holder .getIntentField (), "putExtra" ).arg (extraKeyField );
192+ if (castToSerializable ) {
193+ invocation .arg (cast (holder .classes ().SERIALIZABLE , extraParameterVar ));
194+ } else if (castToParcelable ) {
195+ invocation .arg (cast (holder .classes ().PARCELABLE , extraParameterVar ));
196+ } else {
197+ invocation .arg (extraParameterVar );
198+ }
199+ body ._return (_this ());
200+ return method ;
137201 }
138202
139- private JFieldVar addFragmentConstructor (JClass fragmentClass , String fieldName ) {
140- JFieldVar fragmentField = holder .getIntentBuilderClass ().field (PRIVATE , fragmentClass , fieldName );
141- JMethod constructor = holder .getIntentBuilderClass ().constructor (JMod .PUBLIC );
142- JVar constructorFragmentParam = constructor .param (fragmentClass , "fragment" );
143- JBlock constructorBody = constructor .body ();
144- constructorBody .assign (fragmentField , constructorFragmentParam );
145- constructorBody .assign (contextField , constructorFragmentParam .invoke ("getActivity" ));
146- constructorBody .assign (holder .getIntentField (), _new (holder .classes ().INTENT ).arg (contextField ).arg (holder .getGeneratedClass ().dotclass ()));
147- return fragmentField ;
148- }
149-
150- private boolean hasFragmentInClasspath () {
151- boolean fragmentExistsInSdk = androidManifest .getMinSdkVersion () >= MIN_SDK_WITH_FRAGMENT_SUPPORT ;
152- return fragmentExistsInSdk && elementUtils .getTypeElement (CanonicalNameConstants .FRAGMENT ) != null ;
153- }
154-
155- private boolean hasFragmentSupportInClasspath () {
156- return elementUtils .getTypeElement (CanonicalNameConstants .SUPPORT_V4_FRAGMENT ) != null ;
157- }
158-
159- public JMethod getPutExtraMethod (TypeMirror elementType , String parameterName , JFieldVar extraKeyField ) {
160- Pair <TypeMirror , String > signature = new Pair <TypeMirror , String >(elementType ,parameterName );
161- JMethod putExtraMethod = putExtraMethods .get (signature );
162- if (putExtraMethod == null ) {
163- putExtraMethod = addPutExtraMethod (elementType , parameterName , extraKeyField );
164- putExtraMethods .put (signature , putExtraMethod );
165- }
166- return putExtraMethod ;
167- }
168-
169- private JMethod addPutExtraMethod (TypeMirror elementType , String parameterName , JFieldVar extraKeyField ) {
170- boolean castToSerializable = false ;
171- boolean castToParcelable = false ;
172- if (elementType .getKind () == TypeKind .DECLARED ) {
173- Elements elementUtils = holder .processingEnvironment ().getElementUtils ();
174- TypeMirror parcelableType = elementUtils .getTypeElement (PARCELABLE ).asType ();
175- if (!typeUtils .isSubtype (elementType , parcelableType )) {
176- TypeMirror stringType = elementUtils .getTypeElement (STRING ).asType ();
177- if (!typeUtils .isSubtype (elementType , stringType )) {
178- castToSerializable = true ;
179- }
180- } else {
181- TypeMirror serializableType = elementUtils .getTypeElement (SERIALIZABLE ).asType ();
182- if (typeUtils .isSubtype (elementType , serializableType )) {
183- castToParcelable = true ;
184- }
185- }
186- }
187-
188- JMethod method = holder .getIntentBuilderClass ().method (PUBLIC , holder .getIntentBuilderClass (), parameterName );
189- JClass parameterClass = codeModelHelper .typeMirrorToJClass (elementType , holder );
190- JVar extraParameterVar = method .param (parameterClass , parameterName );
191- JBlock body = method .body ();
192- JInvocation invocation = body .invoke (holder .getIntentField (), "putExtra" ).arg (extraKeyField );
193- if (castToSerializable ) {
194- invocation .arg (cast (holder .classes ().SERIALIZABLE , extraParameterVar ));
195- } else if (castToParcelable ) {
196- invocation .arg (cast (holder .classes ().PARCELABLE , extraParameterVar ));
197- } else {
198- invocation .arg (extraParameterVar );
199- }
200- body ._return (_this ());
201- return method ;
202- }
203203}
0 commit comments