/* * ALMA - Atacama Large Millimiter Array * (c) European Southern Observatory, 2002 * Copyright by ESO (in the framework of the ALMA collaboration), * All rights reserved * * This library 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 2.1 of the License, or (at your option) any later version. * * This library 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 library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package alma.acs.component.dynwrapper; import java.lang.reflect.Field; import java.util.logging.Logger; /** * Maps between composite objects, delegating the translation of values * recursively if necessary. * * @author heiko */ public class CompositionMapper extends TypeMapper { /** * @see alma.acs.component.dynwrapper.TypeMapper#TypeMapper(java.lang.Object, Logger) */ public CompositionMapper(Object delegate, Logger logger) { super(delegate, logger); } /** * @see alma.acs.component.dynwrapper.TypeMapper#canTranslate(java.lang.Class, * java.lang.Class, alma.acs.component.dynwrapper.ComponentInvocationHandler) */ @SuppressWarnings("unchecked") public boolean canTranslate( Class oldObjClass, Class newObjClass, ComponentInvocationHandler invHandler) { boolean canTranslate = true; Field oldField = null; String fieldMismatchMsg = null; try { // iterate over all public members of oldObjClass and check if they can be translated // into a corresponding member of newObjClass Field[] oldFields = oldObjClass.getFields(); for (int i = 0; i < oldFields.length; i++) { oldField = oldFields[i]; Field newField = newObjClass.getField(oldField.getName()); // recursion boolean canTranslateField = invHandler.canTranslate(oldField.getType(), newField.getType()); if (!canTranslateField) { canTranslate = false; break; } } } catch (NoSuchFieldException e) { canTranslate = false; fieldMismatchMsg = "Member field '" + oldField.getName() + "' not found in " + newObjClass.getName() + "."; } if (m_verbose) { String msg = "can " + (canTranslate ? "" : "not ") + "translate from class '" + oldObjClass.getName() + "' to class '" + newObjClass.getName() + "'. "; if (fieldMismatchMsg != null) { msg += fieldMismatchMsg; } m_logger.finer(msg); } return canTranslate; } /* * TODO * Translates the object in the <code>value</code> field of <code>oldHolder</code> using some other mapper, * and sets it as the <code>value</code> of <code>newHolderTemplate</code>. * * @see alma.acs.component.dynwrapper.TypeMapper#translate(java.lang.Object, * java.lang.Object, java.lang.Class, alma.acs.component.dynwrapper.ComponentInvocationHandler) */ public <T> Object translate( Object oldObject, T newObjectTemplate, Class<T> newObjectClass, ComponentInvocationHandler invHandler) throws DynWrapperException { if (m_verbose) { m_logger.finer("will try to translate from '" + oldObject.getClass().getName() + "' to '" + newObjectClass.getName() + "'."); } if (newObjectTemplate == null) { try { newObjectTemplate = newObjectClass.newInstance(); } catch (Exception e) { throw new DynWrapperException("failed to create composition class " + newObjectClass.getName()); } } // not true, e.g. if it's a return try { Field[] oldFields = oldObject.getClass().getFields(); for (int i = 0; i < oldFields.length; i++) { Field oldValueField = oldFields[i]; Object oldValue = oldValueField.get(oldObject); Field newValueField = newObjectClass.getField(oldValueField.getName()); Object newValueTemplate = newValueField.get(newObjectTemplate); // recursion Object newValue = null; if (oldValue == null) { m_logger.warning("Field " + oldObject.getClass().getName() + "." + oldValueField.getName() + " is null. If this corresponds to a CORBA struct, the ORB will not transmit this data."); } else { newValue = invHandler.translate(oldValue, newValueTemplate, newValueField.getType()); } newValueField.set(newObjectTemplate, newValue); } } catch (Exception e) { throw new DynWrapperException(e); } if (m_verbose) { m_logger.finer("successfully translated from '" + oldObject.getClass().getName() + "' to '" + newObjectTemplate.getClass().getName() + "'."); } return newObjectTemplate; } }