⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sequencebuiltins.java

📁 freemaker安装软件
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * Copyright (c) 2003 The Visigoth Software Society. All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowledgement:
 *       "This product includes software developed by the
 *        Visigoth Software Society (http://www.visigoths.org/)."
 *    Alternately, this acknowledgement may appear in the software itself,
 *    if and wherever such third-party acknowledgements normally appear.
 *
 * 4. Neither the name "FreeMarker", "Visigoth", nor any of the names of the
 *    project contributors may be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact visigoths@visigoths.org.
 *
 * 5. Products derived from this software may not be called "FreeMarker" or "Visigoth"
 *    nor may "FreeMarker" or "Visigoth" appear in their names
 *    without prior written permission of the Visigoth Software Society.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Visigoth Software Society. For more
 * information on the Visigoth Software Society, please see
 * http://www.visigoths.org/
 */

package freemarker.core;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import freemarker.template.SimpleNumber;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateDateModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateModelListSequence;
import freemarker.template.TemplateNumberModel;
import freemarker.template.TemplateScalarModel;
import freemarker.template.TemplateSequenceModel;
import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateModelIterator;
import freemarker.template.utility.Constants;
import freemarker.template.utility.StringUtil;

/**
 * A holder for builtins that operate exclusively on TemplateSequenceModels.
 */

abstract class SequenceBuiltins {
    abstract static class SequenceBuiltIn extends BuiltIn {
        TemplateModel _getAsTemplateModel(Environment env)
                throws TemplateException
        {
            TemplateModel model = target.getAsTemplateModel(env);
            if (!(model instanceof TemplateSequenceModel)) {
                throw invalidTypeException(model, target, env, "sequence");
            }
            return calculateResult((TemplateSequenceModel) model);
        }
        abstract TemplateModel calculateResult(TemplateSequenceModel tsm)
        throws
            TemplateModelException;
    }

    static class firstBI extends SequenceBuiltIn {
        TemplateModel calculateResult(TemplateSequenceModel tsm)
        throws
            TemplateModelException
        {
            if (tsm.size() == 0) {
                return null;
            }
            return tsm.get(0);
        }
    }

    static class lastBI extends SequenceBuiltIn {
        TemplateModel calculateResult(TemplateSequenceModel tsm)
        throws
            TemplateModelException
        {
            if (tsm.size() == 0) {
                return null;
            }
            return tsm.get(tsm.size() -1);
        }
    }

    static class reverseBI extends SequenceBuiltIn {
        TemplateModel calculateResult(TemplateSequenceModel tsm) {
            if (tsm instanceof ReverseSequence) {
                return ((ReverseSequence) tsm).seq;
            } else {
                return new ReverseSequence(tsm);
            }
        }

        private static class ReverseSequence implements TemplateSequenceModel
        {
            private final TemplateSequenceModel seq;

            ReverseSequence(TemplateSequenceModel seq)
            {
                this.seq = seq;
            }

            public int size() throws TemplateModelException
            {
                return seq.size();
            }

            public TemplateModel get(int index) throws TemplateModelException
            {
                return seq.get(seq.size() - 1 - index);
            }
        }
    }

    static class sortBI extends SequenceBuiltIn {
        
        static final int KEY_TYPE_STRING = 1;
        static final int KEY_TYPE_NUMBER = 2;
        static final int KEY_TYPE_DATE = 3;
        
        TemplateModel calculateResult(TemplateSequenceModel seq)
                throws TemplateModelException {
            return sort(seq, null);
        }
        
        static String startErrorMessage(Object keys) {
            return (keys == null ? "?sort" : "?sort_by(...)") + " failed: ";
        }
        
        /**
         * Sorts a sequence for the <tt>sort</tt> and <tt>sort_by</tt>
         * built-ins.
         * 
         * @param seq the sequence to sort.
         * @param keys the name of the subvariable whose value is used for the
         *     sorting. If the sorting is done by a sub-subvaruable, then this
         *     will be of length 2, and so on. If the sorting is done by the
         *     sequene items directly, then this argument has to be 0 length
         *     array or <code>null</code>.
         * @return a new sorted sequence, or the original sequence if the
         *     sequence length was 0.
         */
        static TemplateSequenceModel sort(TemplateSequenceModel seq, String[] keys)
                throws TemplateModelException {
            int i;
            int keyCnt;

            int ln = seq.size();
            if (ln == 0) {
                return seq;
            }
            
            List res = new ArrayList(ln);
            Object item;
            item = seq.get(0);
            if (keys != null) {
                keyCnt = keys.length;
                if (keyCnt == 0) {
                    keys = null;
                } else {
                    for (i = 0; i < keyCnt; i++) {
                        if (!(item instanceof TemplateHashModel)) {
                            throw new TemplateModelException(
                                    startErrorMessage(keys)
                                    + (i == 0
                                            ? "You can't use ?sort_by when the "
                                              + "sequence items are not hashes."
                                            : "The subvariable "
                                              + StringUtil.jQuote(keys[i - 1])
                                              + " is not a hash, so ?sort_by "
                                              + "can't proceed by getting the "
                                              + StringUtil.jQuote(keys[i])
                                              + " subvariable."));
                        }
                        
                        item = ((TemplateHashModel) item).get(keys[i]);
                        if (item == null) {
                            throw new TemplateModelException(
                                    startErrorMessage(keys)
                                    + "The " + StringUtil.jQuote(keys[i])
                                    + " subvariable "
                                    + (keyCnt == 1
                                        ? "was not found."
                                        : "(specified by ?sort_by argument number "
                                          + (i + 1) + ") was not found."));
                        }
                    }
                }
            } else {
                keyCnt = 0;
            }

            int keyType;
            if (item instanceof TemplateScalarModel) {
                keyType = KEY_TYPE_STRING;
            } else if (item instanceof TemplateNumberModel) {
                keyType = KEY_TYPE_NUMBER;
            } else if (item instanceof TemplateDateModel) {
                keyType = KEY_TYPE_DATE;
            } else {
                throw new TemplateModelException(
                        startErrorMessage(keys)
                        + "Values used for sorting must be numbers, strings, or date/time values.");
            }

            if (keys == null) {
                if (keyType == KEY_TYPE_STRING) {
                    for (i = 0; i < ln; i++) {
                        item = seq.get(i);
                        try {
                            res.add(new KVP(
                                    ((TemplateScalarModel) item).getAsString(),
                                    item));
                        } catch (ClassCastException e) {
                            if (!(item instanceof TemplateScalarModel)) {
                                throw new TemplateModelException(
                                        startErrorMessage(keys)
                                        + "All values in the sequence must be "
                                        + "strings, because the first value "
                                        + "was a string. "
                                        + "The value at index " + i
                                        + " is not string.");
                            } else {
                                throw e;
                            }
                        }
                    }
                } else if (keyType == KEY_TYPE_NUMBER) {
                    for (i = 0; i < ln; i++) {
                        item = seq.get(i);
                        try {
                            res.add(new KVP(
                                    ((TemplateNumberModel) item).getAsNumber(),
                                    item));
                        } catch (ClassCastException e) {
                            if (!(item instanceof TemplateNumberModel)) {
                                throw new TemplateModelException(
                                        startErrorMessage(keys)
                                        + "All values in the sequence must be "
                                        + "numbers, because the first value "
                                        + "was a number. "
                                        + "The value at index " + i
                                        + " is not number.");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -