/** * This file is part of the CRISTAL-iSE kernel. * Copyright (c) 2001-2014 The CRISTAL Consortium. 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 3 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; with out 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. * * http://www.fsf.org/licensing/licenses/lgpl.html */ package com.c2kernel.utils; //Java import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; import java.util.HashSet; import java.util.Properties; import java.util.StringTokenizer; import org.exolab.castor.mapping.Mapping; import org.exolab.castor.mapping.MappingException; import org.exolab.castor.xml.MarshalException; import org.exolab.castor.xml.Marshaller; import org.exolab.castor.xml.Unmarshaller; import org.exolab.castor.xml.ValidationException; import org.exolab.castor.xml.XMLContext; import com.c2kernel.common.InvalidDataException; import com.c2kernel.persistency.outcome.Outcome; import com.c2kernel.process.resource.ResourceLoader; /************************************************************************** * Loads all mapfiles, and wraps marshalling/unmarshalling * * @author $Author: abranson $ $Date: 2004/10/20 14:10:21 $ * @version $Revision: 1.12 $ **************************************************************************/ public class CastorXMLUtility { public static final String CASTOR_XML_SERIALIZER_FACTORY = "org.exolab.castor.xml.serializer.factory"; private XMLContext mappingContext; /** * Looks for a file called 'index.xml' at the given URL, and loads every * file listed in there by relative path * * @param aResourceLoader * the resource loader able to return the right class loader * @param aAppProperties * the application properties containing optional castor * configuration * @param mapURL * the root URL for the mapfiles * @throws InvalidDataException */ public CastorXMLUtility(final ResourceLoader aResourceLoader, final Properties aAppProperties, final URL mapURL) throws InvalidDataException { // load index Logger.msg(3,String.format( "CastorXMLUtility. Loading maps from [%s]",mapURL)); String index; try { index = FileStringUtility.url2String( new URL(mapURL, "index") ); } catch (Exception e) { throw new InvalidDataException(String.format("Could not load map index from [%s]",mapURL)); } // retrieve the class loader of the class "CastorXMLUtility" ClassLoader defaultClassLoader = aResourceLoader .getClassLoader(CastorXMLUtility.class.getName()); Logger.msg(3, String.format( "CastorXMLUtility.: defaultClassLoader=[%s]", defaultClassLoader)); StringTokenizer sTokenizer = new StringTokenizer(index); int wNbMap = sTokenizer.countTokens(); // init the castor mapping using the classloader of the class "CastorXMLUtility" Mapping thisMapping = new Mapping(defaultClassLoader); HashSet loadedMapURLs = new HashSet(); try { int wMapIdx=0; while( sTokenizer.hasMoreTokens() ) { String thisMap = sTokenizer.nextToken(); String thisMapURL = new URL(mapURL, thisMap).toString(); wMapIdx++; if( !loadedMapURLs.contains(thisMapURL) ) { Logger.msg( 3, String.format("CastorXMLUtility.: Adding mapping file (%d/%d):[%s]", wMapIdx, wNbMap, thisMapURL)); thisMapping.loadMapping( new URL(thisMapURL) ); loadedMapURLs.add( thisMapURL ); } else { Logger.msg(3,"Map file already loaded:"+thisMapURL); } } mappingContext = new XMLContext(); mappingContext.setClassLoader(defaultClassLoader); // if the aAppProperties contains castor properties then if (aAppProperties!= null && aAppProperties.containsKey(CASTOR_XML_SERIALIZER_FACTORY)) { mappingContext.setProperty(CASTOR_XML_SERIALIZER_FACTORY, aAppProperties .getProperty(CASTOR_XML_SERIALIZER_FACTORY)); Logger.msg(3, String.format( "CastorXMLUtility.: castor prop: %s=[%s]", CASTOR_XML_SERIALIZER_FACTORY, mappingContext .getProperty(CASTOR_XML_SERIALIZER_FACTORY))); } mappingContext.addMapping(thisMapping); } catch (MappingException ex) { Logger.error(ex); throw new InvalidDataException("XML Mapping files are not valid: "+ex.getMessage()); } catch (MalformedURLException ex) { Logger.error(ex); throw new InvalidDataException("Mapping file location invalid: "+ex.getMessage()); } catch (IOException ex) { Logger.error(ex); throw new InvalidDataException("Could not read XML mapping files: "+ex.getMessage()); } Logger.msg(1, String.format("Loaded [%d] maps from [%s]", loadedMapURLs.size(), mapURL)); } /************************************************************************** * Marshalls a mapped object to string. The mapping must be loaded before. * See updateMapping(). **************************************************************************/ public String marshall( Object obj ) throws IOException, MappingException, MarshalException, ValidationException { if (obj == null) return ""; if (obj instanceof Outcome) return ((Outcome)obj).getData(); StringWriter sWriter = new StringWriter(); Marshaller marshaller = mappingContext.createMarshaller(); marshaller.setWriter(sWriter); marshaller.setMarshalAsDocument( false ); marshaller.marshal( obj ); return sWriter.toString(); } /************************************************************************** * Unmarshalls a mapped object from string. The mapping must be loaded before. * See updateMapping(). **************************************************************************/ public Object unmarshall( String data ) throws IOException, MappingException, MarshalException, ValidationException { if (data.equals("")) return null; StringReader sReader = new StringReader( data ); Unmarshaller unmarshaller = mappingContext.createUnmarshaller(); return unmarshaller.unmarshal( sReader ); } }