001
002 /*
003 * Copyright (C) 2012 Archie L. Cobbs. All rights reserved.
004 *
005 * $Id: SpringXSLPersistentObjectSchemaUpdate.java 240 2012-01-19 19:42:54Z archie.cobbs $
006 */
007
008 package org.dellroad.stuff.pobj;
009
010 import java.io.IOException;
011 import java.io.InputStream;
012 import java.util.Properties;
013
014 import javax.xml.transform.Transformer;
015 import javax.xml.transform.TransformerException;
016 import javax.xml.transform.TransformerFactory;
017 import javax.xml.transform.stream.StreamSource;
018
019 import org.dellroad.stuff.xml.TransformErrorListener;
020 import org.slf4j.LoggerFactory;
021 import org.springframework.core.io.Resource;
022
023 /**
024 * {@link SpringPersistentObjectSchemaUpdate} that applies a configured XSL transform to the XML form of the persistent object.
025 *
026 * <p>
027 * The {@link #setTransform transform} property is required.
028 *
029 * <p>
030 * See {@link SpringPersistentObjectSchemaUpdater} for a Spring configuration example.
031 *
032 * @param <T> type of the persistent object
033 */
034 public class SpringXSLPersistentObjectSchemaUpdate<T> extends SpringPersistentObjectSchemaUpdate<T> {
035
036 private Resource transform;
037 private Properties parameters;
038
039 @Override
040 public void afterPropertiesSet() throws Exception {
041 super.afterPropertiesSet();
042 if (this.transform == null)
043 throw new Exception("no transform configured");
044 }
045
046 /**
047 * Configure the XSLT transform as a resource.
048 */
049 public void setTransform(Resource transform) {
050 this.transform = transform;
051 }
052
053 public Resource getTransform() {
054 return this.transform;
055 }
056
057 /**
058 * Configure XSLT parameters. This is an optional property.
059 */
060 public void setParameters(Properties properties) {
061 this.parameters = parameters;
062 }
063
064 /**
065 * Apply this update to the given transaction.
066 */
067 @Override
068 public void apply(PersistentFileTransaction transaction) {
069
070 // Get transform source
071 InputStream input;
072 try {
073 input = this.transform.getInputStream();
074 } catch (IOException e) {
075 throw new RuntimeException(e);
076 }
077 try {
078
079 // Setup transformer
080 Transformer transformer = TransformerFactory.newInstance().newTransformer(
081 new StreamSource(input, this.transform.getURI().toString()));
082 transformer.setErrorListener(new TransformErrorListener(LoggerFactory.getLogger(this.getClass()), true));
083 if (this.parameters != null) {
084 for (String name : this.parameters.stringPropertyNames())
085 transformer.setParameter(name, this.parameters.getProperty(name));
086 }
087
088 // Do the transform
089 transaction.transform(transformer);
090
091 } catch (IOException e) {
092 throw new RuntimeException(e);
093 } catch (TransformerException e) {
094 throw new RuntimeException(e);
095 } catch (RuntimeException e) {
096 if (e.getCause() instanceof TransformerException && e.getCause().getCause() instanceof RuntimeException)
097 e = (RuntimeException)e.getCause().getCause();
098 throw e;
099 } finally {
100 try {
101 input.close();
102 } catch (IOException e) {
103 // ignore
104 }
105 }
106 }
107 }
108