001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.commons.template; 018 019import java.util.*; 020 021/** 022 * Describes the names a template may read, for {@link TemplateResolver#check(String, TemplateCatalog)}. 023 * 024 * <p> 025 * A <em>field</em> is a top-level name. A <em>list</em> is a top-level name holding rows; it may carry a 026 * {@link FieldCatalog} naming the row fields, and without one any row field is accepted. 027 */ 028public final class TemplateCatalog { 029 030 private final Set<String> fields; 031 private final Map<String,FieldCatalog> lists; 032 private final boolean allowUnknownFunctions; 033 034 private TemplateCatalog(Builder b) { 035 fields = Collections.unmodifiableSet(new LinkedHashSet<>(b.fields)); 036 lists = Collections.unmodifiableMap(new LinkedHashMap<>(b.lists)); 037 allowUnknownFunctions = b.allowUnknownFunctions; 038 } 039 040 /** 041 * Creates a builder. 042 * 043 * @return A new builder. 044 */ 045 public static Builder create() { return new Builder(); } 046 047 /** Builder for {@link TemplateCatalog}. */ 048 public static final class Builder { 049 private final Set<String> fields = new LinkedHashSet<>(); 050 private final Map<String,FieldCatalog> lists = new LinkedHashMap<>(); 051 private boolean allowUnknownFunctions; 052 053 private Builder() {} 054 055 /** 056 * Declares top-level fields. 057 * 058 * @param names The names. 059 * @return This object. 060 */ 061 public Builder fields(String...names) { 062 for (var n : names) 063 fields.add(new FieldDef(n).name()); 064 return this; 065 } 066 067 /** 068 * Declares a list whose row fields are not checked. 069 * 070 * @param name The list name. 071 * @return This object. 072 */ 073 public Builder list(String name) { 074 lists.put(new FieldDef(name).name(), null); 075 return this; 076 } 077 078 /** 079 * Declares a list with its row fields. 080 * 081 * @param name The list name. 082 * @param rowFields The row fields. Must not be <jk>null</jk>. 083 * @return This object. 084 */ 085 public Builder list(String name, FieldCatalog rowFields) { 086 lists.put(new FieldDef(name).name(), Objects.requireNonNull(rowFields, "rowFields must not be null")); 087 return this; 088 } 089 090 /** 091 * Accepts function names the resolver does not know or permit. 092 * 093 * @param value Whether to accept them. Default <jk>false</jk>. 094 * @return This object. 095 */ 096 public Builder allowUnknownFunctions(boolean value) { 097 allowUnknownFunctions = value; 098 return this; 099 } 100 101 /** 102 * Builds the catalog. 103 * 104 * @return A new catalog. 105 */ 106 public TemplateCatalog build() { return new TemplateCatalog(this); } 107 } 108 109 boolean hasName(String name) { return fields.contains(name) || lists.containsKey(name); } 110 111 boolean isList(String name) { return lists.containsKey(name); } 112 113 /** @return The row catalog, or <jk>null</jk> if the list is undeclared or has none. */ 114 FieldCatalog rowFields(String list) { return lists.get(list); } 115 116 boolean allowUnknownFunctions() { return allowUnknownFunctions; } 117}