--- /dev/null
+package org.argeo.cms.internal.http;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.argeo.cms.CmsException;
+import org.argeo.cms.auth.HttpRequestCallbackHandler;
+import org.argeo.fm.jcr.JcrModel;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.node.NodeConstants;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import freemarker.template.Configuration;
+import freemarker.template.SimpleScalar;
+import freemarker.template.Template;
+import freemarker.template.TemplateExceptionHandler;
+
+public class HtmlServlet extends HttpServlet {
+ private static final long serialVersionUID = 2083925371199357045L;
+ static String base = System.getProperty("user.home") + File.separator + "dev" + File.separator + "work"
+ + File.separator + "ftl";
+ static Configuration cfg;
+ static {
+ try {
+ cfg = new Configuration(Configuration.VERSION_2_3_28);
+ cfg.setDirectoryForTemplateLoading(new File(base));
+ cfg.setDefaultEncoding("UTF-8");
+ cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
+ cfg.setLogTemplateExceptions(false);
+ cfg.setWrapUncheckedExceptions(true);
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
+ private ServiceTracker<Repository, Repository> repositorySt;
+
+ private Repository repository;
+
+ @Override
+ public void init() throws ServletException {
+ repositorySt = new ServiceTracker<Repository, Repository>(bc, Repository.class, null) {
+
+ @Override
+ public Repository addingService(ServiceReference<Repository> reference) {
+ String cn = reference.getProperty(NodeConstants.CN).toString();
+ Repository repo = super.addingService(reference);
+ if (NodeConstants.NODE.equals(cn))
+ repository = repo;
+ return repo;
+ }
+
+ };
+ repositorySt.open();
+ }
+
+ @Override
+ public void destroy() {
+ if (repositorySt != null)
+ repositorySt.close();
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ String path = req.getPathInfo();
+ String servletPath = req.getServletPath();
+ String[] p = path.split("/");
+
+ String basePath =servletPath+'/'+p[1];
+ String template = p[1] + ".ftl";
+ StringBuilder sb = new StringBuilder();
+ for (int i = 2; i < p.length; i++)
+ sb.append('/').append(p[i]);
+
+ Session session = null;
+ try {
+ LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
+ new HttpRequestCallbackHandler(req, resp));
+ lc.login();
+ session = Subject.doAs(lc.getSubject(), new PrivilegedExceptionAction<Session>() {
+
+ @Override
+ public Session run() throws Exception {
+ Session session = repository.login();
+ return session;
+ }
+ });
+
+ Node node = session.getNode(sb.toString());
+
+ Template t = cfg.getTemplate(template);
+ Map<String, Object> root = new HashMap<>();
+ root.put("node", new JcrModel(node));
+ root.put("basePath", new SimpleScalar(basePath));
+
+ t.process(root, resp.getWriter());
+
+ resp.setContentType("text/html");
+ } catch (Exception e) {
+ throw new CmsException("Cannot log in", e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+ }
+
+}
import org.argeo.cms.CmsException;
import org.argeo.cms.internal.http.CmsSessionProvider;
import org.argeo.cms.internal.http.DataHttpContext;
+import org.argeo.cms.internal.http.HtmlServlet;
import org.argeo.cms.internal.http.HttpUtils;
import org.argeo.cms.internal.http.LinkServlet;
import org.argeo.cms.internal.http.PrivateHttpContext;
try {
httpService.registerServlet("/!", new LinkServlet(), null, null);
httpService.registerServlet("/robots.txt", new RobotServlet(), null, null);
+ httpService.registerServlet("/html", new HtmlServlet(), null, null);
} catch (Exception e) {
throw new CmsException("Cannot register filters", e);
}
import javax.jcr.Node;
import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
+import javax.jcr.Value;
import freemarker.template.SimpleScalar;
+import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateHashModel;
+import freemarker.template.TemplateHashModelEx2;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
+import freemarker.template.TemplateModelIterator;
import freemarker.template.TemplateNodeModel;
import freemarker.template.TemplateSequenceModel;
}
}
+ // HASH
+
@Override
public TemplateModel get(String key) throws TemplateModelException {
try {
+ if ("jcr:path".equals(key))
+ return new SimpleScalar(node.getPath());
+ if ("jcr:name".equals(key))
+ return new SimpleScalar(node.getName());
+ if ("jcr:properties".equals(key))
+ return new PropertiesModel();
+ if ("jcr:parent".equals(key))
+ return node.getParent() != null ? new JcrModel(node.getParent()) : null;
+
Property property = node.getProperty(key);
if (property == null)
return null;
@Override
public boolean isEmpty() throws TemplateModelException {
- // JCR default properties always accessible
return false;
}
- // HASH
+ public Node getNode() {
+ return node;
+ }
+
+ protected TemplateModel propertyValues(Property property) throws RepositoryException {
+ if (!property.isMultiple())
+ return new SimpleScalar(property.getString());
+ Value[] values = property.getValues();
+ StringBuilder sb = new StringBuilder();
+ for (Value value : values) {
+ sb.append(value.getString()).append('\n');
+ }
+ return new SimpleScalar(sb.toString());
+ }
+
+ class PropertiesModel implements TemplateHashModelEx2 {
+ @Override
+ public TemplateModel get(String key) throws TemplateModelException {
+ return JcrModel.this.get(key);
+ }
+
+ @Override
+ public boolean isEmpty() throws TemplateModelException {
+ return false;
+ }
+
+ @Override
+ public TemplateCollectionModel keys() throws TemplateModelException {
+ try {
+ PropertyIterator pit = node.getProperties();
+ return new TemplateCollectionModel() {
+
+ @Override
+ public TemplateModelIterator iterator() throws TemplateModelException {
+ return new TemplateModelIterator() {
+
+ @Override
+ public TemplateModel next() throws TemplateModelException {
+ try {
+ return new SimpleScalar(pit.nextProperty().getName());
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+ @Override
+ public boolean hasNext() throws TemplateModelException {
+ return pit.hasNext();
+ }
+ };
+ }
+ };
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public int size() throws TemplateModelException {
+ try {
+ PropertyIterator pit = node.getProperties();
+ return (int) pit.getSize();
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public TemplateCollectionModel values() throws TemplateModelException {
+ try {
+ PropertyIterator pit = node.getProperties();
+ return new TemplateCollectionModel() {
+
+ @Override
+ public TemplateModelIterator iterator() throws TemplateModelException {
+ return new TemplateModelIterator() {
+
+ @Override
+ public TemplateModel next() throws TemplateModelException {
+ try {
+ return propertyValues(pit.nextProperty());
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public boolean hasNext() throws TemplateModelException {
+ return pit.hasNext();
+ }
+ };
+ }
+ };
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public KeyValuePairIterator keyValuePairIterator() throws TemplateModelException {
+ try {
+ PropertyIterator pit = node.getProperties();
+ return new KeyValuePairIterator() {
+
+ @Override
+ public boolean hasNext() throws TemplateModelException {
+ return pit.hasNext();
+ }
+
+ @Override
+ public KeyValuePair next() throws TemplateModelException {
+ Property property = pit.nextProperty();
+ return new KeyValuePair() {
+
+ @Override
+ public TemplateModel getValue() throws TemplateModelException {
+ try {
+ return propertyValues(property);
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ @Override
+ public TemplateModel getKey() throws TemplateModelException {
+ try {
+ return new SimpleScalar(property.getName());
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+ };
+ }
+ };
+ } catch (RepositoryException e) {
+ throw new TemplateModelException("Cannot list properties of " + node, e);
+ }
+ }
+
+ }
}