Repository: incubator-freemarker Updated Branches: refs/heads/3 7338b3255 -> 492fa2085
util.ObjectFactory was renamed to CommonSupplier, and its createObject() method was renamed to get(), to be more similar to the Java 8 API. The difference to CommonBuilder was clarified. Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/492fa208 Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/492fa208 Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/492fa208 Branch: refs/heads/3 Commit: 492fa2085c420ef97f3a624d85fe59882d94f515 Parents: 7338b32 Author: ddekany <ddek...@apache.org> Authored: Mon Jun 19 23:55:44 2017 +0200 Committer: ddekany <ddek...@apache.org> Committed: Mon Jun 19 23:55:44 2017 +0200 ---------------------------------------------------------------------- FM3-CHANGE-LOG.txt | 2 ++ .../freemarker/core/DirectiveCallPlaceTest.java | 6 ++-- .../freemarker/core/ASTDirUserDefined.java | 18 +++++----- ...lPlaceCustomDataInitializationException.java | 4 ++- .../freemarker/core/DirectiveCallPlace.java | 18 +++++----- .../freemarker/core/util/CommonBuilder.java | 7 ++-- .../freemarker/core/util/CommonSupplier.java | 35 ++++++++++++++++++++ .../freemarker/core/util/ObjectFactory.java | 29 ---------------- 8 files changed, 65 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/492fa208/FM3-CHANGE-LOG.txt ---------------------------------------------------------------------- diff --git a/FM3-CHANGE-LOG.txt b/FM3-CHANGE-LOG.txt index d464d33..0759d58 100644 --- a/FM3-CHANGE-LOG.txt +++ b/FM3-CHANGE-LOG.txt @@ -281,3 +281,5 @@ the FreeMarer 3 changelog here: - Removed the logTemplateExceptions (log_template_exceptions) setting. FreeMarker now behaves as if it was false. When a FreeMarker method throws an exception, the caller is responsible for either logging it or letting it bubble up. +- util.ObjectFactory was renamed to CommonSupplier, and its createObject() method was renamed to + get(), to be more similar to the Java 8 API. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/492fa208/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java ---------------------------------------------------------------------- diff --git a/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java index 29220c4..28744b3 100644 --- a/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java +++ b/freemarker-core-test/src/test/java/org/apache/freemarker/core/DirectiveCallPlaceTest.java @@ -31,7 +31,7 @@ import org.apache.freemarker.core.model.TemplateDirectiveModel; import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.model.TemplateModelException; import org.apache.freemarker.core.model.TemplateScalarModel; -import org.apache.freemarker.core.util.ObjectFactory; +import org.apache.freemarker.core.util.CommonSupplier; import org.apache.freemarker.test.TemplateTest; import org.junit.Test; @@ -125,10 +125,10 @@ public class DirectiveCallPlaceTest extends TemplateTest { if (callPlace.isNestedOutputCacheable()) { try { convertedText = (String) callPlace.getOrCreateCustomData( - getTextConversionIdentity(), new ObjectFactory<String>() { + getTextConversionIdentity(), new CommonSupplier<String>() { @Override - public String createObject() throws TemplateException, IOException { + public String get() throws TemplateException, IOException { return convertBodyText(body) + "[cached " + cacheRecreationCount.incrementAndGet() + "]"; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/492fa208/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirUserDefined.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirUserDefined.java b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirUserDefined.java index 2fab592..d19aaa2 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirUserDefined.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/ASTDirUserDefined.java @@ -31,7 +31,7 @@ import java.util.Map; import org.apache.freemarker.core.model.TemplateDirectiveModel; import org.apache.freemarker.core.model.TemplateModel; import org.apache.freemarker.core.model.TemplateTransformModel; -import org.apache.freemarker.core.util.ObjectFactory; +import org.apache.freemarker.core.util.CommonSupplier; import org.apache.freemarker.core.util._StringUtil; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -251,7 +251,7 @@ final class ASTDirUserDefined extends ASTDirective implements DirectiveCallPlace @Override @SuppressFBWarnings(value={ "IS2_INCONSISTENT_SYNC", "DC_DOUBLECHECK" }, justification="Performance tricks") - public Object getOrCreateCustomData(Object providerIdentity, ObjectFactory objectFactory) + public Object getOrCreateCustomData(Object providerIdentity, CommonSupplier supplier) throws CallPlaceCustomDataInitializationException { // We are using double-checked locking, utilizing Java memory model "final" trick. // Note that this.customDataHolder is NOT volatile. @@ -261,7 +261,7 @@ final class ASTDirUserDefined extends ASTDirective implements DirectiveCallPlace synchronized (this) { customDataHolder = this.customDataHolder; if (customDataHolder == null || customDataHolder.providerIdentity != providerIdentity) { - customDataHolder = createNewCustomData(providerIdentity, objectFactory); + customDataHolder = createNewCustomData(providerIdentity, supplier); this.customDataHolder = customDataHolder; } } @@ -271,7 +271,7 @@ final class ASTDirUserDefined extends ASTDirective implements DirectiveCallPlace synchronized (this) { customDataHolder = this.customDataHolder; if (customDataHolder == null || customDataHolder.providerIdentity != providerIdentity) { - customDataHolder = createNewCustomData(providerIdentity, objectFactory); + customDataHolder = createNewCustomData(providerIdentity, supplier); this.customDataHolder = customDataHolder; } } @@ -280,20 +280,20 @@ final class ASTDirUserDefined extends ASTDirective implements DirectiveCallPlace return customDataHolder.customData; } - private CustomDataHolder createNewCustomData(Object provierIdentity, ObjectFactory objectFactory) + private CustomDataHolder createNewCustomData(Object provierIdentity, CommonSupplier supplier) throws CallPlaceCustomDataInitializationException { CustomDataHolder customDataHolder; Object customData; try { - customData = objectFactory.createObject(); + customData = supplier.get(); } catch (Exception e) { throw new CallPlaceCustomDataInitializationException( "Failed to initialize custom data for provider identity " + _StringUtil.tryToString(provierIdentity) + " via factory " - + _StringUtil.tryToString(objectFactory), e); + + _StringUtil.tryToString(supplier), e); } if (customData == null) { - throw new NullPointerException("ObjectFactory.createObject() has returned null"); + throw new NullPointerException("CommonSupplier.get() has returned null"); } customDataHolder = new CustomDataHolder(provierIdentity, customData); return customDataHolder; @@ -317,7 +317,7 @@ final class ASTDirUserDefined extends ASTDirective implements DirectiveCallPlace /** * Used for implementing double check locking in implementing the - * {@link DirectiveCallPlace#getOrCreateCustomData(Object, ObjectFactory)}. + * {@link DirectiveCallPlace#getOrCreateCustomData(Object, CommonSupplier)}. */ private static class CustomDataHolder { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/492fa208/freemarker-core/src/main/java/org/apache/freemarker/core/CallPlaceCustomDataInitializationException.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/CallPlaceCustomDataInitializationException.java b/freemarker-core/src/main/java/org/apache/freemarker/core/CallPlaceCustomDataInitializationException.java index 842fda1..810ccba 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/CallPlaceCustomDataInitializationException.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/CallPlaceCustomDataInitializationException.java @@ -19,8 +19,10 @@ package org.apache.freemarker.core; +import org.apache.freemarker.core.util.CommonSupplier; + /** - * Thrown by {@link DirectiveCallPlace#getOrCreateCustomData(Object, org.apache.freemarker.core.util.ObjectFactory)} + * Thrown by {@link DirectiveCallPlace#getOrCreateCustomData(Object, CommonSupplier)} */ public class CallPlaceCustomDataInitializationException extends Exception { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/492fa208/freemarker-core/src/main/java/org/apache/freemarker/core/DirectiveCallPlace.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/DirectiveCallPlace.java b/freemarker-core/src/main/java/org/apache/freemarker/core/DirectiveCallPlace.java index 29ac0c2..d6392ac 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/DirectiveCallPlace.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/DirectiveCallPlace.java @@ -23,7 +23,7 @@ import java.util.IdentityHashMap; import org.apache.freemarker.core.model.TemplateDirectiveModel; import org.apache.freemarker.core.model.TemplateTransformModel; -import org.apache.freemarker.core.util.ObjectFactory; +import org.apache.freemarker.core.util.CommonSupplier; /** * Gives information about the place where a directive is called from, also lets you attach a custom data object to that @@ -32,7 +32,7 @@ import org.apache.freemarker.core.util.ObjectFactory; * {@link Template} object that contains the directive call. Hence, the {@link DirectiveCallPlace} object and the custom * data you put into it is cached together with the {@link Template} (and templates are normally cached - see * {@link Configuration#getTemplate(String)}). The custom data is normally initialized on demand, that is, when the - * directive call is first executed, via {@link #getOrCreateCustomData(Object, ObjectFactory)}. + * directive call is first executed, via {@link #getOrCreateCustomData(Object, CommonSupplier)}. * * <p> * Currently this method doesn't give you access to the {@link Template} object, because it's probable that future @@ -84,10 +84,10 @@ public interface DirectiveCallPlace { * during template parsing, not on runtime settings. * * <p> - * This method will block other calls while the {@code objectFactory} is executing, thus, the object will be + * This method will block other calls while the {@code supplier} is executing, thus, the object will be * <em>usually</em> created only once, even if multiple threads request the value when it's still {@code null}. It * doesn't stand though when {@code providerIdentity} mismatches occur (see later). Furthermore, then it's also - * possible that multiple objects created by the same {@link ObjectFactory} will be in use on the same time, because + * possible that multiple objects created by the same {@link CommonSupplier} will be in use on the same time, because * of directive executions already running in parallel, and because of memory synchronization delays (hardware * dependent) between the threads. * @@ -105,17 +105,17 @@ public interface DirectiveCallPlace { * data. (In a more generic implementation the {@code providerIdentity} would be a key in a * {@link IdentityHashMap}, but then this feature would be slower, while {@code providerIdentity} * mismatches aren't occurring in most applications.) - * @param objectFactory + * @param supplier * Called when the custom data wasn't yet set, to invoke its initial value. If this parameter is * {@code null} and the custom data wasn't set yet, then {@code null} will be returned. The returned - * value of {@link ObjectFactory#createObject()} can be any kind of object, but can't be {@code null}. + * value of {@link CommonSupplier#get()} can be any kind of object, but can't be {@code null}. * - * @return The current custom data object, or possibly {@code null} if there was no {@link ObjectFactory} provided. + * @return The current custom data object, or possibly {@code null} if there was no {@link CommonSupplier} provided. * * @throws CallPlaceCustomDataInitializationException - * If the {@link ObjectFactory} had to be invoked but failed. + * If the {@link CommonSupplier} had to be invoked but failed. */ - Object getOrCreateCustomData(Object providerIdentity, ObjectFactory objectFactory) + Object getOrCreateCustomData(Object providerIdentity, CommonSupplier supplier) throws CallPlaceCustomDataInitializationException; /** http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/492fa208/freemarker-core/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java index 569f8d1..7b0ecd3 100644 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CommonBuilder.java @@ -22,9 +22,10 @@ package org.apache.freemarker.core.util; import org.apache.freemarker.core.ConfigurationException; /** - * Interface of builders (used for implementing the builder pattern). - */ -public interface CommonBuilder<ProductT> { + * Common interface for builders (used for implementing the builder design pattern). This is technically very similar to + * {@link CommonSupplier}, but the intent is more specific. A is builder stateful object used only for creating a + * single instance. Generally, it isn't expected to be thread safe. + */public interface CommonBuilder<ProductT> { /** * Creates an instance of the product class. This is usually a new instance, though if the product is stateless, http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/492fa208/freemarker-core/src/main/java/org/apache/freemarker/core/util/CommonSupplier.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/CommonSupplier.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CommonSupplier.java new file mode 100644 index 0000000..eebdc41 --- /dev/null +++ b/freemarker-core/src/main/java/org/apache/freemarker/core/util/CommonSupplier.java @@ -0,0 +1,35 @@ +/* + * 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.core.util; + +/** + * Similar to {@code java.util.function.Supplier} in Java 8, but we don't require Java 8. + */ +public interface CommonSupplier<ProductT> { + + /** + * Returns an instance of the object. Whether this should return a new object each time, or the same + * object every time, is ultimately specified by the method whose parameter the supplier will be. If nothing + * is said there, then it should return a new object every time, except if the object is immutable and thread + * safe, in which case it can be safely returned for multiple times. + */ + ProductT get() throws Exception; + +} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/492fa208/freemarker-core/src/main/java/org/apache/freemarker/core/util/ObjectFactory.java ---------------------------------------------------------------------- diff --git a/freemarker-core/src/main/java/org/apache/freemarker/core/util/ObjectFactory.java b/freemarker-core/src/main/java/org/apache/freemarker/core/util/ObjectFactory.java deleted file mode 100644 index 471ed35..0000000 --- a/freemarker-core/src/main/java/org/apache/freemarker/core/util/ObjectFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.core.util; - -/** - * Used for the trivial cases of the factory pattern. Has a generic type argument since 2.3.24. - */ -public interface ObjectFactory<T> { - - T createObject() throws Exception; - -}