/** * Construct node object. * * @param object wrapped object. */ public ObjectNode(Object object) { this.converter = ConverterRegistry.getConverter(); this.object = object; }
/** * An object is <em>strict object</em> if is not value type, that is, there is no converter for it. * * @param object object instance to check. * @return true if <code>object</code> is <em>strict object</em>. */ private boolean isStrictObject(Object object) { return !ConverterRegistry.hasType(object.getClass()); } }
/** * Convenient way to retrieve converter instance, see {@link #getConverterInstance()}. * * @return converter instance. */ public static Converter getConverter() { return instance.getConverterInstance(); }
if (!propertyPath.equals(".") && ConverterRegistry.hasType(scope.getClass())) { throw new TemplateException("Operand is property path but scope is not an object."); Object object = this.content.getObject(scope, propertyPath); if (object != null) { if (!ConverterRegistry.hasType(object.getClass())) { throw new TemplateException("Invalid element |%s|. Operand for VALUE operator without formatter should be convertible to string.", element); value = ConverterRegistry.getConverter().asString(object);
if(Types.isKindOf(valueType, Converter.class)) { registerConverter(valueType, (Class<? extends Converter>)valueType); registerConverterInstance(valueType, entries.getValue());
ConverterRegistry.getInstance().registerConverter(valueType, converterClass);
registerConverter(entry.getKey(), entry.getValue());
/** * Convenient way to test for converter support, see {@link #hasClassConverter(Class)}. Note that this predicate * variant accepts {@link Type} as parameter to simplify integration with user code but always returns false if type * is not a {@link Class}. * * @param valueType value type to check for conversion support. * @return true if value type has registered converter. */ public static boolean hasType(Type valueType) { return valueType instanceof Class ? instance.hasClassConverter((Class<?>)valueType) : false; }
/** * Register user defined converter associated to value type. Converter class should be instantiable, i.e. not * abstract, interface or void, must have no arguments constructor, even if private and its constructor should of * course execute without exception. Otherwise unchecked exception may arise as described on throws section. There are * no other constrains on value type class. * <p> * Note: it is caller responsibility to enforce proper bound, i.e. given converter class to properly handle requested * value type. Otherwise exception may throw when this particular converter is enacted. * * @param valueType value type class, * @param converterClass specialized converter class. * @throws BugError if converter class is not instantiable. * @throws NoSuchBeingException if converter class has no default constructor. * @throws InvocationException with target exception if converter class construction fails on its execution. */ public void registerConverter(Class<?> valueType, Class<? extends Converter> converterClass) { Converter converter = Classes.newInstance(converterClass); if(Types.isConcrete(valueType)) { registerConverterInstance(valueType, converter); } else { if(abstractConverters.put(valueType, converter) == null) { log.debug("Register abstract converter |%s| for value type |%s|.", converterClass, valueType); } else { log.warn("Override abstract converter |%s| for value type |%s|.", converterClass, valueType); } } }
return format.format(value); if (!Types.isPrimitiveLike(value) && !ConverterRegistry.hasType(value.getClass())) { throw new TemplateException("Value |%s#%s| should be a primitive like but is |%s|.", scope.getClass(), propertyPath, value.getClass()); return ConverterRegistry.getConverter().asString(value);
/** * Construct list node for a given list component type. * * @param object wrapped list, * @param componentType list component type. */ public ListNode(Object object, Class<?> componentType) { this.converter = ConverterRegistry.getConverter(); this.list = (List<Object>) object; this.componentType = componentType; }
throw new BugError("Generic value types are not supported."); if (ConverterRegistry.hasType(type)) { return ConverterRegistry.getConverter().asObject(value, (Class<T>) type); Converter converter = ConverterRegistry.getConverter(); for (String s : strings) { collection.add(converter.asObject(s.trim(), itemType));
if (!propertyPath.equals(".") && ConverterRegistry.hasType(scope.getClass())) { throw new TemplateException("Operand is property path but scope is not an object.");
/** * Check if registry instance has registered converter for requested class. * * @param classConverter class to check for conversion support. * @return true if this converter registry has support for requested class. */ public boolean hasClassConverter(Class<?> classConverter) { return getConverter(classConverter) != null || String.class.equals(classConverter); }
Converter converter = ConverterRegistry.getConverter(); try { if (Types.isBoolean(value)) { if (value instanceof String || ConverterRegistry.hasType(value.getClass())) { writeString(converter.asString(value)); return;
/** * Execute TITLE operator. Uses property path to extract content value, convert it to string and set <em>title</em> * attribute. * * @param element context element, unused, * @param scope scope object, * @param propertyPath property path, * @param arguments optional arguments, unused. * @return always returns null for void. * @throws TemplateException if requested content value is undefined. */ @Override protected Object doExec(Element element, Object scope, String propertyPath, Object... arguments) throws TemplateException { if (!propertyPath.equals(".") && ConverterRegistry.hasType(scope.getClass())) { throw new TemplateException("Operand is property path but scope is not an object."); } Object value = content.getObject(scope, propertyPath); if (value == null) { return null; } if (!(value instanceof String)) { throw new TemplateException("Invalid element |%s|. TITLE operand should be string.", element); } return new AttrImpl("title", (String) value); } }
/** * Construct array node. * * @param array wrapped array. */ public ArrayNode(Object array) { this.converter = ConverterRegistry.getConverter(); this.array = array; this.componentType = array.getClass().getComponentType(); }
Converter converter = ConverterRegistry.getConverter(); if (type == null) { return new MissingFieldValue(converter); return new CollectionValue(converter, type); if (type instanceof Class<?> && ConverterRegistry.hasType(type)) { return new PrimitiveValue(converter, (Class<?>) type);
/** * Execute HREF operator. Uses property path to extract content value, convert it to string and set <em>href</em> attribute. * * @param element context element, unused, * @param scope scope object, * @param propertyPath property path, * @param arguments optional arguments, unused. * @return always returns null for void. * @throws TemplateException if requested content value is undefined. */ @Override protected Object doExec(Element element, Object scope, String propertyPath, Object... arguments) throws TemplateException { if (!propertyPath.equals(".") && ConverterRegistry.hasType(scope.getClass())) { throw new TemplateException("Operand is property path but scope is not an object."); } Object value = content.getObject(scope, propertyPath); if (value == null) { return null; } if (value instanceof URL) { value = ((URL) value).toExternalForm(); } if (!(value instanceof String)) { throw new TemplateException("Invalid element |%s|. HREF operand should be URL or string.", element); } return new AttrImpl("href", (String) value); } }
@Override public void setProperty(String name, Object value) { if (!(value instanceof String)) { value = ConverterRegistry.getConverter().asString(value); } contextParameters.put(name, value); }