/* * Encog(tm) Core v2.5 - Java Version * http://www.heatonresearch.com/encog/ * http://code.google.com/p/encog-java/ * Copyright 2008-2010 Heaton Research, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * For more information on Heaton Research copyrights, licenses * and trademarks visit: * http://www.heatonresearch.com/copyright */ package org.encog.persist.persistors.generic; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import org.encog.parse.tags.write.WriteXML; import org.encog.persist.EncogPersistedObject; import org.encog.persist.PersistError; import org.encog.persist.annotations.EGAttribute; import org.encog.persist.annotations.EGReference; import org.encog.persist.persistors.PersistorUtil; import org.encog.util.obj.ReflectionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A generic class used to take an object and produce XML for it. Some of the * Encog persistors make use of this class. The Encog generic persistor makes * use of this class. * * @author jheaton * */ public class Object2XML { /** * The logging object. */ @SuppressWarnings("unused") private final Logger logger = LoggerFactory.getLogger(this.getClass()); public static final String REFF_ID = "idx"; /** * The XML writer used. */ private WriteXML out; /** * The object tagger, allows the objects to be tagged with references. */ private final ObjectTagger tagger = new ObjectTagger(); /** * Save the object to XML. * * @param encogObject * The object to save. * @param out * The XML writer. */ public void save(final EncogPersistedObject encogObject, final WriteXML out) { this.out = out; try { PersistorUtil.beginEncogObject(encogObject.getClass() .getSimpleName(), out, encogObject, true); this.tagger.analyze(encogObject); for (final Field childField : ReflectionUtil .getAllFields(encogObject.getClass())) { if (ReflectionUtil.shouldAccessField(childField, true)) { childField.setAccessible(true); final Object childValue = childField.get(encogObject); out.beginTag(childField.getName()); saveField(childValue); out.endTag(); } } out.endTag(); } catch (final IllegalAccessException e) { throw new PersistError(e); } } /** * Save a collection. * * @param value * The collection to save * @throws IllegalAccessException An error. */ private void saveCollection(final Collection< ? > value) throws IllegalAccessException { for (final Object obj : value) { saveObject(obj); } } /** * Save a field. * @param fieldObject The field to save. * @throws IllegalAccessException An error. */ private void saveField(final Object fieldObject) throws IllegalAccessException { if (fieldObject != null) { if (fieldObject instanceof Collection< ? >) { saveCollection((Collection< ? >) fieldObject); } else if( fieldObject.getClass().isEnum() ) { this.out.addText(fieldObject.toString()); } else if (ReflectionUtil.isPrimitive(fieldObject) || ReflectionUtil.isSimple(fieldObject)) { this.out.addText(fieldObject.toString()); } else if (fieldObject instanceof String) { this.out.addText(fieldObject.toString()); } else { saveObject(fieldObject); } } } /** * Save a field by reference. * @param fieldObject The field to save. */ private void saveFieldReference(final Object fieldObject) { if (this.tagger.hasReference(fieldObject)) { this.out.addAttribute("ref", "" + this.tagger.getReference(fieldObject)); } else { this.out.addAttribute("ref", ""); } this.out.beginTag(fieldObject.getClass().getSimpleName()); this.out.endTag(); } /** * Save an object. * @param obj The object. * @throws IllegalAccessException An error. */ private void saveObject(final Object obj) throws IllegalAccessException { // ignore arrays if( obj.getClass().isArray() ) return; // does this object have an ID? if (this.tagger.hasReference(obj)) { final int id = this.tagger.getReference(obj); this.out.addAttribute(REFF_ID, "" + id); } // get all fields final Collection<Field> allFields = ReflectionUtil .getAllFields(obj.getClass()); // handle attributes for (final Field childField : allFields) { childField.setAccessible(true); if (ReflectionUtil.shouldAccessField(childField, false) && (childField.getAnnotation(EGAttribute.class) != null)) { final Object childValue = childField.get(obj); this.out.addAttribute(childField.getName(), childValue .toString()); } } // handle actual fields this.out.beginTag(obj.getClass().getSimpleName()); for (final Field childField : allFields) { childField.setAccessible(true); if (ReflectionUtil.shouldAccessField(childField, false) && (childField.getAnnotation(EGAttribute.class) == null)) { final Object childValue = childField.get(obj); this.out.beginTag(childField.getName()); if (childField.getAnnotation(EGReference.class) != null) { saveFieldReference(childValue); } else { saveField(childValue); } this.out.endTag(); } } this.out.endTag(); } }