jodd.bean.BeanVisitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of redisson-all Show documentation
Show all versions of redisson-all Show documentation
Easy Redis Java client and Real-Time Data Platform. Valkey compatible. Sync/Async/RxJava3/Reactive API. Client side caching. Over 50 Redis based Java objects and services: JCache API, Apache Tomcat, Hibernate, Spring, Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Scheduler, RPC
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package jodd.bean;
import jodd.introspector.ClassDescriptor;
import jodd.introspector.ClassIntrospector;
import jodd.introspector.FieldDescriptor;
import jodd.introspector.MethodDescriptor;
import jodd.introspector.PropertyDescriptor;
import jodd.util.StringUtil;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import static jodd.util.StringPool.LEFT_SQ_BRACKET;
import static jodd.util.StringPool.RIGHT_SQ_BRACKET;
/**
* Visitor for bean properties. It extracts properties names
* from the source bean and then visits one by one.
*/
public class BeanVisitor {
public BeanVisitor(final Object source) {
this.source = source;
isSourceMap = (source instanceof Map);
}
/**
* Source bean.
*/
protected final Object source;
/**
* Flag for enabling declared properties, or just public ones.
*/
protected boolean declared;
/**
* Defines if null values should be ignored.
*/
protected boolean ignoreNullValues;
/**
* Defines if empty string should be ignored.
*/
protected boolean ignoreEmptyString;
/**
* Defines if fields should be included.
*/
protected boolean includeFields;
/**
* Indicates the the source is a Map.
*/
protected final boolean isSourceMap;
/**
* Defines if null
values should be ignored.
*/
public BeanVisitor ignoreNulls(final boolean ignoreNulls) {
this.ignoreNullValues = ignoreNulls;
return this;
}
/**
* Defines if empty string
should be ignored.
*/
public BeanVisitor ignoreEmptyString(final boolean ignoreEmptyString) {
this.ignoreEmptyString = ignoreEmptyString;
return this;
}
/**
* Defines if all properties should be copied (when set to true
)
* or only public (when set to false
, default).
*/
public BeanVisitor declared(final boolean declared) {
this.declared = declared;
return this;
}
/**
* Defines if fields without getters should be copied too.
*/
public BeanVisitor includeFields(final boolean includeFields) {
this.includeFields = includeFields;
return this;
}
// ---------------------------------------------------------------- util
/**
* Returns all bean property names.
*/
protected String[] getAllBeanPropertyNames(final Class type, final boolean declared) {
final ClassDescriptor classDescriptor = ClassIntrospector.get().lookup(type);
final PropertyDescriptor[] propertyDescriptors = classDescriptor.getAllPropertyDescriptors();
final ArrayList names = new ArrayList<>(propertyDescriptors.length);
for (final PropertyDescriptor propertyDescriptor : propertyDescriptors) {
final MethodDescriptor getter = propertyDescriptor.getReadMethodDescriptor();
if (getter != null) {
if (getter.matchDeclared(declared)) {
names.add(propertyDescriptor.getName());
}
}
else if (includeFields) {
final FieldDescriptor field = propertyDescriptor.getFieldDescriptor();
if (field != null) {
if (field.matchDeclared(declared)) {
names.add(field.getName());
}
}
}
}
return names.toArray(new String[0]);
}
/**
* Returns an array of bean properties. If bean is a Map
,
* all its keys will be returned.
*/
protected String[] resolveProperties(final Object bean, final boolean declared) {
final String[] properties;
if (bean instanceof Map) {
final Set keys = ((Map) bean).keySet();
properties = new String[keys.size()];
int ndx = 0;
for (final Object key : keys) {
properties[ndx] = key.toString();
ndx++;
}
} else {
properties = getAllBeanPropertyNames(bean.getClass(), declared);
}
return properties;
}
/**
* Starts visiting properties.
*/
public void visit(final BiConsumer propertyConsumer) {
final String[] properties = resolveProperties(source, declared);
for (final String name : properties) {
if (name == null) {
continue;
}
final Object value;
String propertyName = name;
if (isSourceMap) {
propertyName = LEFT_SQ_BRACKET + name + RIGHT_SQ_BRACKET;
}
if (declared) {
value = BeanUtil.declared.getProperty(source, propertyName);
} else {
value = BeanUtil.pojo.getProperty(source, propertyName);
}
if (value == null && ignoreNullValues) {
continue;
}
if (ignoreEmptyString && value instanceof String && StringUtil.isEmpty((String) value)) {
continue;
}
propertyConsumer.accept(name, value);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy