001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.kernel.bean;
016    
017    import com.liferay.portal.kernel.annotation.AutoEscape;
018    import com.liferay.portal.kernel.util.HtmlUtil;
019    
020    import java.lang.reflect.InvocationHandler;
021    import java.lang.reflect.InvocationTargetException;
022    import java.lang.reflect.Method;
023    
024    /**
025     * Wraps a bean so that all strings returned from <code>@AutoEscape</code>
026     * annotated methods are automatically HTML escaped.
027     *
028     * <p>
029     * For a usage example see {@link
030     * com.liferay.portlet.shopping.util.ShoppingUtil#getBreadcrumbs(
031     * com.liferay.portlet.shopping.model.ShoppingCategory,
032     * javax.servlet.jsp.PageContext, javax.portlet.RenderRequest,
033     * javax.portlet.RenderResponse) ShoppingUtil.getBreadcrumbs} .
034     * </p>
035     *
036     * @author Shuyang Zhou
037     * @see    AutoEscape
038     */
039    public class AutoEscapeBeanHandler implements InvocationHandler {
040    
041            public AutoEscapeBeanHandler(Object bean) {
042                    _bean = bean;
043            }
044    
045            public Object getBean() {
046                    return _bean;
047            }
048    
049            public Object invoke(Object proxy, Method method, Object[] args)
050                    throws Throwable {
051    
052                    String methodName = method.getName();
053    
054                    if (methodName.startsWith("set")) {
055                            throw new IllegalAccessException(
056                                    "Setter methods cannot be called on an escaped bean");
057                    }
058    
059                    if (methodName.endsWith("isEscapedModel")) {
060                            return true;
061                    }
062    
063                    Object result = null;
064    
065                    try {
066                            result = method.invoke(_bean, args);
067                    }
068                    catch(InvocationTargetException ite) {
069                            throw ite.getTargetException();
070                    }
071    
072                    if (method.getAnnotation(AutoEscape.class) != null) {
073                            result = HtmlUtil.escape((String)result);
074                    }
075    
076                    return result;
077            }
078    
079            private Object _bean;
080    
081    }