You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/09/13 09:49:13 UTC
[12/36] incubator-freemarker git commit: Using CallableUtils to throw
exceptions; use positional param for code
Using CallableUtils to throw exceptions; use positional param for code
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/a8e73ec7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/a8e73ec7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/a8e73ec7
Branch: refs/heads/3
Commit: a8e73ec77a735b643be986e0c190205f3b7a2192
Parents: b0acedd
Author: Woonsan Ko <wo...@apache.org>
Authored: Tue Sep 5 08:33:55 2017 -0400
Committer: Woonsan Ko <wo...@apache.org>
Committed: Tue Sep 5 08:33:55 2017 -0400
----------------------------------------------------------------------
.../AbstractSpringTemplateCallableModel.java | 6 +-
.../AbstractSpringTemplateDirectiveModel.java | 17 ++++-
.../AbstractSpringTemplateFunctionModel.java | 14 +++-
.../spring/model/MessageFunction.java | 77 +++++++++++---------
.../freemarker/spring/model/ThemeFunction.java | 38 ++++++++++
.../spring/web/view/FreeMarkerView.java | 2 +
6 files changed, 112 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a8e73ec7/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java
index 431c066..b82bed1 100644
--- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateCallableModel.java
@@ -28,6 +28,7 @@ import org.apache.freemarker.core.model.ObjectWrappingException;
import org.apache.freemarker.core.model.TemplateCallableModel;
import org.apache.freemarker.core.model.TemplateModel;
import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.core.util.CallableUtils;
import org.springframework.web.servlet.support.BindStatus;
import org.springframework.web.servlet.support.RequestContext;
@@ -81,7 +82,8 @@ public abstract class AbstractSpringTemplateCallableModel implements TemplateCal
if (status != null) {
if (!(objectWrapperAndUnwrapper instanceof DefaultObjectWrapper)) {
- throw new IllegalArgumentException("objectWrapperAndUnwrapper is not a DefaultObjectWrapper.");
+ CallableUtils.newGenericExecuteException("objectWrapperAndUnwrapper is not a DefaultObjectWrapper.",
+ this, isFunction());
}
return ((DefaultObjectWrapper) objectWrapperAndUnwrapper).wrap(status);
@@ -90,6 +92,8 @@ public abstract class AbstractSpringTemplateCallableModel implements TemplateCal
return null;
}
+ protected abstract boolean isFunction();
+
private String resolveNestedPath(final Environment env, ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper,
final String path) {
// TODO: should read it from request or env??
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a8e73ec7/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java
index c4ed76c..df6a2bc 100644
--- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateDirectiveModel.java
@@ -32,13 +32,15 @@ import org.apache.freemarker.core.model.ObjectWrapper;
import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
import org.apache.freemarker.core.model.TemplateDirectiveModel;
import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.util.CallableUtils;
import org.springframework.web.servlet.support.RequestContext;
import org.springframework.web.servlet.view.AbstractTemplateView;
/**
* Abstract TemplateDirectiveModel for derived classes to support Spring MVC based templating environment.
*/
-public abstract class AbstractSpringTemplateDirectiveModel extends AbstractSpringTemplateCallableModel implements TemplateDirectiveModel {
+public abstract class AbstractSpringTemplateDirectiveModel extends AbstractSpringTemplateCallableModel
+ implements TemplateDirectiveModel {
public AbstractSpringTemplateDirectiveModel(HttpServletRequest request, HttpServletResponse response) {
super(request, response);
@@ -50,14 +52,16 @@ public abstract class AbstractSpringTemplateDirectiveModel extends AbstractSprin
final ObjectWrapper objectWrapper = env.getObjectWrapper();
if (!(objectWrapper instanceof ObjectWrapperAndUnwrapper)) {
- throw new TemplateException(
- "The ObjectWrapper of environment wasn't instance of ObjectWrapperAndUnwrapper.");
+ CallableUtils.newGenericExecuteException(
+ "The ObjectWrapper of environment isn't an instance of ObjectWrapperAndUnwrapper.", this,
+ isFunction());
}
TemplateModel rcModel = env.getVariable(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE);
if (rcModel == null) {
- throw new TemplateException(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE + " not found.");
+ CallableUtils.newGenericExecuteException(
+ AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE + " not found.", this, isFunction());
}
RequestContext requestContext = (RequestContext) ((ObjectWrapperAndUnwrapper) objectWrapper).unwrap(rcModel);
@@ -65,6 +69,11 @@ public abstract class AbstractSpringTemplateDirectiveModel extends AbstractSprin
executeInternal(args, callPlace, out, env, (ObjectWrapperAndUnwrapper) objectWrapper, requestContext);
}
+ @Override
+ protected final boolean isFunction() {
+ return false;
+ }
+
protected abstract void executeInternal(TemplateModel[] args, CallPlace callPlace, Writer out, Environment env,
ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper, RequestContext requestContext)
throws TemplateException, IOException;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a8e73ec7/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java
index c0fe502..7851ad8 100644
--- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/AbstractSpringTemplateFunctionModel.java
@@ -29,6 +29,7 @@ import org.apache.freemarker.core.model.ObjectWrapper;
import org.apache.freemarker.core.model.ObjectWrapperAndUnwrapper;
import org.apache.freemarker.core.model.TemplateFunctionModel;
import org.apache.freemarker.core.model.TemplateModel;
+import org.apache.freemarker.core.util.CallableUtils;
import org.springframework.web.servlet.support.RequestContext;
import org.springframework.web.servlet.view.AbstractTemplateView;
@@ -47,14 +48,16 @@ public abstract class AbstractSpringTemplateFunctionModel extends AbstractSpring
final ObjectWrapper objectWrapper = env.getObjectWrapper();
if (!(objectWrapper instanceof ObjectWrapperAndUnwrapper)) {
- throw new TemplateException(
- "The ObjectWrapper of environment wasn't instance of ObjectWrapperAndUnwrapper.");
+ CallableUtils.newGenericExecuteException(
+ "The ObjectWrapper of environment isn't an instance of ObjectWrapperAndUnwrapper.", this,
+ isFunction());
}
TemplateModel rcModel = env.getVariable(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE);
if (rcModel == null) {
- throw new TemplateException(AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE + " not found.");
+ CallableUtils.newGenericExecuteException(
+ AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE + " not found.", this, isFunction());
}
RequestContext requestContext = (RequestContext) ((ObjectWrapperAndUnwrapper) objectWrapper).unwrap(rcModel);
@@ -62,6 +65,11 @@ public abstract class AbstractSpringTemplateFunctionModel extends AbstractSpring
return executeInternal(args, callPlace, env, (ObjectWrapperAndUnwrapper) objectWrapper, requestContext);
}
+ @Override
+ protected final boolean isFunction() {
+ return true;
+ }
+
protected abstract TemplateModel executeInternal(TemplateModel[] args, CallPlace callPlace, Environment env,
ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper, RequestContext requestContext)
throws TemplateException;
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a8e73ec7/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java
index 9579366..c6d1c69 100644
--- a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/MessageFunction.java
@@ -36,24 +36,26 @@ import org.apache.freemarker.core.model.TemplateModelIterator;
import org.apache.freemarker.core.model.impl.SimpleString;
import org.apache.freemarker.core.util.CallableUtils;
import org.apache.freemarker.core.util.StringToIndexMap;
+import org.apache.freemarker.core.util._StringUtils;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.web.servlet.support.RequestContext;
public class MessageFunction extends AbstractSpringTemplateFunctionModel {
- private static final int MESSAGE_PARAM_IDX = 0;
- private static final int MESSAGE_ARGS_PARAM_IDX = 1;
+ private static final int CODE_PARAM_IDX = 0;
+ private static final int MESSAGE_RESOLVABLE_PARAM_IDX = 1;
+ private static final int MESSAGE_ARGS_PARAM_IDX = 2;
- private static final String MESSAGE_PARAM_NAME = "message";
+ private static final String MESSAGE_RESOLVABLE_PARAM_NAME = "message";
private static final ArgumentArrayLayout ARGS_LAYOUT =
ArgumentArrayLayout.create(
- 0,
+ 1,
true,
- StringToIndexMap.of(
- MESSAGE_PARAM_NAME, MESSAGE_PARAM_IDX),
- false);
+ StringToIndexMap.of(MESSAGE_RESOLVABLE_PARAM_NAME, MESSAGE_RESOLVABLE_PARAM_IDX),
+ false
+ );
public MessageFunction(HttpServletRequest request, HttpServletResponse response) {
super(request, response);
@@ -63,42 +65,45 @@ public class MessageFunction extends AbstractSpringTemplateFunctionModel {
public TemplateModel executeInternal(TemplateModel[] args, CallPlace callPlace, Environment env,
ObjectWrapperAndUnwrapper objectWrapperAndUnwrapper, RequestContext requestContext)
throws TemplateException {
- final MessageSource messageSource = requestContext.getMessageSource();
+ final MessageSource messageSource = getMessageSource(requestContext);
if (messageSource == null) {
- throw new TemplateException("MessageSource not found.");
+ CallableUtils.newGenericExecuteException("MessageSource not found.", this);
}
String message = null;
- final TemplateCollectionModel messageArgsModel = (TemplateCollectionModel) args[MESSAGE_ARGS_PARAM_IDX];
-
- if (!messageArgsModel.isEmptyCollection()) {
- String code = null;
- List<Object> msgArgumentList = new ArrayList<>();
- TemplateModel msgArgModel;
- int i = 0;
- for (TemplateModelIterator tit = messageArgsModel.iterator(); tit.hasNext(); i++) {
- msgArgModel = tit.next();
- if (i == 0) {
- code = objectWrapperAndUnwrapper.unwrap(msgArgModel).toString();
- } else {
- msgArgumentList.add(objectWrapperAndUnwrapper.unwrap(msgArgModel));
- }
- }
+ final TemplateModel messageResolvableModel = CallableUtils.getOptionalArgument(args, MESSAGE_RESOLVABLE_PARAM_IDX,
+ TemplateModel.class, this);
- // TODO: Is it okay to set the default value to null to avoid NoSuchMessageException from Spring MessageSource?
- message = messageSource.getMessage(code, (msgArgumentList.isEmpty()) ? null : msgArgumentList.toArray(),
- null, requestContext.getLocale());
+ if (messageResolvableModel != null) {
+ MessageSourceResolvable messageResolvable = (MessageSourceResolvable) objectWrapperAndUnwrapper
+ .unwrap(messageResolvableModel);
+ message = messageSource.getMessage(messageResolvable, requestContext.getLocale());
} else {
- final TemplateModel messageModel = CallableUtils.getOptionalArgument(args, MESSAGE_PARAM_IDX,
- TemplateModel.class, this);
- if (messageModel != null) {
- MessageSourceResolvable messageResolvable = (MessageSourceResolvable) objectWrapperAndUnwrapper
- .unwrap(messageModel);
- message = messageSource.getMessage(messageResolvable, requestContext.getLocale());
+ final String code = _StringUtils
+ .emptyToNull(CallableUtils.getOptionalStringArgument(args, CODE_PARAM_IDX, this));
+
+ if (code != null) {
+ List<Object> msgArgumentList = null;
+ final TemplateCollectionModel messageArgsModel = (TemplateCollectionModel) args[MESSAGE_ARGS_PARAM_IDX];
+
+ if (!messageArgsModel.isEmptyCollection()) {
+ msgArgumentList = new ArrayList<>();
+ TemplateModel msgArgModel;
+ int i = 0;
+ for (TemplateModelIterator tit = messageArgsModel.iterator(); tit.hasNext(); i++) {
+ msgArgModel = tit.next();
+ msgArgumentList.add(objectWrapperAndUnwrapper.unwrap(msgArgModel));
+ }
+ }
+
+ // Note: Pass null as default value to avoid NoSuchMessageException from Spring MessageSource
+ // since we want to take advantage of FreeMarker's default value expressions.
+ message = messageSource.getMessage(code, (msgArgumentList == null) ? null : msgArgumentList.toArray(),
+ null, requestContext.getLocale());
} else {
- throw new TemplateException("Neither message code nor message resolvable was set.");
+ CallableUtils.newNullOrOmittedArgumentException(CODE_PARAM_IDX, this);
}
}
@@ -110,4 +115,8 @@ public class MessageFunction extends AbstractSpringTemplateFunctionModel {
return ARGS_LAYOUT;
}
+ protected MessageSource getMessageSource(final RequestContext requestContext) {
+ return requestContext.getMessageSource();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a8e73ec7/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/ThemeFunction.java
----------------------------------------------------------------------
diff --git a/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/ThemeFunction.java b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/ThemeFunction.java
new file mode 100644
index 0000000..b3b0653
--- /dev/null
+++ b/freemarker-spring/src/main/java/org/apache/freemarker/spring/model/ThemeFunction.java
@@ -0,0 +1,38 @@
+/*
+ * 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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.context.MessageSource;
+import org.springframework.web.servlet.support.RequestContext;
+
+public class ThemeFunction extends MessageFunction {
+
+ public ThemeFunction(HttpServletRequest request, HttpServletResponse response) {
+ super(request, response);
+ }
+
+ protected MessageSource getMessageSource(final RequestContext requestContext) {
+ return requestContext.getTheme().getMessageSource();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/a8e73ec7/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 f34fd4b..a789f4e 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
@@ -40,6 +40,7 @@ import org.apache.freemarker.servlet.ServletContextHashModel;
import org.apache.freemarker.servlet.jsp.TaglibFactory;
import org.apache.freemarker.spring.model.BindDirective;
import org.apache.freemarker.spring.model.MessageFunction;
+import org.apache.freemarker.spring.model.ThemeFunction;
/**
* FreeMarker template based view implementation, with being able to provide a {@link ServletContextHashModel}
@@ -180,6 +181,7 @@ public class FreeMarkerView extends AbstractFreeMarkerView {
final SimpleHash springCallableHash = new SimpleHash(objectWrapper);
springCallableHash.put("bind", new BindDirective(request, response));
springCallableHash.put("message", new MessageFunction(request, response));
+ springCallableHash.put("theme", new ThemeFunction(request, response));
return springCallableHash;
}
}