freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From woon...@apache.org
Subject incubator-freemarker git commit: FREEMARKER-55: Adding form.password directive
Date Thu, 25 Jan 2018 00:34:21 GMT
Repository: incubator-freemarker
Updated Branches:
  refs/heads/3 486dc6229 -> 3ec52aaa0


FREEMARKER-55: Adding form.password directive


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/3ec52aaa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/3ec52aaa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/3ec52aaa

Branch: refs/heads/3
Commit: 3ec52aaa056361bf1e806ed6e3b27f81b456baa4
Parents: 486dc62
Author: Woonsan Ko <woonsan@apache.org>
Authored: Wed Jan 24 19:34:10 2018 -0500
Committer: Woonsan Ko <woonsan@apache.org>
Committed: Wed Jan 24 19:34:10 2018 -0500

----------------------------------------------------------------------
 FM3-CHANGE-LOG.txt                              |   1 +
 ...tHtmlInputElementTemplateDirectiveModel.java |   3 +
 .../model/form/FormTemplateDirectiveModel.java  |   1 -
 .../model/form/InputTemplateDirectiveModel.java |  12 +-
 .../PasswordInputTemplateDirectiveModel.java    | 124 +++++++++++++++++++
 .../SpringFormTemplateCallableHashModel.java    |   1 +
 .../example/mvc/users/UserRepository.java       |   2 +
 ...PasswordInputTemplateDirectiveModelTest.java |  71 +++++++++++
 .../form/password-input-directive-usages.ftlh   |  64 ++++++++++
 9 files changed, 276 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3ec52aaa/FM3-CHANGE-LOG.txt
----------------------------------------------------------------------
diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt
index 42fbf68..30a86c6 100644
--- a/FM3-CHANGE-LOG.txt
+++ b/FM3-CHANGE-LOG.txt
@@ -524,6 +524,7 @@ models by default like FreemarkerServlet does.
 - Directives Support to replace Spring Form JSP Tag Libraries in spring-form.tld:
   - <form:form ... /> : Replaced by <@form.form ... /> directive.
   - <form:input ... /> : Replaced by <@form.input ... /> directive.
+  - <form:password ... /> : Replaced by <@form.password ... /> directive.
 
 Core / Miscellaneous
 ....................

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3ec52aaa/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java
index 6399cbb..83bee50 100644
--- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/AbstractHtmlInputElementTemplateDirectiveModel.java
@@ -35,6 +35,9 @@ import org.apache.freemarker.core.util.CallableUtils;
 import org.apache.freemarker.core.util.StringToIndexMap;
 import org.springframework.web.servlet.support.RequestContext;
 
+/**
+ * Corresponds to <code>org.springframework.web.servlet.tags.form.AbstractHtmlInputElementTag</code>.
+ */
 abstract class AbstractHtmlInputElementTemplateDirectiveModel extends AbstractHtmlElementTemplateDirectiveModel
{
 
     private static final int NAMED_ARGS_OFFSET = AbstractHtmlElementTemplateDirectiveModel.ARGS_LAYOUT

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3ec52aaa/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java
index 9274603..c8b72c7 100644
--- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/FormTemplateDirectiveModel.java
@@ -60,7 +60,6 @@ import org.springframework.web.util.UriUtils;
  * Some valid example(s):
  * </P>
  * <PRE>
- * &lt;#assign form=spring.form /&gt;
  * &lt;@form.form "user"&gt;
  *   &lt;div&gt;First name: &lt;@form.input 'firstName' /&gt;&lt;/div&gt;
  * &lt;/@form.form&gt;

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3ec52aaa/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java
index d4c6da4..f111704 100644
--- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/InputTemplateDirectiveModel.java
@@ -51,8 +51,6 @@ import org.springframework.web.servlet.support.RequestContext;
  * Some valid example(s):
  * </P>
  * <PRE>
- *   &lt;#assign form=spring.form /&gt;
- *   ...
  *   &lt;@form.input 'user.firstName' /&gt;
  *   
  *   &lt;@form.input 'user.email' id="customEmailId" /&gt;
@@ -190,4 +188,14 @@ class InputTemplateDirectiveModel extends AbstractHtmlInputElementTemplateDirect
         return "text";
     }
 
+    @Override
+    protected boolean isValidDynamicAttribute(String localName, Object value) {
+        if ("type".equals(localName)) {
+            if ("checkbox".equals(value) || "radio".equals(value)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3ec52aaa/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/PasswordInputTemplateDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/PasswordInputTemplateDirectiveModel.java
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/PasswordInputTemplateDirectiveModel.java
new file mode 100644
index 0000000..52729e1
--- /dev/null
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/PasswordInputTemplateDirectiveModel.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.freemarker.spring.model.form;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.freemarker.core.CallPlace;
+import org.apache.freemarker.core.Environment;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.ArgumentArrayLayout;
+import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.util.CallableUtils;
+import org.apache.freemarker.core.util.StringToIndexMap;
+import org.springframework.web.servlet.support.RequestContext;
+
+/**
+ * Provides <code>TemplateModel</code> for data-binding-aware HTML '{@code input}'
element with a '{@code type}'
+ * of '{@code password}'.
+ * <P>
+ * This directive supports the following parameters:
+ * <UL>
+ * <LI><code>path</code>: The first positional parameter pointing to the
bean or bean property to bind status information for.</LI>
+ * <LI>
+ *   ... TODO ...
+ * </LI>
+ * </UL>
+ * </P>
+ * <P>
+ * Some valid example(s):
+ * </P>
+ * <PRE>
+ *   &lt;@form.password 'user.password' /&gt;
+ * </PRE>
+ * <P>
+ * <EM>Note:</EM> Unlike Spring Framework's <code>&lt;form:password
/&gt;</code> JSP Tag Library, this directive
+ * does not support <code>htmlEscape</code> parameter. It always renders HTML's
without escaping
+ * because it is much easier to control escaping in FreeMarker Template expressions.
+ * </P>
+ */
+
+class PasswordInputTemplateDirectiveModel extends InputTemplateDirectiveModel {
+
+    public static final String NAME = "password";
+
+    private static final int NAMED_ARGS_OFFSET = InputTemplateDirectiveModel.ARGS_LAYOUT
+            .getPredefinedNamedArgumentsEndIndex();
+
+    private static final int SHOW_PASSWORD_PARAM_IDX = NAMED_ARGS_OFFSET;
+    private static final String SHOW_PASSWORD_PARAM_NAME = "showPassword";
+
+    protected static final ArgumentArrayLayout ARGS_LAYOUT =
+            ArgumentArrayLayout.create(
+                    1,
+                    false,
+                    StringToIndexMap.of(InputTemplateDirectiveModel.ARGS_LAYOUT.getPredefinedNamedArgumentsMap(),
+                            new StringToIndexMap.Entry(SHOW_PASSWORD_PARAM_NAME, SHOW_PASSWORD_PARAM_IDX)
+                            ),
+                    true);
+
+    private boolean showPassword;
+
+    protected PasswordInputTemplateDirectiveModel(HttpServletRequest request, HttpServletResponse
response) {
+        super(request, response);
+    }
+
+    @Override
+    public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
+        return ARGS_LAYOUT;
+    }
+
+    @Override
+    protected void executeInternal(TemplateModel[] args, CallPlace callPlace, Writer out,
Environment env,
+            ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper, RequestContext requestContext)
+            throws TemplateException, IOException {
+        showPassword = CallableUtils.getOptionalBooleanArgument(args, SHOW_PASSWORD_PARAM_IDX,
this, false);
+        super.executeInternal(args, callPlace, out, env, objectWrapperAndUnwrapper, requestContext);
+    }
+
+    public boolean isShowPassword() {
+        return showPassword;
+    }
+
+    @Override
+    protected String getType() {
+        return "password";
+    }
+
+    @Override
+    protected void writeValue(Environment env, TagOutputter tagOut) throws TemplateException,
IOException {
+        if (isShowPassword()) {
+            super.writeValue(env, tagOut);
+        } else {
+            tagOut.writeAttribute("value", processFieldValue(env, getName(), "", getType()));
+        }
+    }
+
+    @Override
+    protected boolean isValidDynamicAttribute(String localName, Object value) {
+        return !"type".equals(localName);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3ec52aaa/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/SpringFormTemplateCallableHashModel.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/SpringFormTemplateCallableHashModel.java
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/SpringFormTemplateCallableHashModel.java
index c7b1f5a..dde548a 100644
--- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/SpringFormTemplateCallableHashModel.java
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/form/SpringFormTemplateCallableHashModel.java
@@ -47,6 +47,7 @@ public final class SpringFormTemplateCallableHashModel implements TemplateHashMo
     public SpringFormTemplateCallableHashModel(final HttpServletRequest request, final HttpServletResponse
response) {
         modelsMap.put(FormTemplateDirectiveModel.NAME, new FormTemplateDirectiveModel(request,
response));
         modelsMap.put(InputTemplateDirectiveModel.NAME, new InputTemplateDirectiveModel(request,
response));
+        modelsMap.put(PasswordInputTemplateDirectiveModel.NAME, new PasswordInputTemplateDirectiveModel(request,
response));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3ec52aaa/freemarker-spring/src/test/java/org/apache/freemarker/spring/example/mvc/users/UserRepository.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/test/java/org/apache/freemarker/spring/example/mvc/users/UserRepository.java
b/freemarker-spring/src/test/java/org/apache/freemarker/spring/example/mvc/users/UserRepository.java
index 1f1a9e2..933b1a0 100644
--- a/freemarker-spring/src/test/java/org/apache/freemarker/spring/example/mvc/users/UserRepository.java
+++ b/freemarker-spring/src/test/java/org/apache/freemarker/spring/example/mvc/users/UserRepository.java
@@ -35,6 +35,7 @@ public class UserRepository {
         Long id = 101L;
         User user = new User(id);
         user.setEmail("john@example.com");
+        user.setPassword("johnpass");
         user.setFirstName("John");
         user.setLastName("Doe");
         Calendar birthDate = Calendar.getInstance();
@@ -47,6 +48,7 @@ public class UserRepository {
         id = 102L;
         user = new User(id);
         user.setEmail("jane@example.com");
+        user.setPassword("janepass");
         user.setFirstName("Jane");
         user.setLastName("Doe");
         birthDate = Calendar.getInstance();

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3ec52aaa/freemarker-spring/src/test/java/org/apache/freemarker/spring/model/form/PasswordInputTemplateDirectiveModelTest.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/test/java/org/apache/freemarker/spring/model/form/PasswordInputTemplateDirectiveModelTest.java
b/freemarker-spring/src/test/java/org/apache/freemarker/spring/model/form/PasswordInputTemplateDirectiveModelTest.java
new file mode 100644
index 0000000..d69adf2
--- /dev/null
+++ b/freemarker-spring/src/test/java/org/apache/freemarker/spring/model/form/PasswordInputTemplateDirectiveModelTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.freemarker.spring.model.form;
+
+import org.apache.freemarker.spring.example.mvc.users.User;
+import org.apache.freemarker.spring.example.mvc.users.UserRepository;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.xpath;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration("classpath:META-INF/web-resources")
+@ContextConfiguration(locations = { "classpath:org/apache/freemarker/spring/example/mvc/users/users-mvc-context.xml"
})
+public class PasswordInputTemplateDirectiveModelTest {
+
+    @Autowired
+    private WebApplicationContext wac;
+
+    @Autowired
+    private UserRepository userRepository;
+
+    private MockMvc mockMvc;
+
+    @Before
+    public void setUp() {
+        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
+    }
+
+    @Test
+    public void testBasicUsages() throws Exception {
+        final Long userId = userRepository.getUserIds().iterator().next();
+        final User user = userRepository.getUser(userId);
+        mockMvc.perform(get("/users/{userId}/", userId).param("viewName", "test/model/form/password-input-directive-usages")
+                .accept(MediaType.parseMediaType("text/html"))).andExpect(status().isOk())
+                .andExpect(content().contentTypeCompatibleWith("text/html")).andDo(print())
+                .andExpect(xpath("//form[@id='form1']//input[@name='password']/@value").string(""))
+                .andExpect(xpath("//form[@id='form2']//input[@name='password']/@value").string(user.getPassword()))
+                .andExpect(xpath("//form[@id='form3']//input[@name='password']/@value").string(""));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/3ec52aaa/freemarker-spring/src/test/resources/META-INF/web-resources/views/test/model/form/password-input-directive-usages.ftlh
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/test/resources/META-INF/web-resources/views/test/model/form/password-input-directive-usages.ftlh
b/freemarker-spring/src/test/resources/META-INF/web-resources/views/test/model/form/password-input-directive-usages.ftlh
new file mode 100644
index 0000000..fa59e54
--- /dev/null
+++ b/freemarker-spring/src/test/resources/META-INF/web-resources/views/test/model/form/password-input-directive-usages.ftlh
@@ -0,0 +1,64 @@
+<#--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<html>
+<body>
+
+  <h1>Form 1</h1>
+  <hr/>
+  <form id="form1">
+    <table>
+      <tr>
+        <th>Password:</th>
+        <td>
+          <@form.password 'user.password' />
+        </td>
+      </tr>
+    </table>
+  </form>
+
+  <hr/>
+
+  <h2>Testing with setting showPassword to true</h2>
+  <form id="form2">
+    <table>
+      <tr>
+        <th>Password:</th>
+        <td>
+          <@form.password 'user.password' showPassword=true />
+        </td>
+      </tr>
+    </table>
+  </form>
+
+  <hr/>
+
+  <h2>Testing with setting showPassword to false explicitly</h2>
+  <form id="form3">
+    <table>
+      <tr>
+        <th>Password:</th>
+        <td>
+          <@form.password 'user.password' showPassword=false />
+        </td>
+      </tr>
+    </table>
+  </form>
+
+</body>
+</html>


Mime
View raw message