栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

FreeMarker代码分析(1)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

FreeMarker代码分析(1)

2021SC@SDUSC

**内容非常主观,可能出现错漏,慎重参考

_ArrayEnumeration.java


package freemarker.core;

import java.util.Enumeration;
import java.util.NoSuchElementException;


public class _ArrayEnumeration implements Enumeration {

    private final Object[] array;
    private final int size;
    private int nextIndex;

    public _ArrayEnumeration(Object[] array, int size) {
        this.array = array;
        this.size = size;
        this.nextIndex = 0;
    }

    @Override
    public boolean hasMoreElements() {
        return nextIndex < size;
    }

    @Override
    public Object nextElement() {
        if (nextIndex >= size) {
            throw new NoSuchElementException();
        }
        return array[nextIndex++];
    }

}

Enumeration接口中定义了一些方法,通过这些方法可以枚举(一次获得一个)对象集合中的元素。这种传统接口已被迭代器取代,虽然Enumeration 还未被遗弃,但在现代代码中已经被很少使用了。尽管如此,它还是使用在诸如Vector和Properties这些传统类所定义的方法中,除此之外,还用在一些API类,并且在应用程序中也广泛被使用。 下表总结了一些Enumeration声明的方法:

1boolean hasMoreElements( )
 测试此枚举是否包含更多的元素。
2Object nextElement( )
如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。

_ArrayIterator.java


package freemarker.core;

import java.util.Iterator;
import java.util.NoSuchElementException;


public class _ArrayIterator implements Iterator {

    private final Object[] array;
    private int nextIndex;

    public _ArrayIterator(Object[] array) {
        this.array = array;
        this.nextIndex = 0;
    }

    @Override
    public boolean hasNext() {
        return nextIndex < array.length;
    }

    @Override
    public Object next() {
        if (nextIndex >= array.length) {
            throw new NoSuchElementException();
        }
        return array[nextIndex++];
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }

}

Iterator ——迭代器

Java.util.Iterator 接口描述的是以统一的方式对各种集合元素进行遍历 / 迭代的工具,也称“迭代器”。

迭代器( Iterator )模式,又叫做游标( Cursor )模式,是用于遍历集合类的标准访问方法。 GOF 给出的定义为:提供一种方法访问一个容器(Container )对象中各个元素,而又不需暴露该对象的内部细节。

_CoreAPI.java


package freemarker.core;

import java.io.Writer;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template._TemplateAPI;
import freemarker.template.utility.ClassUtil;


 
public class _CoreAPI {
    
    public static final String ERROR_MESSAGE_HR = "----";

    // Can't be instantiated
    private _CoreAPI() { }

    private static void addName(Set allNames, Set lcNames, Set ccNames,
            String commonName) {
        allNames.add(commonName);
        lcNames.add(commonName);
        ccNames.add(commonName);
    }
    
    private static void addName(Set allNames, Set lcNames, Set ccNames,
            String lcName, String ccName) {
        allNames.add(lcName);
        allNames.add(ccName);
        lcNames.add(lcName);
        ccNames.add(ccName);
    }
    
    public static final Set ALL_BUILT_IN_DIRECTIVE_NAMES;
    public static final Set LEGACY_BUILT_IN_DIRECTIVE_NAMES;
    public static final Set CAMEL_CASE_BUILT_IN_DIRECTIVE_NAMES;
    static {
        Set allNames = new TreeSet();
        Set lcNames = new TreeSet();
        Set ccNames = new TreeSet();
        
        addName(allNames, lcNames, ccNames, "assign");
        addName(allNames, lcNames, ccNames, "attempt");
        addName(allNames, lcNames, ccNames, "autoesc", "autoEsc");
        addName(allNames, lcNames, ccNames, "break");
        addName(allNames, lcNames, ccNames, "call");
        addName(allNames, lcNames, ccNames, "case");
        addName(allNames, lcNames, ccNames, "comment");
        addName(allNames, lcNames, ccNames, "compress");
        addName(allNames, lcNames, ccNames, "continue");
        addName(allNames, lcNames, ccNames, "default");
        addName(allNames, lcNames, ccNames, "else");
        addName(allNames, lcNames, ccNames, "elseif", "elseIf");
        addName(allNames, lcNames, ccNames, "escape");
        addName(allNames, lcNames, ccNames, "fallback");
        addName(allNames, lcNames, ccNames, "flush");
        addName(allNames, lcNames, ccNames, "foreach", "forEach");
        addName(allNames, lcNames, ccNames, "ftl");
        addName(allNames, lcNames, ccNames, "function");
        addName(allNames, lcNames, ccNames, "global");
        addName(allNames, lcNames, ccNames, "if");
        addName(allNames, lcNames, ccNames, "import");
        addName(allNames, lcNames, ccNames, "include");
        addName(allNames, lcNames, ccNames, "items");
        addName(allNames, lcNames, ccNames, "list");
        addName(allNames, lcNames, ccNames, "local");
        addName(allNames, lcNames, ccNames, "lt");
        addName(allNames, lcNames, ccNames, "macro");
        addName(allNames, lcNames, ccNames, "nested");
        addName(allNames, lcNames, ccNames, "noautoesc", "noAutoEsc");
        addName(allNames, lcNames, ccNames, "noescape", "noEscape");
        addName(allNames, lcNames, ccNames, "noparse", "noParse");
        addName(allNames, lcNames, ccNames, "nt");
        addName(allNames, lcNames, ccNames, "outputformat", "outputFormat");
        addName(allNames, lcNames, ccNames, "recover");
        addName(allNames, lcNames, ccNames, "recurse");
        addName(allNames, lcNames, ccNames, "return");
        addName(allNames, lcNames, ccNames, "rt");
        addName(allNames, lcNames, ccNames, "sep");
        addName(allNames, lcNames, ccNames, "setting");
        addName(allNames, lcNames, ccNames, "stop");
        addName(allNames, lcNames, ccNames, "switch");
        addName(allNames, lcNames, ccNames, "t");
        addName(allNames, lcNames, ccNames, "transform");
        addName(allNames, lcNames, ccNames, "visit");
        
        ALL_BUILT_IN_DIRECTIVE_NAMES = Collections.unmodifiableSet(allNames);
        LEGACY_BUILT_IN_DIRECTIVE_NAMES = Collections.unmodifiableSet(lcNames);
        CAMEL_CASE_BUILT_IN_DIRECTIVE_NAMES = Collections.unmodifiableSet(ccNames);
    }
    
    
    public static Set getSupportedBuiltInNames(int namingConvention) {
        Set names;
        if (namingConvention == Configuration.AUTO_DETECT_NAMING_CONVENTION) {
            names = BuiltIn.BUILT_INS_BY_NAME.keySet();
        } else if (namingConvention == Configuration.LEGACY_NAMING_CONVENTION) {
            names = BuiltIn.SNAKE_CASE_NAMES;
        } else if (namingConvention == Configuration.CAMEL_CASE_NAMING_CONVENTION) {
            names = BuiltIn.CAMEL_CASE_NAMES;
        } else {
            throw new IllegalArgumentException("Unsupported naming convention constant: " + namingConvention);
        }
        return Collections.unmodifiableSet(names);
    }
    
    public static void appendInstructionStackItem(TemplateElement stackEl, StringBuilder sb) {
        Environment.appendInstructionStackItem(stackEl, sb);
    }
    
    public static TemplateElement[] getInstructionStackSnapshot(Environment env) {
        return env.getInstructionStackSnapshot();
    }
    
    public static void outputInstructionStack(
            TemplateElement[] instructionStackSnapshot, boolean terseMode, Writer pw) {
        Environment.outputInstructionStack(instructionStackSnapshot, terseMode, pw);
    }

    
    static final public void addThreadInterruptedChecks(Template template) {
        try {
            new ThreadInterruptionSupportTemplatePostProcessor().postProcess(template);
        } catch (TemplatePostProcessorException e) {
            throw new RuntimeException("Template post-processing failed", e);
        }
    }
    
    static final public void checkHasNonestedContent(TemplateDirectiveBody body)
            throws NestedContentNotSupportedException {
        NestedContentNotSupportedException.check(body);
    }
    
    static final public void replaceText(TextBlock textBlock, String text) {
        textBlock.replaceText(text);
    }

    
    public static void checkSettingValueItemsType(String somethingsSentenceStart, Class expectedClass,
            Collection values) {
        if (values == null) return;
        for (Object value : values) {
            if (!expectedClass.isInstance(value)) {
                throw new IllegalArgumentException(somethingsSentenceStart + " must be instances of "
                        + ClassUtil.getShortClassName(expectedClass) + ", but one of them was a(n) "
                        + ClassUtil.getShortClassNameOfObject(value) + ".");
            }
        }
    }
    
    
    public static TemplateModelException ensureIsTemplateModelException(String modelOpMsg, TemplateException e) {
        if (e instanceof TemplateModelException) {
            return (TemplateModelException) e;
        } else {
            return new _TemplateModelException(
                    _TemplateAPI.getBlamedexpression(e), e.getCause(), e.getEnvironment(), modelOpMsg);
        }
    }
    
    public static TemplateElement getParentElement(TemplateElement te) {
        return te.getParentElement();
    }

    public static TemplateElement getChildElement(TemplateElement te, int index) {
        return te.getChild(index);
    }

    public static void setPreventStrippings(FMParser parser, boolean preventStrippings) {
        parser.setPreventStrippings(preventStrippings);
    }

    public static boolean isLazilyGeneratedSequenceModel(TemplateCollectionModel model) {
        return model instanceof LazilyGeneratedCollectionModel && ((LazilyGeneratedCollectionModel) model).isSequence();
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/309553.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号