All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cristalise.kernel.utils.CastorXMLUtility Maven / Gradle / Ivy

/**
 * This file is part of the CRISTAL-iSE kernel.
 * Copyright (c) 2001-2015 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 org.cristalise.kernel.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 javax.xml.transform.Result;

import org.cristalise.kernel.common.InvalidDataException;
import org.cristalise.kernel.persistency.outcome.Outcome;
import org.cristalise.kernel.process.resource.ResourceLoader;
import org.cristalise.kernel.querying.Query;
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.ValidationException;
import org.exolab.castor.xml.XMLContext;

/**
 * Loads all castor mapfiles, and wraps marshalling/unmarshalling
 */
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' 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
     */
    public CastorXMLUtility(final ResourceLoader aResourceLoader, final Properties aAppProperties, final URL mapURL)
            throws InvalidDataException
    {
        // load index
        Logger.msg(3, "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, "CastorXMLUtility.: defaultClassLoader=[%s]", defaultClassLoader);

        StringTokenizer sTokenizer = new StringTokenizer(index);
        int wNbMap = sTokenizer.countTokens();

        // init the castor mapping using the classloader of this class
        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, "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, "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, "Loaded [%d] maps from [%s]", loadedMapURLs.size(), mapURL);
    }

    /**
     * Marshalls a mapped object to xml string. The mapping must be loaded before. See updateMapping().
     *
     * @param obj the object to be marshalled
     * @return the xml string of the marshalled object
     */
    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);

        if (obj instanceof Query) marshaller.addProcessingInstruction(Result.PI_DISABLE_OUTPUT_ESCAPING, "");

        marshaller.marshal(obj);

        return sWriter.toString();
    }

    /**
     * Unmarshalls a mapped object from XML string. The mapping must be loaded before. See updateMapping().
     *
     * @param data the string to be unmarshalled
     * @return the unmarshalled object
     */
    public Object unmarshall(String data) throws IOException, MappingException, MarshalException, ValidationException {
        if (data.equals("")) return null;

        StringReader sReader = new StringReader(data);

        return mappingContext.createUnmarshaller().unmarshal(sReader);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy