/* * 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.entityutil; import java.io.IOException; import java.io.StringWriter; import java.util.logging.Logger; import org.exolab.castor.xml.Marshaller; import alma.entities.commonentity.EntityT; import alma.xmlentity.XmlEntityStruct; /** * Serializes entity objects. * These are instances of binding classes that represent the XML data in a type-safe Java API. * Currently all binding classes are generated using the Castor tool. * <p> * @author hsommer May 6, 2003 5:31:48 PM */ public class EntitySerializer { private static EntitySerializer s_entitySerializer; private Logger m_logger; private boolean m_verbose; private XmlEntityStructFactory m_esf; private EntityTFinder m_finder; /** * Singleton accessor. * * @param logger Logger to be used * (may be null in subsequent invocations since only one instance of * EntitySerializer is constructed and then reused) * * @return single instance */ public static EntitySerializer getEntitySerializer(Logger logger) { if (s_entitySerializer == null) { s_entitySerializer = new EntitySerializer(logger); } return s_entitySerializer; } private EntitySerializer(Logger logger) { m_logger = logger; m_esf = new DefaultXmlEntityStructFactory(); m_finder = new EntityTFinder(m_logger); setVerbose(false); } /** * Makes this <code>EntitySerializer</code> use a client-supplied factory * for <code>XmlEntityStruct</code> objects. * <p> * You should use this method if you wish to get a subclass of * <code>alma.xmlentity.XmlEntityStruct</code> returned from the * <code>serializeEntity</code> methods. * * @param esf the factory to be used */ public void setXmlEntityFactory(XmlEntityStructFactory esf) { m_esf = esf; } /** * Marshals an entity object to the CORBA struct used for transport. * * @param entityObject the entity object as a binding class, currently generated by castor. * @param entityMeta usually subtype of <code>EntityT</code>. * @return the struct that contains the stringified xml and some other data; * null if <code>entityObject</code> is null. */ public XmlEntityStruct serializeEntity(Object entityObject, EntityT entityMeta) throws EntityException { if (entityObject == null) { return null; } if (entityMeta == null) { throw new EntityException("Entity administrational data of type EntityT must not be null. " + "(object of type " + entityObject.getClass().getName() + ")"); } XmlEntityStruct entStruct = m_esf.createXmlEntityStruct(); try { entStruct.entityId = entityMeta.getEntityId(); entStruct.entityTypeName = entityMeta.getEntityTypeName(); entStruct.schemaVersion = ( entityMeta.getSchemaVersion() != null ? entityMeta.getSchemaVersion() : ""); entStruct.timeStamp = ( entityMeta.getTimestamp() != null ? entityMeta.getTimestamp() : ""); entStruct.xmlString = serializeEntityPart(entityObject); } catch (Exception e) { throw new EntityException(e); } return entStruct; } /** * Marshals an entity object to the CORBA struct used for transport. * Unlike in {@link #serializeEntity(Object, EntityT)}, the child of type * <code>EntityT</code> that has the administrational information about the * entity object, is not given as a parameter. * It will be accessed dynamically using {@link EntityTFinder}, which makes this * method slightly slower than its 2-parameter companion. * It's meant to be used rather by generic code that doesn't know about particular entity classes. * * @param entityObject the entity object as a binding class * @return the struct that contains the stringified xml and some other data; * null if <code>entityObject</code> is null. */ public XmlEntityStruct serializeEntity(Object entityObject) throws EntityException { if (entityObject == null) { return null; } EntityT entityMeta = m_finder.extractEntityT(entityObject); return serializeEntity(entityObject, entityMeta); } /** * Serializes a binding class object which is a part (child node) of some other full Entity object. * @param entityPart the binding object, e.g. of type <code>alma.entity.xmlbinding.schedblock.CorrelatorConfigT</code>. * @return a plain XML String that represents the data of <code>entityPart</code>. * @throws EntityException if the operation could not be performed * @see #serializeEntity(Object) * @see #serializeEntity(Object, EntityT) */ public String serializeEntityPart(Object entityPart) throws EntityException { try { StringWriter wr = new StringWriter(); Marshaller marsh = createMarshaller(wr); marsh.setValidation(false); marsh.marshal(entityPart); return wr.toString(); } catch (Exception e) { throw new EntityException("failed to serialize entity part of type '" + entityPart.getClass().getName() + "'.", e); } } protected Marshaller createMarshaller(StringWriter wr) throws IOException { return new Marshaller(wr); } public void setVerbose(boolean verbose) { m_verbose = verbose; m_finder.setVerbose(m_verbose); } }