001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.util.resource; 018 019import java.io.ByteArrayInputStream; 020import java.io.ByteArrayOutputStream; 021import java.io.IOException; 022import java.io.InputStream; 023import java.time.Instant; 024import java.util.Map; 025import java.util.Map.Entry; 026import org.apache.wicket.util.io.IOUtils; 027import org.apache.wicket.util.lang.Bytes; 028 029/** 030 * {@link IResourceStream} that applies XSLT on an input {@link IResourceStream}. The XSL stylesheet 031 * itself is also an {@link IResourceStream}. Override {@link #getParameters()} to pass parameters 032 * to the XSL stylesheet. 033 * 034 * <p> 035 * NOTE: this is an experimental feature which does not implement any kind of caching, use with 036 * care, running an XSL transformation for every request is very expensive! Please have a look at 037 * {@link ZipResourceStream} for an in-depth explanation of what needs to be done with respect to 038 * caching. 039 * </p> 040 * 041 * @author <a href="mailto:jbq@apache.org">Jean-Baptiste Quenot</a> 042 */ 043public class XSLTResourceStream extends AbstractResourceStream 044{ 045 /** 046 * 047 */ 048 private static final long serialVersionUID = 1L; 049 private final transient ByteArrayOutputStream out; 050 051 /** 052 * @return a {@link Map} of XSLT parameters, appropriate for passing information to the XSL 053 * stylesheet 054 */ 055 protected Map<Object, Object> getParameters() 056 { 057 return null; 058 } 059 060 /** 061 * Construct. 062 * 063 * @param xsltResource 064 * the XSL stylesheet as an {@link IResourceStream} 065 * @param xmlResource 066 * the input XML document as an {@link IResourceStream} 067 */ 068 public XSLTResourceStream(final IResourceStream xsltResource, final IResourceStream xmlResource) 069 { 070 try 071 { 072 javax.xml.transform.Source xmlSource = new javax.xml.transform.stream.StreamSource( 073 xmlResource.getInputStream()); 074 javax.xml.transform.Source xsltSource = new javax.xml.transform.stream.StreamSource( 075 xsltResource.getInputStream()); 076 out = new ByteArrayOutputStream(); 077 javax.xml.transform.Result result = new javax.xml.transform.stream.StreamResult(out); 078 079 // create an instance of TransformerFactory 080 javax.xml.transform.TransformerFactory transFact = javax.xml.transform.TransformerFactory.newInstance(); 081 082 javax.xml.transform.Transformer trans = transFact.newTransformer(xsltSource); 083 Map<Object, Object> parameters = getParameters(); 084 if (parameters != null) 085 { 086 for (Entry<Object, Object> e : parameters.entrySet()) 087 { 088 trans.setParameter(e.getKey().toString(), e.getValue().toString()); 089 } 090 } 091 092 trans.transform(xmlSource, result); 093 } 094 catch (Exception e) 095 { 096 throw new RuntimeException(e); 097 } 098 finally 099 { 100 IOUtils.closeQuietly(xmlResource); 101 IOUtils.closeQuietly(xsltResource); 102 } 103 } 104 105 /** 106 * @see org.apache.wicket.util.resource.IResourceStream#close() 107 */ 108 @Override 109 public void close() throws IOException 110 { 111 } 112 113 /** 114 * Returns always null 115 * 116 * @see org.apache.wicket.util.resource.IResourceStream#getContentType() 117 */ 118 @Override 119 public String getContentType() 120 { 121 return null; 122 } 123 124 /** 125 * @see org.apache.wicket.util.resource.IResourceStream#getInputStream() 126 */ 127 @Override 128 public InputStream getInputStream() throws ResourceStreamNotFoundException 129 { 130 return new ByteArrayInputStream(out.toByteArray()); 131 } 132 133 /** 134 * @see org.apache.wicket.util.resource.IResourceStream#length() 135 */ 136 @Override 137 public Bytes length() 138 { 139 return Bytes.bytes(out.size()); 140 } 141 142 /** 143 * Returns always null 144 * 145 * @see org.apache.wicket.util.watch.IModifiable#lastModifiedTime() 146 */ 147 @Override 148 public Instant lastModifiedTime() 149 { 150 return null; 151 } 152 153}