All Downloads are FREE. Search and download functionalities are using the official Maven repository.

freemarker.ext.beans.BeansWrapperConfiguration Maven / Gradle / Ivy

Go to download

Google App Engine compliant variation of FreeMarker. FreeMarker is a "template engine"; a generic tool to generate text output based on templates.

There is a newer version: 2.3.33
Show newest version
/*
 * Copyright 2014 Attila Szegedi, Daniel Dekany, Jonathan Revusky
 * 
 * Licensed 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 freemarker.ext.beans;

import freemarker.template.DefaultObjectWrapperBuilder;
import freemarker.template.ObjectWrapper;
import freemarker.template.TemplateDateModel;
import freemarker.template.Version;
import freemarker.template._TemplateAPI;

/**
 * Holds {@link BeansWrapper} configuration settings and defines their defaults.
 * You will not use this abstract class directly, but concrete subclasses like {@link BeansWrapperBuilder} and
 * {@link DefaultObjectWrapperBuilder}. Unless, you are developing a builder for a custom {@link BeansWrapper} subclass.
 * 
 * 

This class is designed so that its instances can be used as lookup keys in a singleton cache. This is also why * this class defines the configuration setting defaults for {@link BeansWrapper}, instead of leaving that to * {@link BeansWrapper} itself. (Because, the default values influence the lookup key, and the singleton needs to be * looked up without creating a {@link BeansWrapper} instance.) However, because instances are mutable, you should * deep-clone it with {@link #clone(boolean)} before using it as cache key. * * @since 2.3.21 */ public abstract class BeansWrapperConfiguration implements Cloneable { private final Version incompatibleImprovements; protected ClassIntrospectorBuilder classIntrospectorFactory; // Properties and their *defaults*: private boolean simpleMapWrapper = false; private int defaultDateType = TemplateDateModel.UNKNOWN; private ObjectWrapper outerIdentity = null; private boolean strict = false; private boolean useModelCache = false; // Attention! // - As this object is a cache key, non-normalized field values should be avoided. // - Fields with default values must be set until the end of the constructor to ensure that when the lookup happens, // there will be no unset fields. // - If you add a new field, review all methods in this class /** * @param incompatibleImprovements See the corresponding parameter of {@link BeansWrapper#BeansWrapper(Version)}. * Not {@code null}. * Note that the version will be normalized to the lowest version where the same incompatible * {@link BeansWrapper} improvements were already present, so for the returned instance * {@link #getIncompatibleImprovements()} might returns a lower version than what you have specified. */ protected BeansWrapperConfiguration(Version incompatibleImprovements) { _TemplateAPI.checkVersionNotNullAndSupported(incompatibleImprovements); incompatibleImprovements = BeansWrapper.normalizeIncompatibleImprovementsVersion(incompatibleImprovements); this.incompatibleImprovements = incompatibleImprovements; classIntrospectorFactory = new ClassIntrospectorBuilder(incompatibleImprovements); } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + incompatibleImprovements.hashCode(); result = prime * result + (simpleMapWrapper ? 1231 : 1237); result = prime * result + defaultDateType; result = prime * result + (outerIdentity != null ? outerIdentity.hashCode() : 0); result = prime * result + (strict ? 1231 : 1237); result = prime * result + (useModelCache ? 1231 : 1237); result = prime * result + classIntrospectorFactory.hashCode(); return result; } public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; BeansWrapperConfiguration other = (BeansWrapperConfiguration) obj; if (!incompatibleImprovements.equals(other.incompatibleImprovements)) return false; if (simpleMapWrapper != other.simpleMapWrapper) return false; if (defaultDateType != other.defaultDateType) return false; if (outerIdentity != other.outerIdentity) return false; if (strict != other.strict) return false; if (useModelCache != other.useModelCache) return false; if (!classIntrospectorFactory.equals(other.classIntrospectorFactory)) return false; return true; } protected Object clone(boolean deepCloneKey) { try { BeansWrapperConfiguration clone = (BeansWrapperConfiguration) super.clone(); if (deepCloneKey) { clone.classIntrospectorFactory = (ClassIntrospectorBuilder) classIntrospectorFactory.clone(); } return clone; } catch (CloneNotSupportedException e) { throw new RuntimeException("Failed to clone BeansWrapperConfiguration", e); } } public boolean isSimpleMapWrapper() { return simpleMapWrapper; } /** See {@link BeansWrapper#setSimpleMapWrapper(boolean)}. */ public void setSimpleMapWrapper(boolean simpleMapWrapper) { this.simpleMapWrapper = simpleMapWrapper; } public int getDefaultDateType() { return defaultDateType; } /** See {@link BeansWrapper#setDefaultDateType(int)}. */ public void setDefaultDateType(int defaultDateType) { this.defaultDateType = defaultDateType; } public ObjectWrapper getOuterIdentity() { return outerIdentity; } /** * See {@link BeansWrapper#setOuterIdentity(ObjectWrapper)}, except here the default is {@code null} that means * the {@link ObjectWrapper} that you will set up with this {@link BeansWrapperBuilder} object. */ public void setOuterIdentity(ObjectWrapper outerIdentity) { this.outerIdentity = outerIdentity; } public boolean isStrict() { return strict; } /** See {@link BeansWrapper#setStrict(boolean)}. */ public void setStrict(boolean strict) { this.strict = strict; } public boolean getUseModelCache() { return useModelCache; } /** See {@link BeansWrapper#setUseCache(boolean)} (it means the same). */ public void setUseModelCache(boolean useModelCache) { this.useModelCache = useModelCache; } public Version getIncompatibleImprovements() { return incompatibleImprovements; } public int getExposureLevel() { return classIntrospectorFactory.getExposureLevel(); } /** See {@link BeansWrapper#setExposureLevel(int)}. */ public void setExposureLevel(int exposureLevel) { classIntrospectorFactory.setExposureLevel(exposureLevel); } public boolean getExposeFields() { return classIntrospectorFactory.getExposeFields(); } /** See {@link BeansWrapper#setExposeFields(boolean)}. */ public void setExposeFields(boolean exposeFields) { classIntrospectorFactory.setExposeFields(exposeFields); } public MethodAppearanceFineTuner getMethodAppearanceFineTuner() { return classIntrospectorFactory.getMethodAppearanceFineTuner(); } /** * See {@link BeansWrapper#setMethodAppearanceFineTuner(MethodAppearanceFineTuner)}; additionally, * note that currently setting this to non-{@code null} will disable class introspection cache sharing, unless * the value implements {@link SingletonCustomizer}. */ public void setMethodAppearanceFineTuner(MethodAppearanceFineTuner methodAppearanceFineTuner) { classIntrospectorFactory.setMethodAppearanceFineTuner(methodAppearanceFineTuner); } MethodSorter getMethodSorter() { return classIntrospectorFactory.getMethodSorter(); } void setMethodSorter(MethodSorter methodSorter) { classIntrospectorFactory.setMethodSorter(methodSorter); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy