1 4 package com.opensymphony.webwork.portlet.velocity; 5 6 import com.opensymphony.module.sitemesh.Decorator; 7 import com.opensymphony.module.sitemesh.Factory; 8 import com.opensymphony.module.sitemesh.HTMLPage; 9 import com.opensymphony.module.sitemesh.parser.FastPageParser; 10 import com.opensymphony.module.sitemesh.util.OutputConverter; 11 import com.opensymphony.webwork.portlet.context.PortletContext; 12 import com.opensymphony.webwork.portlet.sitemesh.VelocityUtils; 13 import com.opensymphony.webwork.views.velocity.VelocityManager; 14 import com.opensymphony.xwork.ActionContext; 15 import org.apache.log4j.Category; 16 import org.apache.velocity.context.Context; 17 import org.apache.velocity.context.InternalContextAdapter; 18 import org.apache.velocity.exception.MethodInvocationException; 19 import org.apache.velocity.exception.ParseErrorException; 20 import org.apache.velocity.exception.ResourceNotFoundException; 21 import org.apache.velocity.runtime.RuntimeServices; 22 import org.apache.velocity.runtime.directive.Directive; 23 import org.apache.velocity.runtime.parser.node.Node; 24 25 import javax.servlet.http.HttpServletRequest ; 26 import javax.servlet.http.HttpServletResponse ; 27 import java.io.IOException ; 28 import java.io.StringReader ; 29 import java.io.StringWriter ; 30 import java.io.Writer ; 31 import java.util.EmptyStackException ; 32 import java.util.HashMap ; 33 import java.util.Map ; 34 import java.util.Stack ; 35 36 40 public final class ApplyDecoratorDirective extends Directive { 41 private static final Category log; 42 43 public static final String STACK_KEY; 44 45 private DirectiveStack stack; 46 47 private Map params; 48 49 static { 50 log = Category.getInstance(com.opensymphony.webwork.portlet.velocity.ApplyDecoratorDirective.class); 51 STACK_KEY = (com.opensymphony.webwork.portlet.velocity.ApplyDecoratorDirective.DirectiveStack.class).getName(); 52 } 53 54 public class DirectiveStack { 55 56 public ApplyDecoratorDirective pop() { 57 try { 58 return (ApplyDecoratorDirective) stack.pop(); 59 } catch (EmptyStackException e) { 60 ApplyDecoratorDirective.log.info("Someone's been popping out of order! " + e.getMessage(), e); 61 return null; 62 } 63 } 64 65 public void push(ApplyDecoratorDirective directive) { 66 stack.push(directive); 67 } 68 69 public ApplyDecoratorDirective peek() { 70 if (stack.size() > 0) 71 return (ApplyDecoratorDirective) stack.peek(); 72 else 73 return null; 74 } 75 76 Stack stack; 77 78 public DirectiveStack() { 79 stack = new Stack (); 80 } 81 } 82 83 public ApplyDecoratorDirective() { 84 params = new HashMap (); 85 } 86 87 public String getName() { 88 return "applyDecorator"; 89 } 90 91 public int getType() { 92 return 1; 93 } 94 95 public void init(RuntimeServices services, InternalContextAdapter adapter, Node node) throws Exception { 96 super.init(services, adapter, node); 97 int numArgs = node.jjtGetNumChildren(); 98 if (numArgs < 2) 99 services.error("#applyDecorator error: You need a decorator name in order to use this tag"); 100 else if (numArgs > 3) 101 services.error("#applyDecorator error: Too many parameters"); 102 } 103 104 public boolean render(InternalContextAdapter adapter, Writer writer, Node node) throws IOException , ResourceNotFoundException, 105 ParseErrorException, MethodInvocationException { 106 107 stack = (DirectiveStack) adapter.get(STACK_KEY); 108 if (stack == null) { 109 stack = new DirectiveStack(); 110 adapter.put(STACK_KEY, stack); 111 } 112 stack.push(this); 113 114 boolean flag; 115 HttpServletRequest request = (HttpServletRequest ) adapter.get("req"); 116 if (request == null) 117 throw new IOException ("No request object in context."); 118 119 HttpServletResponse response = (HttpServletResponse ) adapter.get("res"); 120 if (response == null) 121 throw new IOException ("No response object in context."); 122 123 try { 124 String decoratorName = (String ) node.jjtGetChild(0).value(adapter); 125 StringWriter bodyContent = new StringWriter (1024); 126 127 int bodyNode = 1; 128 if (node.jjtGetNumChildren() == 3) 129 bodyNode = 2; 130 node.jjtGetChild(bodyNode).render(adapter, bodyContent); 131 132 Factory factory = PortletContext.getContext().getSiteMeshFactory(); 133 Decorator decorator = factory.getDecoratorMapper().getNamedDecorator(request, decoratorName); 134 if (decorator != null) { 135 com.opensymphony.module.sitemesh.PageParser parser = factory.getPageParser("text/html"); 136 HTMLPage page = (HTMLPage) ((FastPageParser) parser).parse(new StringReader (bodyContent.toString())); 137 Context context = VelocityManager.getInstance() 138 .createContext(ActionContext.getContext().getValueStack(), request, response); 139 context.put("page", page); 140 if (node.jjtGetNumChildren() == 3) 141 context.put("title", (String ) node.jjtGetChild(1).value(adapter)); 142 else 143 context.put("title", page.getTitle()); 144 StringWriter buffer = new StringWriter (); 145 page.writeBody(OutputConverter.getWriter(buffer)); 146 context.put("body", buffer.toString()); 147 buffer = new StringWriter (); 148 page.writeHead(OutputConverter.getWriter(buffer)); 149 context.put("head", buffer.toString()); 150 context.put("params", params); 151 writer.write(VelocityUtils.getRenderedTemplate(decorator.getPage(), context)); 152 } else { 153 throw new IOException ("could not find decorator with name: " + decoratorName); 154 } 155 flag = true; 156 stack.pop(); 157 158 return flag; 159 } catch (Exception exception) { 160 161 stack.pop(); 162 throw new IOException (exception.toString()); 163 } 164 } 165 166 public void addParameter(String paramName, Object paramValue) { 167 params.put(paramName, paramValue); 168 } 169 170 } | Popular Tags |