Skip to content

Commit

Permalink
Bugfixes to object printers; added RotePrintHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvainhalle committed Apr 27, 2019
1 parent 97aaafe commit 8e6ff8f
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 34 deletions.
20 changes: 20 additions & 0 deletions Source/Core/src/ca/uqac/lif/azrael/ObjectPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,24 @@ public static String getVersionString()
{
return "2.0";
}

/**
* Adds a handler to the printer
* @param h The handler
*/
public void addHandler(PrintHandler<T> h)
{
m_handlers.add(h);
}

/**
* Sets whether the printer uses the {@link Printable} interface when an
* object provides one.
* @param b Set to <tt>true</tt> to use the interface, <tt>false</tt> to
* override it
*/
public void setUsePrintable(boolean b)
{
m_usePrintable = b;
}
}
61 changes: 35 additions & 26 deletions Source/Core/src/ca/uqac/lif/azrael/ObjectReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ public abstract class ObjectReader<T>
* Additional class loaders
*/
protected Set<ClassLoader> m_classLoaders;

/**
* A list of objects that handle the printing of objects of various
* types
*/
protected List<ReadHandler<T>> m_handlers;

/**
* The default handler to use when no other accepts an object
*/
protected ReadHandler<T> m_reflectionHandler = new ReflectionReadHandler<T>(this);

/**
* Creates a new object reader
*/
Expand Down Expand Up @@ -154,7 +154,7 @@ public Object getInstance(Class<?> clazz) throws ReadException
}
return o;
}

/**
* Adds a new class loader used to create new class instances
* @param cl The class loader
Expand Down Expand Up @@ -214,27 +214,36 @@ public Class<?> findClass(String class_name) throws ClassNotFoundException
*/
public static void setField(Object o, String field_name, Object value) throws ReadException
{
if (o == null)
{
return;
}
try
{
Field fld = ReflectionPrintHandler.getFromAllFields(field_name, o.getClass());
fld.setAccessible(true);
fld.set(o, value);
}
catch (NoSuchFieldException e)
{
throw new ReadException(e);
}
catch (IllegalArgumentException e)
{
throw new ReadException(e);
}
catch (IllegalAccessException e)
{
throw new ReadException(e);
}
if (o == null)
{
return;
}
try
{
Field fld = ReflectionPrintHandler.getFromAllFields(field_name, o.getClass());
fld.setAccessible(true);
fld.set(o, value);
}
catch (NoSuchFieldException e)
{
throw new ReadException(e);
}
catch (IllegalArgumentException e)
{
throw new ReadException(e);
}
catch (IllegalAccessException e)
{
throw new ReadException(e);
}
}

/**
* Adds a handler to the reader
* @param h The handler
*/
public void addHandler(ReadHandler<T> h)
{
m_handlers.add(h);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ public class ReflectionPrintHandler<T> implements PrintHandler<T>
* The internal object printer
*/
protected ObjectPrinter<T> m_printer;

/**
* Whether the fields marked as <tt>transient</tt> should be ignored
*/
protected boolean m_ignoreTransient = true;

/**
* Creates a new reflection print handler
* @param p The internal object printer
Expand Down Expand Up @@ -88,12 +88,12 @@ public T handle(Object o) throws PrintException
}
return encapsulateFields(o, contents);
}

protected T encapsulateFields(Object o, Map<String,Object> contents) throws PrintException
{
return m_printer.wrap(o, m_printer.print(contents));
}

protected static List<Field> getAllFields(List<Field> fields, Class<?> type)
{
fields.addAll(Arrays.asList(type.getDeclaredFields()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public void store(Object o) throws FridgeException
{
throw new FridgeException(e);
}
m_printer.reset();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public Number getSize(Object o) throws PrintException
}
return size;
}
if (o instanceof ArrayList || o instanceof ArrayDeque)
if (o instanceof ArrayList)
{
ArrayList<?> col = (ArrayList<?>) o;
int size = 48 + 4 * col.size();
Expand All @@ -97,7 +97,16 @@ public Number getSize(Object o) throws PrintException
}
return size;
}
if (o instanceof ArrayDeque)
{
ArrayDeque<?> col = (ArrayDeque<?>) o;
int size = 48 + 4 * col.size();
for (Object elem : col)
{
size += (Integer) m_printer.print(elem);
}
return size;
}
return 0;
}

}
41 changes: 41 additions & 0 deletions Source/Size/src/ca/uqac/lif/azrael/size/NullPrintHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
Azrael, a serializer for Java objects
Copyright (C) 2016-2019 Sylvain Hallé
Laboratoire d'informatique formelle
Université du Québec à Chicoutimi, Canada
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ca.uqac.lif.azrael.size;

import ca.uqac.lif.azrael.PrintException;

public class NullPrintHandler extends ReferencePrintHandler
{
public NullPrintHandler(SizePrinter printer)
{
super(printer);
}

@Override
public boolean canHandle(Object o)
{
return o == null;
}

@Override
public Number getSize(Object o) throws PrintException
{
return 0;
}
}
80 changes: 80 additions & 0 deletions Source/Size/src/ca/uqac/lif/azrael/size/RotePrintHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
Azrael, a serializer for Java objects
Copyright (C) 2016-2019 Sylvain Hallé
Laboratoire d'informatique formelle
Université du Québec à Chicoutimi, Canada
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ca.uqac.lif.azrael.size;

import java.util.IdentityHashMap;

import ca.uqac.lif.azrael.PrintHandler;

/**
* Print handler that returns a fixed size value for all objects matching
* a given class name. Adding such a handler to a size printer can be useful
* to cut off the recursive decomposition of "strange" objects.
*
* @author Sylvain Hallé
*/
public class RotePrintHandler implements PrintHandler<Number>
{
/**
* A map of already seen objects
*/
protected IdentityHashMap<Object,Integer> m_seenObjects;

/**
* The name of the class to match
*/
protected String m_className;

/**
* The size to return for this object
*/
protected int m_sizeToReturn;

public RotePrintHandler(String class_name, int size)
{
super();
m_className = class_name;
m_sizeToReturn = size;
m_seenObjects = new IdentityHashMap<Object,Integer>();
}

@Override
public boolean canHandle(Object o)
{
return o != null && o.getClass().getSimpleName().compareTo(m_className) == 0;
}

@Override
public Number handle(Object o)
{
// We count objects only once
if (m_seenObjects.containsKey(o))
{
return 0;
}
m_seenObjects.put(o, 1);
return m_sizeToReturn;
}

@Override
public void reset()
{
m_seenObjects.clear();
}
}
3 changes: 2 additions & 1 deletion Source/Size/src/ca/uqac/lif/azrael/size/SizePrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

public class SizePrinter extends ObjectPrinter<Number>
{
public static final int OBJECT_SHELL_SIZE = 8;
public static final int OBJECT_SHELL_SIZE = 24;
public static final int OBJREF_SIZE = 4;
public static final int LONG_FIELD_SIZE = 8;
public static final int INT_FIELD_SIZE = 4;
Expand All @@ -37,6 +37,7 @@ public class SizePrinter extends ObjectPrinter<Number>
public SizePrinter()
{
super();
m_handlers.add(new NullPrintHandler(this));
m_handlers.add(new NumberPrintHandler());
m_handlers.add(new StringPrintHandler(this));
m_handlers.add(new BooleanPrintHandler());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public Number handle(Object o) throws PrintException
return 0;
}
m_seenObjects.put(o, 1);
int size = 24; // Basic overhead of a Java object
int size = SizePrinter.OBJECT_SHELL_SIZE; // Basic overhead of a Java object
for (Field field : getAllFields(o.getClass()))
{
// Is this field declared as transient?
Expand Down

0 comments on commit 8e6ff8f

Please sign in to comment.