/** * */ package cz.cuni.mff.peckam.java.origamist.jaxb; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import cz.cuni.mff.peckam.java.origamist.jaxb.AdditionalTransforms.AdditionalTransform; /** * A map of additional transforms. * * @author Martin Pecka */ public class AdditionalTransforms extends HashMap<String, List<AdditionalTransform>> { /** */ private static final long serialVersionUID = -4282035140752973698L; /** * Add an additional transform that is to be applied in addition to the transforms fetched from * {@link BindingsManager} * * @param transform The additional transform. The fromSchema and toSchema will be ignored. * @param location The location of the transform. * @param execIfSchemataEqual Whether to run this transform even if the XML's schema is in the newest version. * @param namespaces The list of source namespaces for which this transform has to be applied. A <code>null</code> * namespace (or namespaces omitted at all) means this transform has to be executed for all source * namespaces (beware: the setting of execIfSchemataEqual can disable the transform if the source * namespace is equal to the target one). */ public void add(TransformInfo transform, TransformLocation location, boolean execIfSchemataEqual, String... namespaces) { AdditionalTransform item = new AdditionalTransform(transform, location, execIfSchemataEqual); String[] namespaces2 = namespaces; if (namespaces2 == null) namespaces2 = new String[] { null }; for (String namespace : namespaces) { List<AdditionalTransform> transforms = get(namespace); if (transforms == null) { put(namespace, new LinkedList<AdditionalTransform>()); transforms = get(namespace); } transforms.add(item); } } /** * Get the transforms that are to be applied to the schema with the given namespace. * * It holds that "start _join_ beforeUnmarshaller _join_ end == the_returned_list". * * @param namespace The source namespace to get additional transforms for. * @param equalNamespaces If true, suppose that namespace is also the target namespace. * @param start List of transforms to be added before the classic ones. * @param beforeUnmarshaller List of transforms to be added before the unmarshaller. * @param end List of transforms to be added after the unmarshaller. * @return The transforms that are to be applied to the schema with the given namespace. If no transform is to be * applied, an empty list will be returned. */ protected List<AdditionalTransform> getTransforms(String namespace, boolean equalNamespaces, List<AdditionalTransform> start, List<AdditionalTransform> beforeUnmarshaller, List<AdditionalTransform> end) { List<AdditionalTransform> nullTransforms = get(null); List<AdditionalTransform> namespaceTransforms = get(namespace); if (nullTransforms == null) return namespaceTransforms == null ? new LinkedList<AdditionalTransform>() : namespaceTransforms; if (namespaceTransforms == null) return nullTransforms; List<AdditionalTransform> result = new LinkedList<AdditionalTransform>(nullTransforms); result.addAll(namespaceTransforms); for (Iterator<AdditionalTransform> it = result.iterator(); it.hasNext();) { AdditionalTransform transform = it.next(); if (equalNamespaces && !transform.execIfSchemataEqual()) { it.remove(); continue; } switch (transform.getLocation()) { case START: if (start != null) start.add(transform); break; case BEFORE_UNMARSHALLER: if (beforeUnmarshaller != null) beforeUnmarshaller.add(transform); break; case END: if (end != null) end.add(transform); break; } } return result; } /** * Get the transforms that are to be applied to the schema with the given namespace. * * @param namespace The source namespace to get additional transforms for. * @return The transforms that are to be applied to the schema with the given namespace. If no transform is to be * applied, an empty list will be returned. */ public List<AdditionalTransform> getTransforms(String namespace) { return getTransforms(namespace, false, null, null, null); } /** * An additional transform that has to be executed in addition to the transforms fetched from * {@link BindingsManager}. * * @author Martin Pecka */ class AdditionalTransform { /** The additional transform. */ protected TransformInfo transform; /** The location of the transform. */ protected TransformLocation location; /** Whether to run this transform even if the XML's schema is in the newest version. */ protected boolean execIfSchemataEqual; /** * @param transform The additional transform. * @param location The location of the transform. * @param execIfSchemataEqual Whether to run this transform even if the XML's schema is in the newest version. */ public AdditionalTransform(TransformInfo transform, TransformLocation location, boolean execIfSchemataEqual) { this.transform = transform; this.location = location; this.execIfSchemataEqual = execIfSchemataEqual; } /** * @return The additional transform. */ public TransformInfo getTransform() { return transform; } /** * @return The location of the transform. */ public TransformLocation getLocation() { return location; } /** * @return Whether to run this transform even if the XML's schema is in the newest version. */ public boolean execIfSchemataEqual() { return execIfSchemataEqual; } } /** * The location where the additional transform should be placed in the execution string. * * @author Martin Pecka */ public enum TransformLocation { /** Perform the transform as the very first. */ START, /** Perform the transform as the very last (after the unmarshaller does its work). */ END, /** Perform the transform as the last, but before the unmarshaller does its work. */ BEFORE_UNMARSHALLER } }