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 }