001    // Copyright 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.annotations;
016    
017    import java.lang.reflect.Method;
018    import java.lang.reflect.Modifier;
019    
020    import org.apache.hivemind.ApplicationRuntimeException;
021    import org.apache.hivemind.Location;
022    import org.apache.hivemind.Messages;
023    import org.apache.hivemind.service.MethodSignature;
024    import org.apache.hivemind.service.impl.ClassFactoryImpl;
025    import org.apache.tapestry.enhance.EnhanceUtils;
026    import org.apache.tapestry.enhance.EnhancementOperation;
027    import org.apache.tapestry.enhance.EnhancementOperationImpl;
028    import org.apache.tapestry.services.ComponentConstructor;
029    import org.apache.tapestry.spec.ComponentSpecification;
030    import org.apache.tapestry.spec.IComponentSpecification;
031    import static org.easymock.EasyMock.aryEq;
032    import static org.easymock.EasyMock.eq;
033    import static org.easymock.EasyMock.expect;
034    import org.testng.annotations.Test;
035    
036    @Test
037    public class TestMessageAnnotationWorker extends BaseAnnotationTestCase
038    {
039        public void testNoArgsMessage()
040        {
041            attempt("noArgsMessage", "{\n  return getMessages().getMessage(\"no-args-message\");\n}\n");
042        }
043    
044        public void testMessageWithSpecificKey()
045        {
046            attempt(
047                    "messageWithSpecificKey",
048                    "{\n  return getMessages().getMessage(\"message-key\");\n}\n");
049        }
050    
051        public void testMessageWithParameters()
052        {
053            attempt("messageWithParameters", "{\n"
054                    + "  java.lang.Object[] params = new java.lang.Object[2];\n"
055                    + "  params[0] = $1;\n" + "  params[1] = $2;\n"
056                    + "  return getMessages().format(\"message-with-parameters\", params);\n}\n");
057        }
058    
059        public void testMessageWithPrimitiveParameters()
060        {
061            attempt("messageWithPrimitives", "{\n"
062                    + "  java.lang.Object[] params = new java.lang.Object[2];\n"
063                    + "  params[0] = ($w) $1;\n" + "  params[1] = ($w) $2;\n"
064                    + "  return getMessages().format(\"message-with-primitives\", params);\n}\n");
065        }
066    
067        public void testNotStringReturnType()
068        {
069            EnhancementOperation op = newOp();
070            IComponentSpecification spec = newSpec();
071    
072            Method method = findMethod(AnnotatedPage.class, "voidMessage");
073    
074            replay();
075    
076            try
077            {
078                new MessageAnnotationWorker().performEnhancement(op, spec, method, null);
079                unreachable();
080            }
081            catch (ApplicationRuntimeException ex)
082            {
083                assertEquals(
084                        "The method's return type is void; this annotation is only allowed on methods that return java.lang.String.",
085                        ex.getMessage());
086            }
087    
088            verify();
089    
090        }
091    
092        public void testSetterIsClaimed()
093        {
094            Location l = newLocation();
095            EnhancementOperation op = newOp();
096            IComponentSpecification spec = newSpec();
097    
098            Method method = findMethod(AnnotatedPage.class, "getLikeGetter");
099    
100            op.addMethod(
101                    Modifier.PUBLIC,
102                    new MethodSignature(method),
103                    "{\n  return getMessages().getMessage(\"like-getter\");\n}\n",
104                    l);
105            op.claimReadonlyProperty("likeGetter");
106    
107            replay();
108    
109            new MessageAnnotationWorker().performEnhancement(op, spec, method, l);
110    
111            verify();
112        }
113    
114        private void attempt(String methodName, String codeBlock)
115        {
116            Location l = newLocation();
117            EnhancementOperation op = newOp();
118            IComponentSpecification spec = newSpec();
119    
120            Method method = findMethod(AnnotatedPage.class, methodName);
121    
122            op.addMethod(Modifier.PUBLIC, new MethodSignature(method), codeBlock, l);
123    
124            replay();
125    
126            new MessageAnnotationWorker().performEnhancement(op, spec, method, l);
127    
128            verify();
129        }
130    
131        private Object construct(Class baseClass, String methodName, Messages messages)
132        {
133            Location l = newLocation();
134    
135            ComponentSpecification spec = new ComponentSpecification();
136            EnhancementOperationImpl op = new EnhancementOperationImpl(getClassResolver(), spec,
137                    baseClass, new ClassFactoryImpl(), null);
138    
139            op.addInjectedField("_messages", Messages.class, messages);
140    
141            EnhanceUtils.createSimpleAccessor(op, "_messages", "messages", Messages.class, l);
142    
143            Method method = findMethod(baseClass, methodName);
144    
145            new MessageAnnotationWorker().performEnhancement(op, spec, method, l);
146    
147            ComponentConstructor cc = op.getConstructor();
148    
149            return cc.newInstance();
150        }
151    
152        public void testNoParams()
153        {
154            Messages messages = newMock(Messages.class);
155            
156            expect(messages.getMessage("no-params")).andReturn("<no params>");
157    
158            MessagesTarget mt = (MessagesTarget) construct(MessagesTarget.class, "noParams", messages);
159    
160            replay();
161    
162            assertEquals("<no params>", mt.noParams());
163    
164            verify();
165        }
166    
167        public void testObjectParam()
168        {
169            Messages messages = newMock(Messages.class);
170    
171            Object[] params = new Object[]
172            { "PinkFloyd" };
173    
174            expect(messages.format(eq("object-param"), aryEq(params))).andReturn("<object param>");
175            
176            MessagesTarget mt = (MessagesTarget) construct(
177                    MessagesTarget.class,
178                    "objectParam",
179                    messages);
180    
181            replay();
182    
183            assertEquals("<object param>", mt.objectParam("PinkFloyd"));
184    
185            verify();
186        }
187    
188        public void testPrimitiveParam()
189        {
190            Messages messages = newMock(Messages.class);
191    
192            Object[] params = new Object[]
193            { 451 };
194    
195            expect(messages.format(eq("primitive-param"), aryEq(params))).andReturn("<primitive param>");
196            
197            MessagesTarget mt = (MessagesTarget) construct(
198                    MessagesTarget.class,
199                    "primitiveParam",
200                    messages);
201    
202            replay();
203    
204            assertEquals("<primitive param>", mt.primitiveParam(451));
205    
206            verify();
207    
208        }
209    
210        public void testInvalidBindings()
211        {
212            invalidBinding("no equals");
213            invalidBinding("= at start");
214            invalidBinding("equals at end=");
215        }
216    
217        private void invalidBinding(String binding)
218        {
219            try
220            {
221                new ComponentAnnotationWorker().addBinding(null, binding, null);
222                unreachable();
223            }
224            catch (ApplicationRuntimeException ex)
225            {
226                assertEquals(AnnotationMessages.bindingWrongFormat(binding), ex.getMessage());
227            }
228        }
229    }