001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau; 014 015import static org.apache.juneau.internal.StringUtils.*; 016 017import java.lang.annotation.*; 018import java.util.*; 019 020import org.apache.juneau.annotation.*; 021import org.apache.juneau.internal.*; 022import org.apache.juneau.reflect.*; 023import org.apache.juneau.svl.*; 024 025/** 026 * Class used to add properties to a {@link PropertyStore} from an annotation (e.g. {@link BeanConfig}). 027 * 028 * @param <T> The annotation that this <c>ConfigApply</c> reads from. 029 */ 030public abstract class ConfigApply<T extends Annotation> { 031 032 private final VarResolverSession r; 033 private final Class<T> c; 034 035 /** 036 * Constructor. 037 * 038 * @param c The annotation class. 039 * @param r The string resolver to use for resolving strings. 040 */ 041 protected ConfigApply(Class<T> c, VarResolverSession r) { 042 this.r = r == null ? VarResolver.DEFAULT.createSession() : r; 043 this.c = c; 044 } 045 046 /** 047 * Apply the specified annotation to the specified property store builder. 048 * 049 * @param a The annotation. 050 * @param ps The property store builder. 051 */ 052 public abstract void apply(AnnotationInfo<T> a, PropertyStoreBuilder ps); 053 054 055 /** 056 * Resolves the specified string. 057 * 058 * @param in The string containing variables to resolve. 059 * @return The resolved string. 060 */ 061 protected String string(String in) { 062 return r.resolve(in); 063 } 064 065 /** 066 * Resolves the specified strings in the string array. 067 * 068 * @param in The string array containing variables to resolve. 069 * @return An array with resolved strings. 070 */ 071 protected String[] strings(String[] in) { 072 String[] out = new String[in.length]; 073 for (int i = 0; i < in.length; i++) 074 out[i] = r.resolve(in[i]); 075 return out; 076 } 077 078 /** 079 * Resolves the specified string as a comma-delimited list of strings. 080 * 081 * @param in The CDL string containing variables to resolve. 082 * @return An array with resolved strings. 083 */ 084 protected String[] strings(String in) { 085 in = r.resolve(in); 086 return StringUtils.split(in); 087 } 088 089 /** 090 * Resolves the specified strings as a maps of strings-to-strings. 091 * 092 * @param in The string array containing variables to resolve. 093 * @param loc The annotation field name. 094 * @return A map of strings-to-strings. 095 */ 096 protected Map<String,String> stringsMap(String[] in, String loc) { 097 Map<String,String> m = new LinkedHashMap<>(); 098 for (String s : strings(in)) { 099 for (String s2 : split(s, ';')) { 100 int i = s2.indexOf(':'); 101 if (i == -1) 102 throw new ConfigException("Invalid syntax for key/value pair on annotation @{0}({1}): {2}", c.getSimpleName(), loc, s2); 103 m.put(s2.substring(0, i).trim(), s2.substring(i+1).trim()); 104 } 105 } 106 return m; 107 } 108 109 /** 110 * Resolves the specified string and converts it to a boolean. 111 * 112 * @param in The string containing variables to resolve. 113 * @return The resolved boolean. 114 */ 115 public boolean bool(String in) { 116 return Boolean.parseBoolean(r.resolve(in)); 117 } 118 119 /** 120 * Resolves the specified string and converts it to an int. 121 * 122 * @param in The string containing variables to resolve. 123 * @param loc The annotation field name. 124 * @return The resolved int. 125 */ 126 protected int integer(String in, String loc) { 127 try { 128 return Integer.parseInt(r.resolve(in)); 129 } catch (NumberFormatException e) { 130 throw new ConfigException("Invalid syntax for integer on annotation @{0}({1}): {2}", c.getSimpleName(), loc, in); 131 } 132 } 133 134 /** 135 * Resolves the specified string and converts it to a Visibility. 136 * 137 * @param in The string containing variables to resolve. 138 * @param loc The annotation field name. 139 * @return The resolved Visibility. 140 */ 141 protected Visibility visibility(String in, String loc) { 142 try { 143 return Visibility.valueOf(r.resolve(in)); 144 } catch (IllegalArgumentException e) { 145 throw new ConfigException("Invalid syntax for visibility on annotation @{0}({1}): {2}", c.getSimpleName(), loc, in); 146 } 147 } 148 149 /** 150 * Resolves the specified strings and converts it to an ObjectMap. 151 * 152 * @param in The strings to be concatenated and parsed into an ObjectMapl. 153 * @param loc The annotation field name. 154 * @return The resolved ObjectMap. 155 */ 156 protected ObjectMap objectMap(String[] in, String loc) { 157 return objectMap(joinnl(strings(in)), loc); 158 } 159 160 /** 161 * Resolves the specified string and converts it to an ObjectMap. 162 * 163 * @param in The string to be parsed into an ObjectMapl. 164 * @param loc The annotation field name. 165 * @return The resolved ObjectMap. 166 */ 167 protected ObjectMap objectMap(String in, String loc) { 168 try { 169 if (! isObjectMap(in, true)) 170 in = "{" + in + "}"; 171 return new ObjectMap(in); 172 } catch (Exception e) { 173 throw new ConfigException("Invalid syntax for Simple-JSON on annotation @{0}({1}): {2}", c.getSimpleName(), loc, in); 174 } 175 } 176}