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