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.IOException;
020 import java.io.InputStream;
021 import java.io.Reader;
022 import java.io.StringReader;
023
024 import javax.xml.transform.TransformerException;
025 import javax.xml.transform.sax.SAXSource;
026 import javax.xml.transform.stream.StreamSource;
027
028 import org.apache.camel.Converter;
029 import org.apache.camel.Exchange;
030 import org.apache.camel.StreamCache;
031 import org.apache.camel.converter.jaxp.BytesSource;
032 import org.apache.camel.converter.jaxp.StringSource;
033 import org.apache.camel.util.IOHelper;
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 @Converter
046 public StreamCache convertToStreamCache(StreamSource source, Exchange exchange) throws IOException {
047 return new StreamSourceCache(source, exchange);
048 }
049
050 @Converter
051 public StreamCache convertToStreamCache(StringSource source) {
052 //no need to do stream caching for a StringSource
053 return null;
054 }
055
056 @Converter
057 public StreamCache convertToStreamCache(BytesSource source) {
058 //no need to do stream caching for a BytesSource
059 return null;
060 }
061
062 @Converter
063 public StreamCache convertToStreamCache(SAXSource source, Exchange exchange) throws TransformerException {
064 String data = exchange.getContext().getTypeConverter().convertTo(String.class, source);
065 return new SourceCache(data);
066 }
067
068 @Converter
069 public StreamCache convertToStreamCache(InputStream stream, Exchange exchange) throws IOException {
070 // set up CachedOutputStream with the properties
071 CachedOutputStream cos = new CachedOutputStream(exchange.getContext().getProperties());
072 IOHelper.copyAndCloseInput(stream, cos);
073 return cos.getStreamCache();
074 }
075
076 @Converter
077 public StreamCache convertToStreamCache(Reader reader, Exchange exchange) throws IOException {
078 String data = exchange.getContext().getTypeConverter().convertTo(String.class, reader);
079 return new ReaderCache(data);
080 }
081
082 /*
083 * {@link StreamCache} implementation for {@link Source}s
084 */
085 private class SourceCache extends StringSource implements StreamCache {
086
087 private static final long serialVersionUID = 4147248494104812945L;
088
089 public SourceCache() {
090 }
091
092 public SourceCache(String text) {
093 super(text);
094 }
095
096 public void reset() {
097 // do nothing here
098 }
099
100 }
101
102 /*
103 * {@link StreamCache} implementation for Cache the StreamSource {@link StreamSource}s
104 */
105 private class StreamSourceCache extends StreamSource implements StreamCache {
106 StreamCache streamCache;
107 ReaderCache readCache;
108
109 public StreamSourceCache(StreamSource source, Exchange exchange) throws IOException {
110 if (source.getInputStream() != null) {
111 // set up CachedOutputStream with the properties
112 CachedOutputStream cos = new CachedOutputStream(exchange.getContext().getProperties());
113 IOHelper.copyAndCloseInput(source.getInputStream(), cos);
114 streamCache = cos.getStreamCache();
115 setInputStream((InputStream)streamCache);
116 setSystemId(source.getSystemId());
117 }
118 if (source.getReader() != null) {
119 String data = exchange.getContext().getTypeConverter().convertTo(String.class, source.getReader());
120 readCache = new ReaderCache(data);
121 setReader(readCache);
122 }
123 }
124
125 public void reset() {
126 if (streamCache != null) {
127 streamCache.reset();
128 }
129 if (readCache != null) {
130 readCache.reset();
131 }
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("Cannot reset cache", e);
147 }
148 }
149
150 public void close() {
151 // Do not release the string for caching
152 }
153
154 }
155
156
157
158
159 }