--- /dev/null
+<?xml version="1.0"?>\r
+<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 4.0.0//EN" "http://www.liferay.com/dtd/liferay-display_4_0_0.dtd">\r
+\r
+<display>\r
+ <category name="IT Mill Toolkit">\r
+ <portlet id="ApplicationPortlet" />\r
+ </category>\r
+</display>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>\r
+<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 4.3.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_4_3_0.dtd">\r
+\r
+<liferay-portlet-app>\r
+\r
+ <portlet>\r
+ <portlet-name>ApplicationPortlet</portlet-name>\r
+ <instanceable>true</instanceable> \r
+ <ajaxable>false</ajaxable>\r
+ </portlet>\r
+ \r
+ <role-mapper>\r
+ <role-name>administrator</role-name>\r
+ <role-link>Administrator</role-link>\r
+ </role-mapper>\r
+ <role-mapper>\r
+ <role-name>guest</role-name>\r
+ <role-link>Guest</role-link>\r
+ </role-mapper>\r
+ <role-mapper>\r
+ <role-name>power-user</role-name>\r
+ <role-link>Power User</role-link>\r
+ </role-mapper>\r
+ <role-mapper>\r
+ <role-name>user</role-name>\r
+ <role-link>User</role-link>\r
+ </role-mapper>\r
+ \r
+</liferay-portlet-app>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<portlet-app\r
+ xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"\r
+ version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">\r
+\r
+ <portlet>\r
+ <portlet-name>ApplicationPortlet</portlet-name>\r
+ <display-name>IT Mill Toolkit Portlet</display-name>\r
+ <portlet-class>com.itmill.toolkit.terminal.gwt.server.ApplicationPortlet</portlet-class>\r
+ <supports>\r
+ <mime-type>text/html</mime-type>\r
+ <portlet-mode>view</portlet-mode>\r
+ <portlet-mode>edit</portlet-mode>\r
+ <portlet-mode>help</portlet-mode>\r
+ </supports>\r
+ <portlet-info>\r
+ <title>IT Mill Toolkit ApplicationPortlet</title>\r
+ <short-title>ApplicationPortlet</short-title>\r
+ </portlet-info>\r
+ \r
+ <security-role-ref>\r
+ <role-name>administrator</role-name>\r
+ </security-role-ref>\r
+ <security-role-ref>\r
+ <role-name>guest</role-name>\r
+ </security-role-ref>\r
+ <security-role-ref>\r
+ <role-name>power-user</role-name>\r
+ </security-role-ref>\r
+ <security-role-ref>\r
+ <role-name>user</role-name>\r
+ </security-role-ref>\r
+ </portlet>\r
+\r
+</portlet-app>
\ No newline at end of file
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.server;\r
+\r
+import java.io.IOException;\r
+import java.io.PrintWriter;\r
+import java.util.Map;\r
+\r
+import javax.portlet.ActionRequest;\r
+import javax.portlet.ActionResponse;\r
+import javax.portlet.Portlet;\r
+import javax.portlet.PortletConfig;\r
+import javax.portlet.PortletException;\r
+import javax.portlet.PortletMode;\r
+import javax.portlet.PortletModeException;\r
+import javax.portlet.PortletPreferences;\r
+import javax.portlet.PortletRequest;\r
+import javax.portlet.PortletRequestDispatcher;\r
+import javax.portlet.PortletSession;\r
+import javax.portlet.PortletURL;\r
+import javax.portlet.RenderRequest;\r
+import javax.portlet.RenderResponse;\r
+\r
+import com.itmill.toolkit.Application;\r
+import com.itmill.toolkit.terminal.gwt.server.PortletApplicationContext.PortletInfo;\r
+import com.itmill.toolkit.terminal.gwt.server.PortletApplicationContext.PortletInfoReceiver;\r
+\r
+public class ApplicationPortlet implements Portlet {\r
+ // The application to show\r
+ protected String app = "Calc"; // empty for root\r
+ // theme to use for the application\r
+ protected String theme = "default";\r
+ // some applications might require that the height is specified\r
+ protected String height = null; // e.g "200px"\r
+\r
+ PortletConfig config;\r
+\r
+ public void destroy() {\r
+ config = null;\r
+ }\r
+\r
+ public void init(PortletConfig config) throws PortletException {\r
+ this.config = config;\r
+ }\r
+\r
+ public void processAction(ActionRequest request, ActionResponse response)\r
+ throws PortletException, IOException {\r
+ // Update preferences (configured)\r
+ PortletPreferences prefs = request.getPreferences();\r
+ app = request.getParameter("app");\r
+ if (app != null && app.length() > 0) {\r
+ prefs.setValue("application", app);\r
+ } else {\r
+ app = null;\r
+ }\r
+ String theme = request.getParameter("theme");\r
+ if (theme != null && theme.length() > 0) {\r
+ prefs.setValue("theme", theme);\r
+ } else {\r
+ prefs.setValue("theme", null);\r
+ }\r
+ String height = request.getParameter("height");\r
+ if (height != null && height.length() > 0) {\r
+ prefs.setValue("height", height);\r
+ } else {\r
+ prefs.setValue("height", null);\r
+ }\r
+ prefs.store();\r
+ }\r
+\r
+ public void render(RenderRequest request, RenderResponse response)\r
+ throws PortletException, IOException {\r
+\r
+ PortletPreferences prefs = request.getPreferences();\r
+ app = prefs.getValue("application", app);\r
+ theme = prefs.getValue("theme", "default");\r
+ height = prefs.getValue("height", null);\r
+\r
+ // display the IT Mill Toolkit application\r
+ writeAjaxWindow(request, response);\r
+ }\r
+\r
+ protected void writeAjaxWindow(RenderRequest request,\r
+ RenderResponse response) throws IOException {\r
+\r
+ response.setContentType("text/html");\r
+ PrintWriter out = response.getWriter();\r
+\r
+ // TODO check user == admin\r
+ if (app == null) {\r
+ // Display the configuration UI\r
+ PortletURL submitUrl = response.createActionURL();\r
+ try {\r
+ submitUrl.setPortletMode(PortletMode.VIEW);\r
+ } catch (PortletModeException e) {\r
+ // Fine\r
+ }\r
+ out.println("<form method='POST' action='" + submitUrl + "'>");\r
+ out.println("Application:");\r
+ out.println(request.getContextPath() + "/");\r
+ out.println("<input size='40' type='text' name='app' value='"\r
+ + (app != null ? app : "") + "'>");\r
+ out.println(" Theme:<input type='text' name='theme' value='"\r
+ + theme + "'><br/>");\r
+ out\r
+ .println("Force height (optional, e.g \"200px\"): <input type='text' name='height' value='"\r
+ + (height != null ? height : "") + "'><br/>");\r
+ out.println("<input type='submit' value='Save'>");\r
+ out.println("</form>");\r
+ } else {\r
+\r
+ PortletSession sess = request.getPortletSession();\r
+ PortletApplicationContext ctx = PortletApplicationContext\r
+ .getApplicationContext(sess);\r
+\r
+ PortletInfo pi = ctx.setPortletInfo(request.getContextPath() + "/"\r
+ + app + (app.endsWith("/") ? "" : "/"), request\r
+ .getPortletMode(), request.getWindowState(), request\r
+ .getUserPrincipal(), (Map) request\r
+ .getAttribute(PortletRequest.USER_INFO), config);\r
+\r
+ PortletRequestDispatcher dispatcher = sess.getPortletContext()\r
+ .getRequestDispatcher("/" + app);\r
+\r
+ try {\r
+ dispatcher.include(request, response);\r
+ } catch (PortletException e) {\r
+ out.print("<h1>Servlet include failed!</h1>");\r
+ out.print("<div>" + e + "</div>");\r
+ return;\r
+ }\r
+\r
+ Object app = request.getAttribute(Application.class.getName());\r
+ if (app instanceof PortletInfoReceiver) {\r
+ ((PortletInfoReceiver) app).receivePortletInfo(pi);\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/**\r
+ * \r
+ */\r
+package com.itmill.toolkit.terminal.gwt.server;\r
+\r
+import java.io.File;\r
+import java.security.Principal;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import javax.portlet.PortletConfig;\r
+import javax.portlet.PortletMode;\r
+import javax.portlet.PortletSession;\r
+import javax.portlet.WindowState;\r
+import javax.servlet.http.HttpSession;\r
+\r
+import com.itmill.toolkit.Application;\r
+import com.itmill.toolkit.service.ApplicationContext;\r
+\r
+/**\r
+ * @author marc\r
+ * \r
+ */\r
+public class PortletApplicationContext implements ApplicationContext {\r
+\r
+ private final PortletSession session;\r
+\r
+ private final Map portletInfoMap;\r
+\r
+ PortletApplicationContext(PortletSession session) {\r
+ this.session = session;\r
+ portletInfoMap = new HashMap();\r
+ }\r
+\r
+ static public PortletApplicationContext getApplicationContext(\r
+ PortletSession session) {\r
+ PortletApplicationContext cx = (PortletApplicationContext) session\r
+ .getAttribute(PortletApplicationContext.class.getName());\r
+ if (cx == null) {\r
+ cx = new PortletApplicationContext(session);\r
+ session.setAttribute(PortletApplicationContext.class.getName(), cx,\r
+ PortletSession.APPLICATION_SCOPE);\r
+ }\r
+ return cx;\r
+ }\r
+\r
+ static public PortletApplicationContext getApplicationContext(\r
+ HttpSession session) {\r
+ PortletApplicationContext cx = (PortletApplicationContext) session\r
+ .getAttribute(PortletApplicationContext.class.getName());\r
+ return cx;\r
+ }\r
+\r
+ public PortletSession getPortletSession() {\r
+ return session;\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * \r
+ * @see com.itmill.toolkit.service.ApplicationContext#addTransactionListener(com.itmill.toolkit.service.ApplicationContext.TransactionListener)\r
+ */\r
+ public void addTransactionListener(TransactionListener listener) {\r
+ WebApplicationContext cx = (WebApplicationContext) session\r
+ .getAttribute(WebApplicationContext.class.getName());\r
+ if (cx != null) {\r
+ cx.addTransactionListener(listener);\r
+ }\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * \r
+ * @see com.itmill.toolkit.service.ApplicationContext#getApplications()\r
+ */\r
+ public Collection getApplications() {\r
+ WebApplicationContext cx = (WebApplicationContext) session\r
+ .getAttribute(WebApplicationContext.class.getName());\r
+ if (cx != null) {\r
+ return cx.getApplications();\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * \r
+ * @see com.itmill.toolkit.service.ApplicationContext#getBaseDirectory()\r
+ */\r
+ public File getBaseDirectory() {\r
+ WebApplicationContext cx = (WebApplicationContext) session\r
+ .getAttribute(WebApplicationContext.class.getName());\r
+ if (cx != null) {\r
+ return cx.getBaseDirectory();\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /*\r
+ * (non-Javadoc)\r
+ * \r
+ * @see com.itmill.toolkit.service.ApplicationContext#removeTransactionListener(com.itmill.toolkit.service.ApplicationContext.TransactionListener)\r
+ */\r
+ public void removeTransactionListener(TransactionListener listener) {\r
+ WebApplicationContext cx = (WebApplicationContext) session\r
+ .getAttribute(WebApplicationContext.class.getName());\r
+ if (cx != null) {\r
+ cx.removeTransactionListener(listener);\r
+ }\r
+ }\r
+\r
+ PortletInfo setPortletInfo(String path, PortletMode mode,\r
+ WindowState state, Principal userPrincipal, Map userInfo,\r
+ PortletConfig config) {\r
+ System.err.println("SETTING PI: " + path);\r
+ PortletInfo pi = (PortletInfo) portletInfoMap.get(path);\r
+ if (pi == null) {\r
+ pi = new PortletInfo(mode, state, userPrincipal, userInfo, config);\r
+ portletInfoMap.put(path, pi);\r
+ } else {\r
+ pi.setInfo(mode, state, userPrincipal, userInfo, config);\r
+ }\r
+ return pi;\r
+ }\r
+\r
+ public PortletInfo getPortletInfo(Application app) {\r
+ if (app != null && app.getURL() != null) {\r
+ // TODO remove\r
+ System.err.println("GETTING PI: " + app.getURL().getPath());\r
+ return (PortletInfo) portletInfoMap.get(app.getURL().getPath());\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public class PortletInfo {\r
+\r
+ PortletMode mode;\r
+ WindowState state;\r
+ Principal userPrincipal;\r
+ Map userInfo;\r
+ PortletConfig config;\r
+\r
+ public PortletInfo(PortletMode mode, WindowState state,\r
+ Principal userPrincipal, Map userInfo, PortletConfig config) {\r
+ this.mode = mode;\r
+ this.state = state;\r
+ this.userPrincipal = userPrincipal;\r
+ this.userInfo = userInfo;\r
+ this.config = config;\r
+ }\r
+\r
+ private void setInfo(PortletMode mode, WindowState state,\r
+ Principal userPrincipal, Map userInfo, PortletConfig config) {\r
+ this.mode = mode;\r
+ this.state = state;\r
+ this.userPrincipal = userPrincipal;\r
+ this.userInfo = userInfo;\r
+ this.config = config;\r
+ }\r
+\r
+ /**\r
+ * Gets the current portlet mode, VIEW / EDIT / HELP\r
+ * \r
+ * @return the current portlet mode\r
+ */\r
+ public PortletMode getPortletMode() {\r
+ return mode;\r
+ }\r
+\r
+ /**\r
+ * Gets the current window state, NORMAL / MAXIMIZED / MINIMIZED\r
+ * \r
+ * @return the current window state\r
+ */\r
+ public WindowState getWindowState() {\r
+ return state;\r
+ }\r
+\r
+ /**\r
+ * Gets the current UserPrincipal\r
+ * \r
+ * @return current UserPrincipal, null if not logged in\r
+ */\r
+ public Principal getUserPrincipal() {\r
+ return userPrincipal;\r
+ }\r
+\r
+ /**\r
+ * Gets the PortletConfig for this portlet\r
+ * \r
+ * @return the PortletConfig\r
+ */\r
+ public PortletConfig getConfig() {\r
+ return config;\r
+ }\r
+\r
+ /**\r
+ * Gets the user info for this portlet, as retreived from\r
+ * request.getAttribute(PortletRequest.USER_INFO);\r
+ * \r
+ * @return the user info Map\r
+ */\r
+ public Map getUserInfo() {\r
+ return userInfo;\r
+ }\r
+\r
+ public String toString() {\r
+ return "PortletMode: " + getPortletMode() + " WindowState: "\r
+ + getWindowState() + " UserPrincipal: "\r
+ + getUserPrincipal() + " User info: " + getUserInfo();\r
+ }\r
+ }\r
+\r
+ public interface PortletInfoReceiver {\r
+ public void receivePortletInfo(PortletInfo info);\r
+ }\r
+}\r