1 package org.argeo.support.freemarker;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.net.URLDecoder;
6 import java.nio.charset.StandardCharsets;
7 import java.security.PrivilegedExceptionAction;
8 import java.util.HashMap;
9 import java.util.Map;
10
11 import javax.jcr.Node;
12 import javax.jcr.Repository;
13 import javax.jcr.Session;
14 import javax.security.auth.Subject;
15 import javax.security.auth.login.LoginContext;
16 import javax.servlet.ServletException;
17 import javax.servlet.http.HttpServlet;
18 import javax.servlet.http.HttpServletRequest;
19 import javax.servlet.http.HttpServletResponse;
20
21 import org.argeo.cms.CmsException;
22 import org.argeo.cms.auth.HttpRequestCallbackHandler;
23 import org.argeo.jcr.JcrUtils;
24 import org.argeo.node.NodeConstants;
25 import org.osgi.framework.BundleContext;
26 import org.osgi.framework.FrameworkUtil;
27 import org.osgi.framework.ServiceReference;
28 import org.osgi.util.tracker.ServiceTracker;
29
30 import freemarker.template.Configuration;
31 import freemarker.template.SimpleScalar;
32 import freemarker.template.Template;
33 import freemarker.template.TemplateExceptionHandler;
34
35 public class HtmlServlet extends HttpServlet {
36 private static final long serialVersionUID = 2083925371199357045L;
37 static String base = System.getProperty("user.home") + File.separator + "dev" + File.separator + "work"
38 + File.separator + "ftl";
39 static Configuration cfg;
40 static {
41 try {
42 cfg = new Configuration(Configuration.VERSION_2_3_28);
43 cfg.setDirectoryForTemplateLoading(new File(base));
44 cfg.setDefaultEncoding("UTF-8");
45 cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
46 cfg.setLogTemplateExceptions(false);
47 cfg.setWrapUncheckedExceptions(true);
48 } catch (IOException e) {
49
50 e.printStackTrace();
51 }
52 }
53
54 private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
55 private ServiceTracker<Repository, Repository> repositorySt;
56
57 private Repository repository;
58
59 @Override
60 public void init() throws ServletException {
61 repositorySt = new ServiceTracker<Repository, Repository>(bc, Repository.class, null) {
62
63 @Override
64 public Repository addingService(ServiceReference<Repository> reference) {
65 String cn = reference.getProperty(NodeConstants.CN).toString();
66 Repository repo = super.addingService(reference);
67 if (NodeConstants.NODE.equals(cn))
68 repository = repo;
69 return repo;
70 }
71
72 };
73 repositorySt.open();
74 }
75
76 @Override
77 public void destroy() {
78 if (repositorySt != null)
79 repositorySt.close();
80 }
81
82 @Override
83 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
84
85 String path = URLDecoder.decode(req.getPathInfo(), StandardCharsets.UTF_8.name());
86 String servletPath = req.getServletPath();
87 String[] p = path.split("/");
88
89 String basePath = servletPath + '/' + p[1];
90 String template = p[1] + ".ftl";
91 StringBuilder sb = new StringBuilder();
92 for (int i = 2; i < p.length; i++)
93 sb.append('/').append(p[i]);
94 String nodePath = sb.toString();
95 if ("".equals(nodePath.trim()))
96 nodePath = "/";
97 Session session = null;
98 try {
99 LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
100 new HttpRequestCallbackHandler(req, resp));
101 lc.login();
102 session = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Session>() {
103
104 @Override
105 public Session run() throws Exception {
106 Session session = repository.login();
107 return session;
108 }
109 });
110
111 Node node = session.getNode(nodePath);
112
113 Template t = cfg.getTemplate(template);
114 Map<String, Object> root = new HashMap<>();
115 root.put("node", new JcrModel(node));
116 root.put("basePath", new SimpleScalar(basePath));
117
118 t.process(root, resp.getWriter());
119
120 resp.setContentType("text/html");
121 } catch (Exception e) {
122 throw new CmsException("Cannot process template", e);
123 } finally {
124 JcrUtils.logoutQuietly(session);
125 }
126 }
127
128 }