1 16 17 20 21 package org.apache.axis.attachments; 22 23 24 import org.apache.axis.components.logger.LogFactory; 25 import org.apache.axis.utils.Messages; 26 import org.apache.commons.logging.Log; 27 28 import javax.activation.DataHandler ; 29 import javax.activation.DataSource ; 30 import java.io.BufferedInputStream ; 31 import java.io.IOException ; 32 import java.util.StringTokenizer ; 33 34 35 66 67 70 public class DimeBodyPart { 71 protected static Log log = 72 LogFactory.getLog(DimeBodyPart.class.getName()); 73 74 protected Object data = null; 75 protected DimeTypeNameFormat dtnf = null; 76 protected byte[] type = null; 77 protected byte[] id = null; 78 static final byte POSITION_FIRST = (byte) 0x04; 79 static final byte POSITION_LAST = (byte) 0x02; 80 private static final byte CHUNK = 0x01; private static final byte CHUNK_NEXT = 0x2; private static int MAX_TYPE_LENGTH = (1 << 16) - 1; 83 private static int MAX_ID_LENGTH = (1 << 16) - 1; 84 85 static final long MAX_DWORD = 0xffffffffL; 86 87 protected DimeBodyPart() {} 91 99 public DimeBodyPart(byte[] data, DimeTypeNameFormat format, 100 String type, String id) { 101 System.arraycopy(data, 0, this.data = new byte[ data.length], 0, data.length); 102 this.dtnf = format; 103 this.type = type.getBytes(); 104 if (this.type.length > MAX_TYPE_LENGTH) 105 throw new IllegalArgumentException (Messages.getMessage 106 ("attach.dimetypeexceedsmax", 107 "" + this.type.length, "" + MAX_TYPE_LENGTH)); 108 this.id = id.getBytes(); 109 if (this.id.length > MAX_ID_LENGTH) 110 throw new IllegalArgumentException ( 111 Messages.getMessage("attach.dimelengthexceedsmax", "" + this.id.length, 112 "" + MAX_ID_LENGTH)); 113 } 114 115 123 public DimeBodyPart(DataHandler dh, 124 DimeTypeNameFormat format, String type, String id) { 125 this.data = dh; 126 this.dtnf = format; 127 if (type == null || type.length() == 0) 128 type = "application/octet-stream"; 129 this.type = type.getBytes(); 130 if (this.type.length > MAX_TYPE_LENGTH) 131 throw new IllegalArgumentException (Messages.getMessage( 132 "attach.dimetypeexceedsmax", 133 "" + this.type.length, "" + MAX_TYPE_LENGTH)); 134 this.id = id.getBytes(); 135 if (this.id.length > MAX_ID_LENGTH) 136 throw new IllegalArgumentException (Messages.getMessage( 137 "attach.dimelengthexceedsmax", 138 "" + this.id.length, "" + MAX_ID_LENGTH)); 139 } 140 141 148 public DimeBodyPart(DataHandler dh, String id) { 149 this(dh, DimeTypeNameFormat.MIME, dh.getContentType(), id); 150 151 String ct = dh.getContentType(); 152 153 if (ct != null) { 154 ct = ct.trim(); 155 if (ct.toLowerCase().startsWith("application/uri")) { 156 StringTokenizer st = new StringTokenizer (ct, " \t;"); 157 String t = st.nextToken(" \t;"); 158 159 if (t.equalsIgnoreCase("application/uri")) { 160 for (; st.hasMoreTokens();) { 161 t = st.nextToken(" \t;"); 162 if (t.equalsIgnoreCase("uri")) { 163 t = st.nextToken("="); 164 if (t != null) { 165 t = t.trim(); 166 if (t.startsWith("\"")) t = 167 t.substring(1); 168 169 if (t.endsWith("\"")) t = 170 t.substring(0, t.length() - 1); 171 this.type = t.getBytes(); 172 this.dtnf = DimeTypeNameFormat.URI; 173 } 174 return; 175 } else if (t.equalsIgnoreCase("uri=")) { 176 t = st.nextToken(" \t;"); 177 if (null != t && t.length() != 0) { 178 t = t.trim(); 179 if (t.startsWith("\"")) t= 180 t.substring(1); 181 if (t.endsWith("\"")) t= 182 t.substring(0, t.length() - 1); 183 this.type = t.getBytes(); 184 this.dtnf = DimeTypeNameFormat.URI; 185 return; 186 } 187 } else if (t.toLowerCase().startsWith("uri=")) { 188 if (-1 != t.indexOf('=')) { 189 t = t.substring(t.indexOf('=')).trim(); 190 if (t.length() != 0) { 191 t = t.trim(); 192 if (t.startsWith("\"")) t = 193 t.substring(1); 194 195 if (t.endsWith("\"")) 196 t = t.substring(0, t.length() - 1); 197 this.type = t.getBytes(); 198 this.dtnf = DimeTypeNameFormat.URI; 199 return; 200 201 } 202 } 203 } 204 } 205 } 206 } 207 } 208 } 209 210 218 void write(java.io.OutputStream os, byte position, long maxchunk) 219 throws java.io.IOException { 220 if (maxchunk < 1) throw new IllegalArgumentException ( 221 Messages.getMessage("attach.dimeMaxChunkSize0", "" + maxchunk)); 222 if (maxchunk > MAX_DWORD) throw new IllegalArgumentException ( 223 Messages.getMessage("attach.dimeMaxChunkSize1", "" + maxchunk)); 224 if (data instanceof byte[]) { 225 send(os, position, (byte[]) data, maxchunk); 226 } else if (data instanceof DynamicContentDataHandler) { 227 send(os, position, (DynamicContentDataHandler) data, maxchunk); 228 } else if (data instanceof DataHandler ) { 229 DataSource source = ((DataHandler )data).getDataSource(); 230 DynamicContentDataHandler dh2 = new DynamicContentDataHandler(source); 231 send(os, position, dh2, maxchunk); 232 } 233 } 234 235 242 void write(java.io.OutputStream os, byte position) 243 throws java.io.IOException { 244 write(os, position, MAX_DWORD); 245 } 246 247 private static final byte[] pad = new byte[4]; 248 249 void send(java.io.OutputStream os, byte position, byte[] data, 250 final long maxchunk)throws java.io.IOException { 251 send(os, position, data, 0, data.length, maxchunk); 252 } 253 254 void send(java.io.OutputStream os, byte position, byte[] data, 255 int offset, final int length, final long maxchunk) 256 throws java.io.IOException { 257 258 byte chunknext = 0; 259 260 do { 261 int sendlength = (int) Math.min(maxchunk, length - offset); 262 263 sendChunk(os, position, data, offset, sendlength, (byte) 264 ((sendlength < (length - offset) ? CHUNK : 0) 265 | chunknext)); 266 offset += sendlength; 267 chunknext = CHUNK_NEXT; 268 } 269 while (offset < length); 270 } 271 272 void send(java.io.OutputStream os, byte position, DataHandler dh, 273 final long maxchunk) throws java.io.IOException { 274 java.io.InputStream in = null; 275 try { 276 long dataSize = getDataSize(); 277 in = dh.getInputStream(); 278 byte[] readbuf = new byte[64 * 1024]; 279 int bytesread; 280 281 sendHeader(os, position, dataSize, (byte) 0); 282 long totalsent = 0; 283 284 do { 285 bytesread = in.read(readbuf); 286 if (bytesread > 0) { 287 os.write(readbuf, 0, bytesread); 288 totalsent += bytesread; 289 } 290 } 291 while (bytesread > -1); 292 os.write(pad, 0, dimePadding(totalsent)); 293 } 294 finally { 295 if (in != null) { 296 try { 297 in.close(); 298 } 299 catch (IOException e) { 300 } 302 } 303 } 304 } 305 306 317 void send(java.io.OutputStream os, byte position, DynamicContentDataHandler dh, 318 final long maxchunk) 319 throws java.io.IOException { 320 321 BufferedInputStream in = new BufferedInputStream (dh.getInputStream()); 322 323 final int myChunkSize = dh.getChunkSize(); 324 325 byte[] buffer1 = new byte[myChunkSize]; 326 byte[] buffer2 = new byte[myChunkSize]; 327 328 int bytesRead1 = 0 , bytesRead2 = 0; 329 330 bytesRead1 = in.read(buffer1); 331 332 if(bytesRead1 < 0) { 333 sendHeader(os, position, 0, (byte) 0); 334 os.write(pad, 0, dimePadding(0)); 335 return; 336 } 337 338 do { 339 bytesRead2 = in.read(buffer2); 340 341 if(bytesRead2 < 0) { 342 sendChunk(os, position, buffer1, 0, bytesRead1, (byte)0); 345 break; 346 } 347 348 sendChunk(os, position, buffer1, 0, bytesRead1, CHUNK); 349 350 System.arraycopy(buffer2,0,buffer1,0,myChunkSize); 352 bytesRead1 = bytesRead2; 353 354 }while(bytesRead2 > 0); 355 } 356 357 protected void sendChunk(java.io.OutputStream os, 358 final byte position, 359 byte[] data, byte chunk) throws java.io.IOException { 360 361 sendChunk(os, position, data, 0, data.length, chunk); 362 } 363 364 protected void sendChunk(java.io.OutputStream os, 365 final byte position, byte[] data, int offset, int length, 366 byte chunk) throws java.io.IOException { 367 368 sendHeader(os, position, length, chunk); 369 os.write(data, offset, length); 370 os.write(pad, 0, dimePadding(length)); 371 } 372 373 static final byte CURRENT_OPT_T = (byte) 0; 374 375 protected void sendHeader(java.io.OutputStream os, 376 final byte position, 377 long length, byte chunk) throws java.io.IOException { 378 byte[] fixedHeader = new byte[12]; 379 380 fixedHeader[0] = (byte)((DimeMultiPart.CURRENT_VERSION << 3) & 0xf8); 382 383 fixedHeader[0] |= (byte) ((position & (byte) 0x6) 385 & ((chunk & CHUNK) != 0 ? ~POSITION_LAST : ~0) & 386 ((chunk & CHUNK_NEXT) != 0 ? ~POSITION_FIRST : ~0)); 387 fixedHeader[0] |= (chunk & CHUNK); 388 389 if ((chunk & CHUNK_NEXT) == 0) fixedHeader[1] = (byte) ((dtnf.toByte() << 4) & 0xf0); 392 393 fixedHeader[1] |= (byte) (CURRENT_OPT_T & 0xf); 395 396 fixedHeader[2] = (byte) 0; 398 fixedHeader[3] = (byte) 0; 399 400 if ((chunk & CHUNK_NEXT) == 0) { fixedHeader[4] = (byte) ((id.length >>> 8) & 0xff); 403 fixedHeader[5] = (byte) ((id.length) & 0xff); 404 } 405 406 if ((chunk & CHUNK_NEXT) == 0) { 408 fixedHeader[6] = (byte) ((type.length >>> 8) & 0xff); 409 fixedHeader[7] = (byte) ((type.length) & 0xff); 410 } 411 412 fixedHeader[8] = (byte) ((length >>> 24) & 0xff); 414 fixedHeader[9] = (byte) ((length >>> 16) & 0xff); 415 fixedHeader[10] = (byte) ((length >>> 8) & 0xff); 416 fixedHeader[11] = (byte) (length & 0xff); 417 418 os.write(fixedHeader); 419 420 423 if ((chunk & CHUNK_NEXT) == 0) { 425 os.write(id); 426 os.write(pad, 0, dimePadding(id.length)); 427 } 428 429 if ((chunk & CHUNK_NEXT) == 0) { 431 os.write(type); 432 os.write(pad, 0, dimePadding(type.length)); 433 } 434 } 435 436 static final int dimePadding(long l) { 437 return (int) ((4L - (l & 0x3L)) & 0x03L); 438 } 439 440 long getTransmissionSize(long chunkSize) { 441 long size = 0; 442 size += id.length; 443 size += dimePadding(id.length); 444 size += type.length; 445 size += dimePadding(type.length); 446 long dataSize = getDataSize(); 448 449 if(0 == dataSize){ 450 size+=12; }else{ 452 453 long fullChunks = dataSize / chunkSize; 454 long lastChunkSize = dataSize % chunkSize; 455 456 if (0 != lastChunkSize) size += 12; size += 12 * fullChunks; size += fullChunks * dimePadding(chunkSize); 459 size += dimePadding(lastChunkSize); 460 size += dataSize; 461 } 462 return size; 463 } 464 465 long getTransmissionSize() { 466 return getTransmissionSize(MAX_DWORD); 467 } 468 469 protected long getDataSize() { 470 if (data instanceof byte[]) return ((byte[]) (data)).length; 471 if (data instanceof DataHandler ) 472 return getDataSize((DataHandler ) data); 473 return -1; 474 } 475 476 protected long getDataSize(DataHandler dh) { 477 long dataSize = -1L; 478 479 try { 480 DataSource ds = dh.getDataSource(); 481 482 if (ds instanceof javax.activation.FileDataSource ) { 485 javax.activation.FileDataSource fdh = 486 (javax.activation.FileDataSource ) ds; 487 java.io.File df = fdh.getFile(); 488 489 if (!df.exists()) { 490 throw new RuntimeException ( 491 Messages.getMessage("noFile", 492 df.getAbsolutePath())); 493 } 494 dataSize = df.length(); 495 } else { 496 dataSize = 0; 497 java.io.InputStream in = ds.getInputStream(); 498 byte[] readbuf = new byte[64 * 1024]; 499 int bytesread; 500 501 do { 502 bytesread = in.read(readbuf); 503 if (bytesread > 0) dataSize += bytesread; 504 } 505 while (bytesread > -1); 506 507 if (in.markSupported()) { 508 in.reset(); 511 } else { 512 in.close(); 515 } 516 } 517 } catch (Exception e) { 518 log.error(Messages.getMessage("exception00"), e); 520 } 521 return dataSize; 522 } 523 } 524 | Popular Tags |