📄 sequencebuiltins.java
字号:
private Environment m_env;
private BIMethodForCollection(TemplateCollectionModel coll, Environment env) {
m_coll = coll;
m_env = env;
}
public Object exec(List args)
throws TemplateModelException {
if (args.size() != 1)
throw new TemplateModelException("?seq_contains(...) expects one argument.");
TemplateModel arg = (TemplateModel) args.get(0);
TemplateModelIterator it = m_coll.iterator();
while (it.hasNext()) {
if (modelsEqual(it.next(), arg, m_env))
return TemplateBooleanModel.TRUE;
}
return TemplateBooleanModel.FALSE;
}
}
}
static class seq_index_ofBI extends BuiltIn {
private int m_dir;
public seq_index_ofBI(int dir) {
m_dir = dir;
}
TemplateModel _getAsTemplateModel(Environment env)
throws TemplateException {
TemplateModel model = target.getAsTemplateModel(env);
if (!(model instanceof TemplateSequenceModel))
throw invalidTypeException(model, target, env, "sequence");
return new BIMethod((TemplateSequenceModel) model, env);
}
private class BIMethod implements TemplateMethodModelEx {
private TemplateSequenceModel m_seq;
private Environment m_env;
private BIMethod(TemplateSequenceModel seq, Environment env) {
m_seq = seq;
m_env = env;
}
public Object exec(List args)
throws TemplateModelException {
int argcnt = args.size();
if (argcnt != 1 && argcnt != 2) {
throw new TemplateModelException(
getBuiltinTemplate() + " expects 1 or 2 arguments.");
}
int startIndex;
int seqSize = m_seq.size();
TemplateModel arg = (TemplateModel) args.get(0);
if (argcnt > 1) {
Object obj = args.get(1);
if (!(obj instanceof TemplateNumberModel)) {
throw new TemplateModelException(
getBuiltinTemplate()
+ "expects a number as its second argument.");
}
startIndex = ((TemplateNumberModel) obj).getAsNumber().intValue();
if (m_dir == 1) {
if (startIndex >= seqSize) {
return Constants.MINUS_ONE;
}
if (startIndex < 0) {
startIndex = 0;
}
} else {
if (startIndex >= seqSize) {
startIndex = seqSize - 1;
}
if (startIndex < 0) {
return Constants.MINUS_ONE;
}
}
} else {
if (m_dir == 1) {
startIndex = 0;
} else {
startIndex = seqSize - 1;
}
}
if (m_dir == 1) {
for (int i = startIndex; i < seqSize; i++) {
if (modelsEqual(m_seq.get(i), arg, m_env))
return new SimpleNumber(i);
}
} else {
for (int i = startIndex; i >= 0; i--) {
if (modelsEqual(m_seq.get(i), arg, m_env))
return new SimpleNumber(i);
}
}
return Constants.MINUS_ONE;
}
private String getBuiltinTemplate() {
if (m_dir == 1)
return "?seq_indexOf(...)";
else
return "?seq_lastIndexOf(...)";
}
}
}
static class chunkBI extends SequenceBuiltIn {
TemplateModel calculateResult(TemplateSequenceModel tsm) throws TemplateModelException {
return new BIMethod(tsm);
}
private static class BIMethod implements TemplateMethodModelEx {
private final TemplateSequenceModel tsm;
private BIMethod(TemplateSequenceModel tsm) {
this.tsm = tsm;
}
public Object exec(List args) throws TemplateModelException {
int numArgs = args.size();
if (numArgs != 1 && numArgs !=2) {
throw new TemplateModelException(
"?chunk(...) expects 1 or 2 arguments.");
}
Object chunkSize = args.get(0);
if (!(chunkSize instanceof TemplateNumberModel)) {
throw new TemplateModelException(
"?chunk(...) expects a number as "
+ "its 1st argument.");
}
return new ChunkedSequence(
tsm,
((TemplateNumberModel) chunkSize).getAsNumber().intValue(),
numArgs > 1 ? (TemplateModel) args.get(1) : null);
}
}
private static class ChunkedSequence implements TemplateSequenceModel {
private final TemplateSequenceModel wrappedTsm;
private final int chunkSize;
private final TemplateModel fillerItem;
private final int numberOfChunks;
private ChunkedSequence(
TemplateSequenceModel wrappedTsm, int chunkSize, TemplateModel fillerItem)
throws TemplateModelException {
if (chunkSize < 1) {
throw new TemplateModelException(
"The 1st argument to ?chunk(...) must be at least 1.");
}
this.wrappedTsm = wrappedTsm;
this.chunkSize = chunkSize;
this.fillerItem = fillerItem;
numberOfChunks = (wrappedTsm.size() + chunkSize - 1) / chunkSize;
}
public TemplateModel get(final int chunkIndex)
throws TemplateModelException {
if (chunkIndex >= numberOfChunks) {
return null;
}
return new TemplateSequenceModel() {
private final int baseIndex = chunkIndex * chunkSize;
public TemplateModel get(int relIndex)
throws TemplateModelException {
int absIndex = baseIndex + relIndex;
if (absIndex < wrappedTsm.size()) {
return wrappedTsm.get(absIndex);
} else {
return absIndex < numberOfChunks * chunkSize
? fillerItem
: null;
}
}
public int size() throws TemplateModelException {
return fillerItem != null || chunkIndex + 1 < numberOfChunks
? chunkSize
: wrappedTsm.size() - baseIndex;
}
};
}
public int size() throws TemplateModelException {
return numberOfChunks;
}
}
}
/*
* WARNING! This algorithm is duplication of ComparisonExpression.isTrue(...).
* Thus, if you update this method, then you have to update that too!
*/
public static boolean modelsEqual(TemplateModel model1, TemplateModel model2,
Environment env)
throws TemplateModelException {
if (env.isClassicCompatible()) {
if (model1 == null) {
model1 = TemplateScalarModel.EMPTY_STRING;
}
if (model2 == null) {
model2 = TemplateScalarModel.EMPTY_STRING;
}
}
int comp = -1;
if(model1 instanceof TemplateNumberModel && model2 instanceof TemplateNumberModel) {
Number first = ((TemplateNumberModel) model1).getAsNumber();
Number second = ((TemplateNumberModel) model2).getAsNumber();
ArithmeticEngine ae =
env != null
? env.getArithmeticEngine()
: env.getTemplate().getArithmeticEngine();
try {
comp = ae.compareNumbers(first, second);
} catch (TemplateException ex) {
throw new TemplateModelException(ex);
}
}
else if(model1 instanceof TemplateDateModel && model2 instanceof TemplateDateModel) {
TemplateDateModel ltdm = (TemplateDateModel)model1;
TemplateDateModel rtdm = (TemplateDateModel)model2;
int ltype = ltdm.getDateType();
int rtype = rtdm.getDateType();
if(ltype != rtype) {
throw new TemplateModelException(
"Can not compare dates of different type. Left date is of "
+ TemplateDateModel.TYPE_NAMES.get(ltype)
+ " type, right date is of "
+ TemplateDateModel.TYPE_NAMES.get(rtype) + " type.");
}
if(ltype == TemplateDateModel.UNKNOWN) {
throw new TemplateModelException(
"Left date is of UNKNOWN type, and can not be compared.");
}
if(rtype == TemplateDateModel.UNKNOWN) {
throw new TemplateModelException(
"Right date is of UNKNOWN type, and can not be compared.");
}
Date first = ltdm.getAsDate();
Date second = rtdm.getAsDate();
comp = first.compareTo(second);
}
else if(model1 instanceof TemplateScalarModel && model2 instanceof TemplateScalarModel) {
String first = ((TemplateScalarModel) model1).getAsString();
String second = ((TemplateScalarModel) model2).getAsString();
comp = env.getCollator().compare(first, second);
}
else if(model1 instanceof TemplateBooleanModel && model2 instanceof TemplateBooleanModel) {
boolean first = ((TemplateBooleanModel)model1).getAsBoolean();
boolean second = ((TemplateBooleanModel)model2).getAsBoolean();
comp = (first ? 1 : 0) - (second ? 1 : 0);
}
return (comp == 0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -