org.refcodes.mixin.Dumpable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-mixin Show documentation
Show all versions of refcodes-mixin Show documentation
Artifact for mixins of general interest.
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// =============================================================================
// This code is copyright (c) by Siegfried Steiner, Munich, Germany, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// =============================================================================
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// together with the GPL linking exception applied; as being applied by the GNU
// Classpath ("http://www.gnu.org/software/classpath/license.html")
// =============================================================================
// Apache License, v2.0 ("http://www.apache.org/licenses/TEXT-2.0")
// =============================================================================
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////
package org.refcodes.mixin;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* Dumps the state of the instance into a {@link Map}. Each property
* representing the implementing class's state should be dumped into a separate
* key/value pair of the {@link Map}. The default implementation of this
* interface applies basic reflection mechanisms to create a dump of the
* implementing instance's state.
*/
public interface Dumpable {
/**
* Dumps the state of the implementing instance into a {@link Map} which is
* returned as result. The {@link #toDump()} method may call the
* {@link #toDump(Map)} methods of internal instances also being part of the
* state. The default implementation creates a new {@link Map} and calls
* {@link #toDump(Map)}. So you most probably implement the
* {@link #toDump(Map)} method.
*
* @return The {@link Map} with the dumped properties of the implementing
* instance.
*/
default Map toDump() {
return toDump( new HashMap<>() );
}
/**
* Dumps the state of the implementing instance into the provided
* {@link Map} which is returned as result. The {@link #toDump(Map)} method
* may call the {@link #toDump(Map)} methods of internal instances also
* being part of the state. You most probably implement the
* {@link #toDump(Map)} method as the {@link #toDump()} method has a default
* implementation invoking {@link #toDump(Map)} with an empty {@link Map}.
* This default implementation uses reflection to create a basic dump.
* {@link Map} properties are processed but not recursively digged into.
* Existing properties are overwritten in case shadowing super-class's
* properties.
*
* @param aDump the {@link Map} where to dump to.
*
* @return The {@link Map} with the dumped properties of the implementing
* instance.
*/
default Map toDump( Map aDump ) {
Field[] eFields;
String eFieldName;
Object eValue;
Map, ?> eMap;
Map eDump;
String eStringValue;
Class> eClass = getClass();
String eKeyString;
if ( this instanceof Map ) {
eMap = (Map, ?>) this;
for ( Object eKey : eMap.keySet() ) {
eValue = eMap.get( eKey );
try {
aDump.put( eKey != null ? eKey.toString() : null, eValue != null ? eValue.toString() : null );
}
// ---------------------------------------------
// In case the Map does not support null values:
// ---------------------------------------------
catch ( NullPointerException e ) {
eKeyString = eKey != null ? eKey.toString() : "null";
eStringValue = eValue != null ? eValue.toString() : "null";
aDump.put( eKeyString, eStringValue );
}
// ---------------------------------------------
}
}
do {
eFields = eClass.getDeclaredFields();
for ( Field eField : eFields ) {
eFieldName = eField.getName();
try {
// Don't in Java 9 |-->
try {
eField.setAccessible( true );
}
catch ( Exception ignore ) {}
// Don't in Java 9 <--|
eValue = eField.get( this );
if ( eValue instanceof Dumpable ) {
eDump = ( (Dumpable) eValue ).toDump();
for ( String eKey : eDump.keySet() ) {
aDump.put( eFieldName + "." + eKey, eDump.get( eKey ) );
}
}
else {
if ( eValue instanceof Map ) {
eMap = (Map, ?>) eValue;
for ( Object eKey : eMap.keySet() ) {
eValue = eMap.get( eKey );
try {
eKeyString = eKey != null ? eKey.toString() : null;
eStringValue = eValue != null ? eValue.toString() : null;
aDump.put( eFieldName + "." + eKeyString, eStringValue );
}
// ---------------------------------------------
// In case the Map does not support null values:
// ---------------------------------------------
catch ( NullPointerException e ) {
eKeyString = eKey != null ? eKey.toString() : "null";
eStringValue = eValue != null ? eValue.toString() : "null";
aDump.put( eFieldName + "." + eKeyString, eStringValue );
}
// ---------------------------------------------
}
}
else {
eStringValue = eValue != null ? eValue.toString() : null;
aDump.put( eFieldName, eStringValue );
}
}
}
catch ( IllegalArgumentException | IllegalAccessException e ) {
aDump.put( eFieldName, "(unaccessible field)" );
}
}
eClass = eClass.getSuperclass();
} while ( eClass != null );
return aDump;
}
/**
* Creates a printable representation of the content of this map.
*
* @return A {@link String} with the content of this map which directly can
* be printed.
*/
// default String toPrintable() {
// StringBuilder theBuilder = new StringBuilder();
// String eValue;
// Map theDump = toDump();
// List theKeys = new ArrayList<>( theDump.keySet() );
// Collections.sort( theKeys );
// for ( String eKey : theKeys ) {
// eValue = theDump.get( eKey );
// if ( eValue != null ) {
// eValue = "\"" + eValue + "\"";
// }
// else {
// eValue = "null";
// }
// theBuilder.append( "\"" + eKey + "\" = " + eValue );
// theBuilder.append( System.lineSeparator() );
// }
// return theBuilder.toString();
// }
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy