2121import static org .androidannotations .helper .AndroidConstants .LOG_VERBOSE ;
2222import static org .androidannotations .helper .AndroidConstants .LOG_WARN ;
2323
24+ import java .util .ArrayList ;
25+ import java .util .Arrays ;
26+ import java .util .List ;
27+
2428import javax .annotation .processing .ProcessingEnvironment ;
2529import javax .lang .model .element .Element ;
2630import javax .lang .model .element .ExecutableElement ;
4044import com .sun .codemodel .JInvocation ;
4145import com .sun .codemodel .JMethod ;
4246import com .sun .codemodel .JTryBlock ;
47+ import com .sun .codemodel .JType ;
4348import com .sun .codemodel .JVar ;
4449
4550public class TraceHandler extends BaseAnnotationHandler <EComponentHolder > {
@@ -80,21 +85,28 @@ public void process(Element element, EComponentHolder holder) throws Exception {
8085 JInvocation currentTimeInvoke = classes ().SYSTEM .staticInvoke ("currentTimeMillis" );
8186 JBlock _thenBody = ifStatement ._then ();
8287
83- String methodName = "[" + element .toString () + "]" ;
84-
8588 // Log In
8689 String logMethodName = logMethodNameFromLevel (level );
8790 JInvocation logEnterInvoke = classes ().LOG .staticInvoke (logMethodName );
8891 logEnterInvoke .arg (tag );
8992
90- JExpression enterMessage = JExpr .lit ("Entering " + methodName );
91- logEnterInvoke .arg (enterMessage );
93+ logEnterInvoke .arg (getEnterMessage (method , executableElement ));
9294 _thenBody .add (logEnterInvoke );
9395 JVar startDeclaration = _thenBody .decl (codeModel ().LONG , "start" , currentTimeInvoke );
9496
95- JTryBlock tryBlock = _thenBody ._try ();
96-
97- tryBlock .body ().add (previousMethodBody );
97+ JTryBlock tryBlock ;
98+
99+ JVar result = null ;
100+ if (method .type ().fullName ().equals ("void" )) {
101+ tryBlock = _thenBody ._try ();
102+ tryBlock .body ().add (previousMethodBody );
103+ } else {
104+ JInvocation superCall = codeModelHelper .getSuperCall (holder , method );
105+ result = _thenBody .decl (refClass (Object .class ), "result" , JExpr ._null ());
106+ tryBlock = _thenBody ._try ();
107+ tryBlock .body ().assign (result , superCall );
108+ tryBlock .body ()._return (JExpr .cast (boxify (method .type ()), result ));
109+ }
98110
99111 JBlock finallyBlock = tryBlock ._finally ();
100112
@@ -103,15 +115,89 @@ public void process(Element element, EComponentHolder holder) throws Exception {
103115 JInvocation logExitInvoke = classes ().LOG .staticInvoke (logMethodName );
104116 logExitInvoke .arg (tag );
105117
106- JExpression exitMessage = JExpr .lit ("Exiting " + methodName + ", duration in ms: " ).plus (durationDeclaration );
107- logExitInvoke .arg (exitMessage );
118+ logExitInvoke .arg (getExitMessage (executableElement , method , result , durationDeclaration ));
108119 finallyBlock .add (logExitInvoke );
109120
110121 JBlock elseBlock = ifStatement ._else ();
111122
112123 elseBlock .add (previousMethodBody );
113124 }
114125
126+ private JClass boxify (JType type ) throws ClassNotFoundException {
127+ return codeModel ().parseType (type .fullName ()).boxify ();
128+ }
129+
130+ private JExpression getExitMessage (ExecutableElement element , JMethod method , JVar result , JVar duration ) throws ClassNotFoundException {
131+ String methodName = getMethodName (element );
132+
133+ List <JVar > params = method .params ();
134+ StringBuilder paramStr = new StringBuilder ();
135+ for (int i = 0 ; i < params .size (); i ++) {
136+ if (i > 0 ) {
137+ paramStr .append (", " );
138+ }
139+ JVar var = params .get (i );
140+ paramStr .append (var .type ().name ());
141+ }
142+
143+ methodName += "(" + paramStr .toString () + ")" ;
144+
145+ JInvocation format = refClass (String .class ).staticInvoke ("format" );
146+ if (result == null ) {
147+ format .arg ("Exiting [" + methodName + "], duration in ms: %d" );
148+ } else {
149+ format .arg ("Exiting [" + methodName + " returning: %s], duration in ms: %d" );
150+ if (method .type ().isArray ()) {
151+ JClass arraysClass = refClass (Arrays .class );
152+ format .arg (arraysClass .staticInvoke ("toString" ).arg (JExpr .cast (boxify (method .type ()), result )));
153+ } else {
154+ format .arg (result );
155+ }
156+ }
157+
158+ return format .arg (duration );
159+ }
160+
161+ private JExpression getEnterMessage (JMethod method , ExecutableElement element ) {
162+ String methodName = getMethodName (element );
163+
164+ List <JVar > params = method .params ();
165+ if (params .isEmpty ()) {
166+ // early exit if the method has no parameters
167+ return JExpr .lit ("Entering [" + methodName + "()]" );
168+ }
169+
170+ JClass arraysClass = refClass (Arrays .class );
171+ StringBuilder paramStr = new StringBuilder ();
172+ List <JExpression > paramExpressions = new ArrayList <JExpression >();
173+ for (int i = 0 ; i < params .size (); i ++) {
174+ if (i > 0 ) {
175+ paramStr .append (", " );
176+ }
177+ JVar var = params .get (i );
178+ paramStr .append (var .name ()).append (" = %s" );
179+ if (var .type ().isArray ()) {
180+ paramExpressions .add (arraysClass .staticInvoke ("toString" ).arg (var ));
181+ } else {
182+ paramExpressions .add (var );
183+ }
184+ }
185+
186+ JInvocation format = refClass (String .class ).staticInvoke ("format" );
187+ format .arg (JExpr .lit ("Entering [" + methodName + "(" + paramStr + ")]" ));
188+ for (JExpression expr : paramExpressions ) {
189+ format .arg (expr );
190+ }
191+
192+ return format ;
193+ }
194+
195+ private String getMethodName (ExecutableElement element ) {
196+ String returnType = element .getReturnType ().toString ();
197+ String simpleName = element .getSimpleName ().toString ();
198+ return returnType + " " + simpleName ;
199+ }
200+
115201 private String logMethodNameFromLevel (int level ) {
116202 switch (level ) {
117203 case LOG_DEBUG :
0 commit comments