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.OutputStream;
023    import javax.xml.transform.stream.StreamSource;
024    
025    import org.apache.camel.Exchange;
026    import org.apache.camel.RuntimeCamelException;
027    import org.apache.camel.StreamCache;
028    import org.apache.camel.util.IOHelper;
029    
030    /**
031     * A {@link org.apache.camel.StreamCache} for {@link javax.xml.transform.stream.StreamSource}s
032     */
033    public final class StreamSourceCache extends StreamSource implements StreamCache {
034    
035        private final InputStream stream;
036        private final StreamCache streamCache;
037        private final ReaderCache readCache;
038    
039        public StreamSourceCache(StreamSource source, Exchange exchange) throws IOException {
040            if (source.getInputStream() != null) {
041                // set up CachedOutputStream with the properties
042                CachedOutputStream cos = new CachedOutputStream(exchange);
043                IOHelper.copyAndCloseInput(source.getInputStream(), cos);
044                streamCache = cos.newStreamCache();
045                readCache = null;
046                setSystemId(source.getSystemId());
047                stream = (InputStream) streamCache;
048            } else if (source.getReader() != null) {
049                String data = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, source.getReader());
050                readCache = new ReaderCache(data);
051                streamCache = null;
052                setReader(readCache);
053                stream = new ByteArrayInputStream(data.getBytes());
054            } else {
055                streamCache = null;
056                readCache = null;
057                stream = null;
058            }
059        }
060    
061        public void reset() {
062            if (streamCache != null) {
063                streamCache.reset();
064            }
065            if (readCache != null) {
066                readCache.reset();
067            }
068            if (stream != null) {
069                try {
070                    stream.reset();
071                } catch (IOException e) {
072                    throw new RuntimeCamelException(e);
073                }
074            }
075        }
076    
077        public void writeTo(OutputStream os) throws IOException {
078            if (streamCache != null) {
079                streamCache.writeTo(os);
080            } else if (readCache != null) {
081                readCache.writeTo(os);
082            }
083        }
084    
085        public boolean inMemory() {
086            if (streamCache != null) {
087                return streamCache.inMemory();
088            } else if (readCache != null) {
089                return readCache.inMemory();
090            } else {
091                // should not happen
092                return true;
093            }
094        }
095    
096        public long length() {
097            if (streamCache != null) {
098                return streamCache.length();
099            } else if (readCache != null) {
100                return readCache.length();
101            } else {
102                // should not happen
103                return 0;
104            }
105        }
106    
107        @Override
108        public InputStream getInputStream() {
109            return stream;
110        }
111    
112        @Override
113        public void setInputStream(InputStream inputStream) {
114            // noop as the input stream is from stream or reader cache
115        }
116    
117    }