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;
018
019 import java.io.BufferedReader;
020 import java.io.BufferedWriter;
021 import java.io.ByteArrayInputStream;
022 import java.io.ByteArrayOutputStream;
023 import java.io.File;
024 import java.io.FileInputStream;
025 import java.io.FileNotFoundException;
026 import java.io.FileOutputStream;
027 import java.io.IOException;
028 import java.io.InputStream;
029 import java.io.InputStreamReader;
030 import java.io.ObjectInput;
031 import java.io.ObjectInputStream;
032 import java.io.ObjectOutput;
033 import java.io.ObjectOutputStream;
034 import java.io.ObjectStreamClass;
035 import java.io.OutputStream;
036 import java.io.OutputStreamWriter;
037 import java.io.Reader;
038 import java.io.StringReader;
039 import java.io.UnsupportedEncodingException;
040 import java.io.Writer;
041 import java.net.URL;
042 import java.nio.charset.UnsupportedCharsetException;
043
044 import org.apache.camel.Converter;
045 import org.apache.camel.Exchange;
046 import org.apache.camel.util.IOHelper;
047 import org.slf4j.Logger;
048 import org.slf4j.LoggerFactory;
049
050 /**
051 * Some core java.io based <a
052 * href="http://camel.apache.org/type-converter.html">Type Converters</a>
053 *
054 * @version
055 */
056 @Converter
057 public final class IOConverter {
058 private static final transient Logger LOG = LoggerFactory.getLogger(IOConverter.class);
059
060 /**
061 * Utility classes should not have a public constructor.
062 */
063 private IOConverter() {
064 }
065
066 @Converter
067 public static InputStream toInputStream(URL url) throws IOException {
068 return IOHelper.buffered(url.openStream());
069 }
070
071 @Converter
072 public static InputStream toInputStream(File file) throws IOException {
073 return IOHelper.buffered(new FileInputStream(file));
074 }
075
076 public static InputStream toInputStream(File file, String charset) throws IOException {
077 if (charset != null) {
078 final BufferedReader reader = toReader(file, charset);
079 return new InputStream() {
080 @Override
081 public int read() throws IOException {
082 return reader.read();
083 }
084
085 @Override
086 public void close() throws IOException {
087 reader.close();
088 }
089
090 @Override
091 public void reset() throws IOException {
092 reader.reset();
093 }
094 };
095 } else {
096 return IOHelper.buffered(new FileInputStream(file));
097 }
098 }
099
100 /**
101 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
102 */
103 @Deprecated
104 public static BufferedReader toReader(File file) throws IOException {
105 return toReader(file, (String) null);
106 }
107
108 @Converter
109 public static BufferedReader toReader(File file, Exchange exchange) throws IOException {
110 return toReader(file, IOHelper.getCharsetName(exchange));
111 }
112
113 public static BufferedReader toReader(File file, String charset) throws IOException {
114 FileInputStream in = new FileInputStream(file);
115 return IOHelper.buffered(new EncodingFileReader(in, charset));
116 }
117
118 @Converter
119 public static File toFile(String name) throws FileNotFoundException {
120 return new File(name);
121 }
122
123 @Converter
124 public static OutputStream toOutputStream(File file) throws FileNotFoundException {
125 return IOHelper.buffered(new FileOutputStream(file));
126 }
127
128 /**
129 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
130 */
131 @Deprecated
132 public static BufferedWriter toWriter(File file) throws IOException {
133 return toWriter(file, false, IOHelper.getCharsetName(null, true));
134 }
135
136 @Converter
137 public static BufferedWriter toWriter(File file, Exchange exchange) throws IOException {
138 return toWriter(file, false, IOHelper.getCharsetName(exchange));
139 }
140
141 public static BufferedWriter toWriter(File file, boolean append, String charset) throws IOException {
142 FileOutputStream os = new FileOutputStream(file, append);
143 return IOHelper.buffered(new EncodingFileWriter(os, charset));
144 }
145
146 /**
147 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
148 */
149 @Deprecated
150 public static Reader toReader(InputStream in) throws IOException {
151 return toReader(in, null);
152 }
153
154 @Converter
155 public static Reader toReader(InputStream in, Exchange exchange) throws IOException {
156 return IOHelper.buffered(new InputStreamReader(in, IOHelper.getCharsetName(exchange)));
157 }
158
159 /**
160 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
161 */
162 @Deprecated
163 public static Writer toWriter(OutputStream out) throws IOException {
164 return toWriter(out, null);
165 }
166
167 @Converter
168 public static Writer toWriter(OutputStream out, Exchange exchange) throws IOException {
169 return IOHelper.buffered(new OutputStreamWriter(out, IOHelper.getCharsetName(exchange)));
170 }
171
172 @Converter
173 public static StringReader toReader(String text) {
174 // no buffering required as the complete string input is already passed
175 // over as a whole
176 return new StringReader(text);
177 }
178
179 /**
180 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
181 */
182 @Deprecated
183 public static InputStream toInputStream(String text) throws IOException {
184 return toInputStream(text, null);
185 }
186
187 @Converter
188 public static InputStream toInputStream(String text, Exchange exchange) throws IOException {
189 return toInputStream(text.getBytes(IOHelper.getCharsetName(exchange)));
190 }
191
192 @Converter
193 public static InputStream toInputStream(StringBuffer buffer, Exchange exchange) throws IOException {
194 return toInputStream(buffer.toString(), exchange);
195 }
196
197 @Converter
198 public static InputStream toInputStream(StringBuilder builder, Exchange exchange) throws IOException {
199 return toInputStream(builder.toString(), exchange);
200 }
201
202 /**
203 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
204 */
205 @Deprecated
206 public static InputStream toInputStream(BufferedReader buffer) throws IOException {
207 return toInputStream(buffer, null);
208 }
209
210 @Converter
211 public static InputStream toInputStream(BufferedReader buffer, Exchange exchange) throws IOException {
212 return toInputStream(toString(buffer), exchange);
213 }
214
215 /**
216 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
217 */
218 @Deprecated
219 public static String toString(byte[] data) throws IOException {
220 return toString(data, null);
221 }
222
223 @Converter
224 public static String toString(byte[] data, Exchange exchange) throws IOException {
225 return new String(data, IOHelper.getCharsetName(exchange));
226 }
227
228 /**
229 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
230 */
231 @Deprecated
232 public static String toString(File file) throws IOException {
233 return toString(file, null);
234 }
235
236 @Converter
237 public static String toString(File file, Exchange exchange) throws IOException {
238 return toString(toReader(file, exchange));
239 }
240
241 @Converter
242 public static byte[] toByteArray(File file) throws IOException {
243 InputStream is = toInputStream(file);
244 try {
245 return toBytes(is);
246 } finally {
247 IOHelper.close(is, "file", LOG);
248 }
249 }
250
251 /**
252 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
253 */
254 @Deprecated
255 public static byte[] toByteArray(Reader reader) throws IOException {
256 return toByteArray(reader, null);
257 }
258
259 @Converter
260 public static byte[] toByteArray(Reader reader, Exchange exchange) throws IOException {
261 return toByteArray(IOHelper.buffered(reader), exchange);
262 }
263
264 /**
265 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
266 */
267 @Deprecated
268 public static String toString(URL url) throws IOException {
269 return toString(url, null);
270 }
271
272 @Converter
273 public static String toString(URL url, Exchange exchange) throws IOException {
274 InputStream is = toInputStream(url);
275 try {
276 return toString(is, exchange);
277 } finally {
278 IOHelper.close(is, "url", LOG);
279 }
280 }
281
282 @Converter
283 public static String toString(Reader reader) throws IOException {
284 return toString(IOHelper.buffered(reader));
285 }
286
287 @Converter
288 public static String toString(BufferedReader reader) throws IOException {
289 if (reader == null) {
290 return null;
291 }
292
293 StringBuilder sb = new StringBuilder(1024);
294 char[] buf = new char[1024];
295 try {
296 int len;
297 // read until we reach then end which is the -1 marker
298 while ((len = reader.read(buf)) != -1) {
299 sb.append(buf, 0, len);
300 }
301 } finally {
302 IOHelper.close(reader, "reader", LOG);
303 }
304
305 return sb.toString();
306 }
307
308 /**
309 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
310 */
311 @Deprecated
312 public static byte[] toByteArray(BufferedReader reader) throws IOException {
313 return toByteArray(reader, null);
314 }
315
316 @Converter
317 public static byte[] toByteArray(BufferedReader reader, Exchange exchange) throws IOException {
318 String s = toString(reader);
319 return toByteArray(s, exchange);
320 }
321
322 /**
323 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
324 */
325 @Deprecated
326 public static byte[] toByteArray(String value) throws IOException {
327 return toByteArray(value, null);
328 }
329
330 @Converter
331 public static byte[] toByteArray(String value, Exchange exchange) throws IOException {
332 return value != null ? value.getBytes(IOHelper.getCharsetName(exchange)) : null;
333 }
334
335 /**
336 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
337 */
338 @Deprecated
339 public static String toString(InputStream in) throws IOException {
340 return toString(in, null);
341 }
342
343 @Converter
344 public static String toString(InputStream in, Exchange exchange) throws IOException {
345 return toString(toReader(in, exchange));
346 }
347
348 @Converter
349 public static InputStream toInputStream(byte[] data) {
350 // no buffering required as the complete byte input is already passed
351 // over as a whole
352 return new ByteArrayInputStream(data);
353 }
354
355 @Converter
356 public static ObjectOutput toObjectOutput(OutputStream stream) throws IOException {
357 if (stream instanceof ObjectOutput) {
358 return (ObjectOutput) stream;
359 } else {
360 return new ObjectOutputStream(IOHelper.buffered(stream));
361 }
362 }
363
364 @Converter
365 public static ObjectInput toObjectInput(final InputStream stream, final Exchange exchange) throws IOException {
366 if (stream instanceof ObjectInput) {
367 return (ObjectInput) stream;
368 } else {
369 return new ObjectInputStream(IOHelper.buffered(stream)) {
370 @Override
371 protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
372 // need to let Camel be able to resolve class using ClassResolver SPI, to let class loading
373 // work in OSGi and other containers
374 Class<?> answer = null;
375 String name = objectStreamClass.getName();
376 if (exchange != null) {
377 LOG.trace("Loading class {} using Camel ClassResolver", name);
378 answer = exchange.getContext().getClassResolver().resolveClass(name);
379 }
380 if (answer == null) {
381 LOG.trace("Loading class {} using JDK default implementation", name);
382 answer = super.resolveClass(objectStreamClass);
383 }
384 return answer;
385 }
386 };
387 }
388 }
389
390 @Converter
391 public static byte[] toBytes(InputStream stream) throws IOException {
392 ByteArrayOutputStream bos = new ByteArrayOutputStream();
393 IOHelper.copy(IOHelper.buffered(stream), bos);
394
395 // no need to close the ByteArrayOutputStream as it's close()
396 // implementation is noop
397 return bos.toByteArray();
398 }
399
400 @Converter
401 public static byte[] toByteArray(ByteArrayOutputStream os) {
402 return os.toByteArray();
403 }
404
405 /**
406 * @deprecated will be removed in Camel 3.0. Use the method which has 2 parameters.
407 */
408 @Deprecated
409 public static String toString(ByteArrayOutputStream os) throws IOException {
410 return toString(os, null);
411 }
412
413 @Converter
414 public static String toString(ByteArrayOutputStream os, Exchange exchange) throws IOException {
415 return os.toString(IOHelper.getCharsetName(exchange));
416 }
417
418 @Converter
419 public static InputStream toInputStream(ByteArrayOutputStream os) {
420 // no buffering required as the complete byte array input is already
421 // passed over as a whole
422 return new ByteArrayInputStream(os.toByteArray());
423 }
424
425 /**
426 * Gets the charset name if set as property {@link Exchange#CHARSET_NAME}.
427 *
428 * @param exchange the exchange
429 * @param useDefault should we fallback and use JVM default charset if no property existed?
430 * @return the charset, or <tt>null</tt> if no found
431 */
432 @Deprecated
433 public static String getCharsetName(Exchange exchange, boolean useDefault) {
434 return IOHelper.getCharsetName(exchange, useDefault);
435 }
436
437 @Deprecated
438 public static String getCharsetName(Exchange exchange) {
439 return getCharsetName(exchange, true);
440 }
441
442 /**
443 * Encoding-aware file reader.
444 */
445 private static class EncodingFileReader extends InputStreamReader {
446
447 private final FileInputStream in;
448
449 /**
450 * @param in file to read
451 * @param charset character set to use
452 */
453 public EncodingFileReader(FileInputStream in, String charset)
454 throws FileNotFoundException, UnsupportedEncodingException {
455 super(in, charset);
456 this.in = in;
457 }
458
459 @Override
460 public void close() throws IOException {
461 try {
462 super.close();
463 } finally {
464 in.close();
465 }
466 }
467 }
468
469 /**
470 * Encoding-aware file writer.
471 */
472 private static class EncodingFileWriter extends OutputStreamWriter {
473
474 private final FileOutputStream out;
475
476 /**
477 * @param out file to write
478 * @param charset character set to use
479 */
480 public EncodingFileWriter(FileOutputStream out, String charset)
481 throws FileNotFoundException, UnsupportedEncodingException {
482 super(out, charset);
483 this.out = out;
484 }
485
486 @Override
487 public void close() throws IOException {
488 try {
489 super.close();
490 } finally {
491 out.close();
492 }
493 }
494 }
495
496 /**
497 * This method will take off the quotes and double quotes of the charset
498 */
499 @Deprecated
500 public static String normalizeCharset(String charset) {
501 return IOHelper.normalizeCharset(charset);
502 }
503
504 @Deprecated
505 public static void validateCharset(String charset) throws UnsupportedCharsetException {
506 IOHelper.validateCharset(charset);
507 }
508
509 }