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