001 /* 002 * Copyright 2013 Google Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 package com.google.gwtmockito.fakes; 017 018 import com.google.gwt.safehtml.shared.SafeHtml; 019 import com.google.gwt.safehtml.shared.SafeHtmlUtils; 020 import com.google.gwt.safehtml.shared.SafeUri; 021 022 import java.lang.reflect.InvocationHandler; 023 import java.lang.reflect.Method; 024 import java.lang.reflect.Proxy; 025 import java.util.Arrays; 026 027 /** 028 * Provides fake implementations of {@link com.google.gwt.i18n.client.Messages}, 029 * {@link com.google.gwt.resources.client.CssResource}, and 030 * {@link com.google.gwt.safehtml.client.SafeHtmlTemplates}. The fake 031 * implementations implement methods by returning Strings of SafeHtml instances 032 * based on the method name and the arguments passed to it. The exact format of 033 * the message is undefined and is subject to change. 034 * 035 * @author ekuefler@google.com (Erik Kuefler) 036 */ 037 public class FakeMessagesProvider<T> implements FakeProvider<T> { 038 039 /** 040 * Returns a new instance of the given type that implements methods as 041 * described in the class description. 042 * 043 * @param type interface to be implemented by the returned type. 044 */ 045 @Override 046 @SuppressWarnings("unchecked") // safe since the proxy implements type 047 public T getFake(Class<?> type) { 048 return (T) Proxy.newProxyInstance(FakeMessagesProvider.class.getClassLoader(), new Class<?>[] {type}, 049 new InvocationHandler() { 050 @Override 051 public Object invoke(Object proxy, Method method, Object[] args) throws Exception { 052 if (method.getName().equals("ensureInjected")) { 053 return true; 054 } else if (method.getReturnType() == String.class) { 055 return buildMessage(method, args); 056 } else if (method.getReturnType() == SafeHtml.class) { 057 return SafeHtmlUtils.fromTrustedString(buildMessage(method, args)); 058 } else { 059 throw new IllegalArgumentException(method.getName() 060 + " must return either String or SafeHtml"); 061 } 062 } 063 }); 064 } 065 066 private String buildMessage(Method method, Object[] args) { 067 StringBuilder message = new StringBuilder(method.getName()); 068 if (args == null || args.length == 0) { 069 return message.toString(); 070 } 071 072 message.append('('); 073 message.append(stringify(args[0])); 074 for (Object arg : Arrays.asList(args).subList(1, args.length)) { 075 message.append(", ").append(stringify(arg)); 076 } 077 return message.append(')').toString(); 078 } 079 080 private String stringify(Object arg) { 081 if (arg == null) { 082 return "null"; 083 } else if (arg instanceof SafeHtml) { 084 return ((SafeHtml) arg).asString(); 085 } else if (arg instanceof SafeUri) { 086 return ((SafeUri) arg).asString(); 087 } else { 088 return arg.toString(); 089 } 090 } 091 }