@Override @SuppressWarnings("unchecked") public void init(SubsetConfiguration conf) { super.init(conf); conf.setListDelimiterHandler(new DefaultListDelimiterHandler(',')); Iterator<String> it = (Iterator<String>) conf.getKeys(); while (it.hasNext()) { String propertyName = it.next(); if (propertyName.startsWith(TAGS_FOR_PREFIX_PROPERTY_PREFIX)) { String contextName = propertyName.substring(TAGS_FOR_PREFIX_PROPERTY_PREFIX.length()); String[] tags = conf.getStringArray(propertyName); boolean useAllTags = false; Set<String> set = new HashSet<>(); for (String tag : tags) { tag = tag.trim(); useAllTags |= tag.equals("*"); if (tag.length() > 0) { set.add(tag); } } if (useAllTags) { set = null; } useTagsMap.put(contextName, set); } } }
/** * {@inheritDoc} This implementation performs delimiter escaping for a * single value (which is not part of a list). */ @Override public Object escape(final Object value, final ValueTransformer transformer) { return escapeValue(value, false, transformer); }
/** * Extracts all values contained in the given source object and returns them * as a flat collection. * * @param source the source object (may be a single value or a complex * object) * @return a collection with all extracted values */ protected Collection<?> extractValues(final Object source) { return extractValues(source, Integer.MAX_VALUE); }
/** * {@inheritDoc} This implementation checks whether the object to be escaped * is a string. If yes, it delegates to {@link #escapeString(String)}, * otherwise no escaping is performed. Eventually, the passed in transformer * is invoked so that additional encoding can be performed. */ @Override public Object escape(final Object value, final ValueTransformer transformer) { final Object escValue = (value instanceof String) ? escapeString((String) value) : value; return transformer.transformValue(escValue); }
@Override public <T> T to(final Object src, final Class<T> targetCls, final ConfigurationInterpolator ci) { final ConfigurationInterpolator interpolator = fetchInterpolator(ci); return convert(interpolator.interpolate(src), targetCls, interpolator); }
@Override public Object escapeList(final List<?> values, final ValueTransformer transformer) { final Object[] escapedValues = new String[values.size()]; int idx = 0; for (final Object v : values) { escapedValues[idx++] = escape(v, transformer); } return StringUtils.join(escapedValues, getDelimiter()); }
/** * Escapes the given property value before it is written. This method add * quotes around the specified value if it contains a comment character and * handles list delimiter characters. * * @param value the string to be escaped */ private String escapeValue(final String value) { return String.valueOf(getListDelimiterHandler().escape( escapeComments(value), ListDelimiterHandler.NOOP_TRANSFORMER)); }
/** * Convert the specified object into an Integer. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to an integer */ public static Integer toInteger(final Object value) throws ConversionException { final Number n = toNumber(value, Integer.class); if (n instanceof Integer) { return (Integer) n; } return n.intValue(); }
/** * Performs the actual work as advertised by the {@code parse()} method. * This method delegates to {@link #flatten(Object, int)} without specifying * a limit. * * @param value the value to be processed * @return a "flat" collection containing all primitive values of * the passed in object */ private Collection<?> flatten(final Object value) { return flatten(value, Integer.MAX_VALUE); }
/** * Adds the property with the specified key. This task will be delegated to * the associated {@code ExpressionEngine}, so the passed in key * must match the requirements of this implementation. * * @param key the key of the new property * @param obj the value of the new property */ @Override protected void addPropertyInternal(final String key, final Object obj) { addPropertyToModel(key, getListDelimiterHandler().parse(obj)); }
/** * Performs a conversion of a single value to the specified target class. * The passed in source object is guaranteed to be a single value, but it * can be <b>null</b>. Derived classes that want to extend the available * conversions, but are happy with the handling of complex objects, just * need to override this method. * * @param <T> the desired target type of the conversion * @param src the source object (a single value) * @param targetCls the target class of the conversion * @param ci the {@code ConfigurationInterpolator} (not <b>null</b>) * @return the converted value * @throws ConversionException if conversion is not possible */ protected <T> T convertValue(final Object src, final Class<T> targetCls, final ConfigurationInterpolator ci) { if (src == null) { return null; } // This is a safe cast because PropertyConverter either returns an // object of the correct class or throws an exception. @SuppressWarnings("unchecked") final T result = (T) PropertyConverter.to(targetCls, src, this); return result; }
/** * {@inheritDoc} This implementation handles the case that the passed in * string is <b>null</b>. In this case, an empty collection is returned. * Otherwise, this method delegates to {@link #splitString(String, boolean)}. */ @Override public Collection<String> split(final String s, final boolean trim) { if (s == null) { return new ArrayList<>(0); } return splitString(s, trim); }
/** * Helper method for converting a value to a constant of an enumeration * class. * * @param enumClass the enumeration class * @param value the value to be converted * @return the converted value */ @SuppressWarnings("unchecked") // conversion is safe because we know that the class is an Enum class private static Object convertToEnum(final Class<?> enumClass, final Object value) { return toEnum(value, enumClass.asSubclass(Enum.class)); } }
((AbstractConfiguration)configuration).setListDelimiterHandler(new DefaultListDelimiterHandler(config.listDelimiter));
/** * Convert the specified object into a Long. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a Long */ public static Long toLong(final Object value) throws ConversionException { final Number n = toNumber(value, Long.class); if (n instanceof Long) { return (Long) n; } return n.longValue(); }
/** * Extracts a maximum number of values contained in the given source object * and returns them as flat collection. This method is useful if the caller * only needs a subset of values, e.g. only the first one. * * @param source the source object (may be a single value or a complex * object) * @param limit the number of elements to extract * @return a collection with all extracted values */ protected Collection<?> extractValues(final Object source, final int limit) { return EXTRACTOR.flatten(source, limit); }
/** * Actually adds a property to this configuration. This method is called by * {@code addProperty()}. It performs list splitting if necessary and * delegates to {@link #addPropertyDirect(String, Object)} for every single * property value. * * @param key the key of the property to be added * @param value the new property value * @since 2.0 */ protected void addPropertyInternal(final String key, final Object value) { for (final Object obj : getListDelimiterHandler().parse(value)) { addPropertyDirect(key, obj); } }
/** * Convert the specified object into a Byte. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a byte */ public static Byte toByte(final Object value) throws ConversionException { final Number n = toNumber(value, Byte.class); if (n instanceof Byte) { return (Byte) n; } return n.byteValue(); }
/** * {@inheritDoc} Depending on the type of the passed in object the following * things happen: * <ul> * <li>Strings are checked for delimiter characters and split if necessary. * This is done by calling the {@code split()} method.</li> * <li>For objects implementing the {@code Iterable} interface, the * corresponding {@code Iterator} is obtained, and contained elements are * added to the resulting iteration.</li> * <li>Arrays are treated as {@code Iterable} objects.</li> * <li>All other types are directly inserted.</li> * <li>Recursive combinations are supported, e.g. a collection containing an * array that contains strings: The resulting collection will only contain * primitive objects.</li> * </ul> */ @Override public Iterable<?> parse(final Object value) { return flatten(value); }
/** * Convert the specified object into a Short. * * @param value the value to convert * @return the converted value * @throws ConversionException thrown if the value cannot be converted to a short */ public static Short toShort(final Object value) throws ConversionException { final Number n = toNumber(value, Short.class); if (n instanceof Short) { return (Short) n; } return n.shortValue(); }