Repository: incubator-freemarker
Updated Branches:
  refs/heads/3 b63e44880 -> 5f6a9174d


FREEMARKER-55: trying with a directive to replace spring:bind jsp tag.


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

Branch: refs/heads/3
Commit: 6709117683e29b34a6e155cac30a160f86f95745
Parents: e3e7f1e
Author: Woonsan Ko <[email protected]>
Authored: Sat Aug 26 01:17:07 2017 -0400
Committer: Woonsan Ko <[email protected]>
Committed: Sat Aug 26 01:17:07 2017 -0400

----------------------------------------------------------------------
 .../freemarker/spring/model/BindDirective.java  | 120 +++++++++++++++++++
 .../spring/web/view/FreeMarkerView.java         |  15 +++
 2 files changed, 135 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/67091176/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/BindDirective.java
----------------------------------------------------------------------
diff --git 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/BindDirective.java
 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/BindDirective.java
new file mode 100644
index 0000000..967344d
--- /dev/null
+++ 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/BindDirective.java
@@ -0,0 +1,120 @@
+/*
+ * 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;
+
+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.ObjectWrapper;
+import org.apache.freemarker.core.model.TemplateDirectiveModel;
+import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.model.impl.BeanModel;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.util.CallableUtils;
+import org.apache.freemarker.core.util.StringToIndexMap;
+import org.springframework.web.servlet.support.BindStatus;
+import org.springframework.web.servlet.support.RequestContext;
+import org.springframework.web.servlet.view.AbstractTemplateView;
+
+public class BindDirective implements TemplateDirectiveModel {
+
+    public static final String STATUS_VARIABLE_NAME = "status";
+
+    /**
+     * @see 
<code>org.springframework.web.servlet.tags.NestedPathTag#NESTED_PATH_VARIABLE_NAME</code>
+     */
+    private static final String NESTED_PATH_VARIABLE_NAME = "nestedPath";
+
+    private static final int PATH_PARAM_IDX = 0;
+    private static final int IGNORE_NESTED_PATH_PARAM_IDX = 1;
+
+    private static final String IGNORE_NESTED_PATH_PARAM_NAME = 
"ignoreNestedPath";
+
+    private static final ArgumentArrayLayout ARGS_LAYOUT = 
ArgumentArrayLayout.create(
+            1,
+            true,
+            StringToIndexMap.of(
+                    IGNORE_NESTED_PATH_PARAM_NAME, IGNORE_NESTED_PATH_PARAM_IDX
+            ),
+            false
+    );
+
+    private final HttpServletRequest request;
+    private final HttpServletResponse response;
+
+    public BindDirective(HttpServletRequest request, HttpServletResponse 
response) {
+        this.request = request;
+        this.response = response;
+    }
+
+    @Override
+    public void execute(TemplateModel[] args, CallPlace callPlace, Writer out, 
Environment env)
+            throws TemplateException, IOException {
+        final ObjectWrapper objectWrapper = env.getObjectWrapper();
+
+        if (!(objectWrapper instanceof DefaultObjectWrapper)) {
+            throw new TemplateException("The ObjectWrapper of environment 
wasn't instance of " + DefaultObjectWrapper.class.getName());
+        }
+
+        TemplateModel model = 
env.getDataModel().get(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE);
+        RequestContext requestContext = (RequestContext) 
((DefaultObjectWrapper) objectWrapper).unwrap(model);
+
+        String resolvedPath = CallableUtils.getStringArgument(args, 
PATH_PARAM_IDX, this);
+        boolean ignoreNestedPath = 
CallableUtils.getOptionalBooleanArgument(args, IGNORE_NESTED_PATH_PARAM_IDX, 
this,
+                false);
+
+        if (!ignoreNestedPath) {
+            resolvedPath = resolveNestedPath(resolvedPath);
+        }
+
+        BindStatus status = requestContext.getBindStatus(resolvedPath);
+        env.setLocalVariable(STATUS_VARIABLE_NAME, new BeanModel(status, 
(DefaultObjectWrapper) objectWrapper));
+
+        callPlace.executeNestedContent(null, out, env);
+    }
+
+    @Override
+    public boolean isNestedContentSupported() {
+        return true;
+    }
+
+    @Override
+    public ArgumentArrayLayout getDirectiveArgumentArrayLayout() {
+        return ARGS_LAYOUT;
+    }
+
+    private String resolveNestedPath(final String path) {
+        String nestedPath = (String) 
request.getAttribute(NESTED_PATH_VARIABLE_NAME);
+
+        if (nestedPath != null && !path.startsWith(nestedPath)
+                && !path.equals(nestedPath.substring(0, nestedPath.length() - 
1))) {
+            return nestedPath + path;
+        }
+
+        return path;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/67091176/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreeMarkerView.java
----------------------------------------------------------------------
diff --git 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreeMarkerView.java
 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreeMarkerView.java
index e827db5..1e94a97 100644
--- 
a/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreeMarkerView.java
+++ 
b/freemarker-spring/src/main/java/org/apache/freemarker/spring/web/view/FreeMarkerView.java
@@ -25,15 +25,20 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
+import org.apache.freemarker.core.model.ObjectWrapper;
 import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
 import org.apache.freemarker.core.model.TemplateHashModel;
+import org.apache.freemarker.core.model.TemplateHashModelEx2;
+import org.apache.freemarker.core.model.impl.SimpleHash;
 import org.apache.freemarker.servlet.AllHttpScopesHashModel;
 import org.apache.freemarker.servlet.FreemarkerServlet;
 import org.apache.freemarker.servlet.HttpRequestHashModel;
 import org.apache.freemarker.servlet.HttpRequestParametersHashModel;
 import org.apache.freemarker.servlet.HttpSessionHashModel;
+import org.apache.freemarker.servlet.IncludePage;
 import org.apache.freemarker.servlet.ServletContextHashModel;
 import org.apache.freemarker.servlet.jsp.TaglibFactory;
+import org.apache.freemarker.spring.model.BindDirective;
 
 /**
  * FreeMarker template based view implementation, with being able to provide a 
{@link ServletContextHashModel}
@@ -134,6 +139,10 @@ public class FreeMarkerView extends AbstractFreeMarkerView 
{
 
         model.putUnlistedModel(FreemarkerServlet.KEY_JSP_TAGLIBS, 
getTaglibFactory());
 
+        model.putUnlistedModel(FreemarkerServlet.KEY_INCLUDE, new 
IncludePage(request, response));
+
+        model.putUnlistedModel("spring", 
createSpringCallableHashModel(objectWrapper, request, response));
+
         model.putAll(map);
 
         return model;
@@ -165,4 +174,10 @@ public class FreeMarkerView extends AbstractFreeMarkerView 
{
         return sessionModel;
     }
 
+    private TemplateHashModelEx2 createSpringCallableHashModel(final 
ObjectWrapper objectWrapper,
+            final HttpServletRequest request, final HttpServletResponse 
response) {
+        final SimpleHash springCallableHash = new SimpleHash(objectWrapper);
+        springCallableHash.put("bind", new BindDirective(request, response));
+        return springCallableHash;
+    }
 }

Reply via email to