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 */ 017 package org.apache.camel.converter.stream; 018 019 import java.io.ByteArrayInputStream; 020 import java.io.IOException; 021 import java.io.InputStream; 022 import java.io.Reader; 023 import java.io.StringReader; 024 025 import javax.xml.transform.TransformerException; 026 import javax.xml.transform.sax.SAXSource; 027 import javax.xml.transform.stream.StreamSource; 028 029 import org.apache.camel.Converter; 030 import org.apache.camel.converter.IOConverter; 031 import org.apache.camel.converter.jaxp.BytesSource; 032 import org.apache.camel.converter.jaxp.StringSource; 033 import org.apache.camel.converter.jaxp.XmlConverter; 034 import org.apache.commons.logging.Log; 035 import org.apache.commons.logging.LogFactory; 036 037 /** 038 * A set of {@link Converter} methods for wrapping stream-based messages in a {@link StreamCache} 039 * implementation to ensure message re-readability (eg multicasting, retrying) 040 */ 041 @Converter 042 public class StreamCacheConverter { 043 private static final transient Log LOG = LogFactory.getLog(StreamCacheConverter.class); 044 045 private XmlConverter converter = new XmlConverter(); 046 047 @Converter 048 public StreamCache convertToStreamCache(StreamSource source) throws IOException { 049 return new StreamSourceCache(source); 050 } 051 052 @Converter 053 public StreamCache convertToStreamCache(StringSource source) { 054 //no need to do stream caching for a StringSource 055 return null; 056 } 057 058 @Converter 059 public StreamCache convertToStreamCache(BytesSource source) { 060 //no need to do stream caching for a BytesSource 061 return null; 062 } 063 064 @Converter 065 public StreamCache convertToStreamCache(SAXSource source) throws TransformerException { 066 return new SourceCache(converter.toString(source)); 067 } 068 069 @Converter 070 public StreamCache convertToStreamCache(InputStream stream) throws IOException { 071 return new InputStreamCache(IOConverter.toBytes(stream)); 072 } 073 074 @Converter 075 public StreamCache convertToStreamCache(Reader reader) throws IOException { 076 return new ReaderCache(IOConverter.toString(reader)); 077 } 078 079 /* 080 * {@link StreamCache} implementation for {@link Source}s 081 */ 082 private class SourceCache extends StringSource implements StreamCache { 083 084 private static final long serialVersionUID = 4147248494104812945L; 085 086 public SourceCache() { 087 } 088 089 public SourceCache(String text) { 090 super(text); 091 } 092 093 public void reset() { 094 // do nothing here 095 } 096 097 } 098 099 /* 100 * {@link StreamCache} implementation for Cache the StreamSource {@link StreamSource}s 101 */ 102 private class StreamSourceCache extends StreamSource implements StreamCache { 103 InputStreamCache inputStreamCache; 104 ReaderCache readCache; 105 106 public StreamSourceCache(StreamSource source) throws IOException { 107 if (source.getInputStream() != null) { 108 inputStreamCache = new InputStreamCache(IOConverter.toBytes(source.getInputStream())); 109 setInputStream(inputStreamCache); 110 setSystemId(source.getSystemId()); 111 } 112 if (source.getReader() != null) { 113 readCache = new ReaderCache(IOConverter.toString(source.getReader())); 114 setReader(readCache); 115 } 116 } 117 public void reset() { 118 if (inputStreamCache != null) { 119 inputStreamCache.reset(); 120 } 121 if (readCache != null) { 122 readCache.reset(); 123 } 124 } 125 126 } 127 128 private class InputStreamCache extends ByteArrayInputStream implements StreamCache { 129 130 public InputStreamCache(byte[] data) { 131 super(data); 132 } 133 134 } 135 136 private class ReaderCache extends StringReader implements StreamCache { 137 138 public ReaderCache(String s) { 139 super(s); 140 } 141 142 public void reset() { 143 try { 144 super.reset(); 145 } catch (IOException e) { 146 LOG.warn("Exception is thrown when resets the ReaderCache", e); 147 } 148 } 149 150 public void close() { 151 // Do not release the string for caching 152 } 153 154 } 155 156 157 }