summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/ui/LoginForm.java
diff options
context:
space:
mode:
authorHenri Sara <henri.sara@itmill.com>2009-05-11 09:19:03 +0000
committerHenri Sara <henri.sara@itmill.com>2009-05-11 09:19:03 +0000
commitadc8c0ad3573272c236040c3a76005b9e73a5737 (patch)
treea3860704dbd5b82dc6af38684b80f8ef79a32722 /src/com/vaadin/ui/LoginForm.java
parent5abc870dda584d0c2fc47fd5eec4ae3de3fa240e (diff)
downloadvaadin-framework-adc8c0ad3573272c236040c3a76005b9e73a5737.tar.gz
vaadin-framework-adc8c0ad3573272c236040c3a76005b9e73a5737.zip
#2904: initial bulk rename "com.itmill.toolkit" -> "com.vaadin"
- com.itmill.toolkit.external not yet fully renamed svn changeset:7715/svn branch:6.0
Diffstat (limited to 'src/com/vaadin/ui/LoginForm.java')
-rw-r--r--src/com/vaadin/ui/LoginForm.java260
1 files changed, 260 insertions, 0 deletions
diff --git a/src/com/vaadin/ui/LoginForm.java b/src/com/vaadin/ui/LoginForm.java
new file mode 100644
index 0000000000..3d3aeaf8b7
--- /dev/null
+++ b/src/com/vaadin/ui/LoginForm.java
@@ -0,0 +1,260 @@
+package com.vaadin.ui;
+
+import java.io.ByteArrayInputStream;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.vaadin.Application;
+import com.vaadin.terminal.ApplicationResource;
+import com.vaadin.terminal.DownloadStream;
+import com.vaadin.terminal.ParameterHandler;
+import com.vaadin.terminal.URIHandler;
+
+/**
+ * LoginForm is a Toolkit component to handle common problem among Ajax
+ * applications: browsers password managers don't fill dynamically created forms
+ * like all those UI elements created by IT Mill Toolkit.
+ * <p>
+ * For developer it is easy to use: add component to a desired place in you UI
+ * and add LoginListener to validate form input. Behind the curtain LoginForm
+ * creates an iframe with static html that browsers detect.
+ * <p>
+ * Login form is by default 100% width and height, so consider using it inside a
+ * sized {@link Panel} or {@link Window}.
+ * <p>
+ * Login page html can be overridden by replacing protected getLoginHTML method.
+ * As the login page is actually an iframe, styles must be handled manually. By
+ * default component tries to guess the right place for theme css.
+ * <p>
+ * Note, this is a new Ajax terminal specific component and is likely to change.
+ *
+ * @since 5.3
+ */
+@SuppressWarnings("serial")
+public class LoginForm extends CustomComponent {
+
+ private Embedded iframe = new Embedded();
+
+ private ApplicationResource loginPage = new ApplicationResource() {
+
+ public Application getApplication() {
+ return LoginForm.this.getApplication();
+ }
+
+ public int getBufferSize() {
+ return getLoginHTML().length;
+ }
+
+ public long getCacheTime() {
+ return -1;
+ }
+
+ public String getFilename() {
+ return "login";
+ }
+
+ public DownloadStream getStream() {
+ return new DownloadStream(new ByteArrayInputStream(getLoginHTML()),
+ getMIMEType(), getFilename());
+ }
+
+ public String getMIMEType() {
+ return "text/html";
+ }
+ };
+
+ private ParameterHandler paramHandler = new ParameterHandler() {
+
+ public void handleParameters(Map parameters) {
+ if (parameters.containsKey("username")) {
+ getWindow().addURIHandler(uriHandler);
+
+ HashMap params = new HashMap();
+ // expecting single params
+ for (Iterator it = parameters.keySet().iterator(); it.hasNext();) {
+ String key = (String) it.next();
+ String value = ((String[]) parameters.get(key))[0];
+ params.put(key, value);
+ }
+ LoginEvent event = new LoginEvent(params);
+ fireEvent(event);
+ }
+ }
+ };
+
+ private URIHandler uriHandler = new URIHandler() {
+ private final String responce = "<html><body>Login form handeled."
+ + "<script type='text/javascript'>top.itmill.forceSync();"
+ + "</script></body></html>";
+
+ public DownloadStream handleURI(URL context, String relativeUri) {
+ if (relativeUri != null && relativeUri.contains("loginHandler")) {
+ if (window != null) {
+ window.removeURIHandler(this);
+ }
+ DownloadStream downloadStream = new DownloadStream(
+ new ByteArrayInputStream(responce.getBytes()),
+ "text/html", "loginSuccesfull");
+ downloadStream.setCacheTime(-1);
+ return downloadStream;
+ } else {
+ return null;
+ }
+ }
+ };
+
+ private Window window;
+
+ public LoginForm() {
+ iframe.setType(Embedded.TYPE_BROWSER);
+ iframe.setSizeFull();
+ setSizeFull();
+ setCompositionRoot(iframe);
+ }
+
+ /**
+ * Returns byte array containing login page html. If you need to override
+ * the login html, use the default html as basis. Login page sets its target
+ * with javascript.
+ *
+ * @return byte array containing login page html
+ */
+ protected byte[] getLoginHTML() {
+
+ String theme = getApplication().getMainWindow().getTheme();
+ String guessedThemeUri = getApplication().getURL() + "ITMILL/themes/"
+ + (theme == null ? "default" : theme) + "/styles.css";
+ String guessedThemeUri2 = getApplication().getURL()
+ + "../ITMILL/themes/" + (theme == null ? "default" : theme)
+ + "/styles.css";
+
+ String appUri = getApplication().getURL().toString();
+
+ return ("<!DOCTYPE html PUBLIC \"-//W3C//DTD "
+ + "XHTML 1.0 Transitional//EN\" "
+ + "\"http://www.w3.org/TR/xhtml1/"
+ + "DTD/xhtml1-transitional.dtd\">\n" + "<html>"
+ + "<head><script type='text/javascript'>"
+ + "var setTarget = function() {" + "var uri = '"
+ + appUri
+ + "loginHandler"
+ + "'; var f = document.getElementById('loginf');"
+ + "document.forms[0].action = uri;document.forms[0].username.focus();};"
+ + "</script>"
+ + "<link rel='stylesheet' href='"
+ + guessedThemeUri
+ + "'/>"
+ + "<link rel='stylesheet' href='"
+ + guessedThemeUri2
+ + "'/>"
+ + "</head><body onload='setTarget();' style='margin:0;padding:0;'>"
+ + "<div class='i-app i-app-loginpage'>"
+ + "<iframe name='logintarget' style='width:0;height:0;"
+ + "border:0;margin:0;padding:0;'></iframe>"
+ + "<form id='loginf' target='logintarget'>"
+ + "<div>Username</div><div >"
+ + "<input class='i-textfield' style='display:block;' type='text' name='username'></div>"
+ + "<div>Password</div>"
+ + "<div><input class='i-textfield' style='display:block;' type='password' name='password'></div>"
+ + "<div><input class='i-button' type='submit' value='Login'></div></form></div>" + "</body></html>")
+ .getBytes();
+ }
+
+ @Override
+ public void attach() {
+ super.attach();
+ getApplication().addResource(loginPage);
+ getWindow().addParameterHandler(paramHandler);
+ iframe.setSource(loginPage);
+ }
+
+ @Override
+ public void detach() {
+ getApplication().removeResource(loginPage);
+ getWindow().removeParameterHandler(paramHandler);
+ // store window temporary to properly remove uri handler once
+ // response is handled. (May happen if login handler removes login
+ // form
+ window = getWindow();
+ if (window.getParent() != null) {
+ window = (Window) window.getParent();
+ }
+ super.detach();
+ }
+
+ /**
+ * This event is sent when login form is submitted.
+ */
+ public class LoginEvent extends Event {
+
+ private Map params;
+
+ private LoginEvent(Map params) {
+ super(LoginForm.this);
+ this.params = params;
+ }
+
+ /**
+ * Access method to form values by field names.
+ *
+ * @param name
+ * @return value in given field
+ */
+ public String getLoginParameter(String name) {
+ if (params.containsKey(name)) {
+ return (String) params.get(name);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Login listener is a class capable to listen LoginEvents sent from
+ * LoginBox
+ */
+ public interface LoginListener extends Serializable {
+ /**
+ * This method is fired on each login form post.
+ *
+ * @param event
+ */
+ public void onLogin(LoginForm.LoginEvent event);
+ }
+
+ private static final Method ON_LOGIN_METHOD;
+
+ static {
+ try {
+ ON_LOGIN_METHOD = LoginListener.class.getDeclaredMethod("onLogin",
+ new Class[] { LoginEvent.class });
+ } catch (final java.lang.NoSuchMethodException e) {
+ // This should never happen
+ throw new java.lang.RuntimeException(
+ "Internal error finding methods in LoginForm");
+ }
+ }
+
+ /**
+ * Adds LoginListener to handle login logic
+ *
+ * @param listener
+ */
+ public void addListener(LoginListener listener) {
+ addListener(LoginEvent.class, listener, ON_LOGIN_METHOD);
+ }
+
+ /**
+ * Removes LoginListener
+ *
+ * @param listener
+ */
+ public void removeListener(LoginListener listener) {
+ removeListener(LoginEvent.class, listener, ON_LOGIN_METHOD);
+ }
+
+}