1 8 9 package org.jboss.axis.attachments; 10 11 12 import org.jboss.axis.utils.Messages; 13 import org.jboss.logging.Logger; 14 15 import javax.activation.DataHandler ; 16 import javax.activation.DataSource ; 17 import java.io.IOException ; 18 import java.util.StringTokenizer ; 19 20 23 24 25 56 57 60 public class DimeBodyPart 61 { 62 private static Logger log = Logger.getLogger(DimeBodyPart.class.getName()); 63 64 protected Object data = null; 65 protected DimeTypeNameFormat dtnf = null; 66 protected byte[] type = null; 67 protected byte[] id = null; 68 static final byte POSITION_FIRST = (byte)0x04; 69 static final byte POSITION_LAST = (byte)0x02; 70 private static final byte CHUNK = 0x01; private static final byte CHUNK_NEXT = 0x2; private static int MAX_TYPE_LENGTH = (1 << 16) - 1; 73 private static int MAX_ID_LENGTH = (1 << 16) - 1; 74 75 static final long MAX_DWORD = 0xffffffffL; 76 77 protected DimeBodyPart() 78 { 79 } 81 89 public DimeBodyPart(byte[] data, DimeTypeNameFormat format, 90 String type, String id) 91 { 92 System.arraycopy(data, 0, this.data = new byte[data.length], 0, data.length); 93 this.dtnf = format; 94 this.type = type.getBytes(); 95 if (this.type.length > MAX_TYPE_LENGTH) 96 throw new IllegalArgumentException (Messages.getMessage 97 ("attach.dimetypeexceedsmax", 98 "" + this.type.length, "" + MAX_TYPE_LENGTH)); 99 this.id = id.getBytes(); 100 if (this.id.length > MAX_ID_LENGTH) 101 throw new IllegalArgumentException (Messages.getMessage("attach.dimelengthexceedsmax", "" + this.id.length, 102 "" + MAX_ID_LENGTH)); 103 } 104 105 113 public DimeBodyPart(DataHandler dh, 114 DimeTypeNameFormat format, String type, String id) 115 { 116 this.data = dh; 117 this.dtnf = format; 118 if (type == null || type.length() == 0) 119 type = "application/octet-stream"; 120 this.type = type.getBytes(); 121 if (this.type.length > MAX_TYPE_LENGTH) 122 throw new IllegalArgumentException (Messages.getMessage("attach.dimetypeexceedsmax", 123 "" + this.type.length, "" + MAX_TYPE_LENGTH)); 124 this.id = id.getBytes(); 125 if (this.id.length > MAX_ID_LENGTH) 126 throw new IllegalArgumentException (Messages.getMessage("attach.dimelengthexceedsmax", 127 "" + this.id.length, "" + MAX_ID_LENGTH)); 128 } 129 130 137 public DimeBodyPart(DataHandler dh, String id) 138 { 139 this(dh, DimeTypeNameFormat.MIME, dh.getContentType(), id); 140 141 String ct = dh.getContentType(); 142 143 if (ct != null) 144 { 145 ct = ct.trim(); 146 if (ct.toLowerCase().startsWith("application/uri")) 147 { 148 StringTokenizer st = new StringTokenizer (ct, " \t;"); 149 String t = st.nextToken(" \t;"); 150 151 if (t.equalsIgnoreCase("application/uri")) 152 { 153 for (; st.hasMoreTokens();) 154 { 155 t = st.nextToken(" \t;"); 156 if (t.equalsIgnoreCase("uri")) 157 { 158 t = st.nextToken("="); 159 if (t != null) 160 { 161 t = t.trim(); 162 if (t.startsWith("\"")) 163 t = 164 t.substring(1); 165 166 if (t.endsWith("\"")) 167 t = 168 t.substring(0, t.length() - 1); 169 this.type = t.getBytes(); 170 this.dtnf = DimeTypeNameFormat.URI; 171 } 172 return; 173 } 174 else if (t.equalsIgnoreCase("uri=")) 175 { 176 t = st.nextToken(" \t;"); 177 if (null != t && t.length() != 0) 178 { 179 t = t.trim(); 180 if (t.startsWith("\"")) 181 t = 182 t.substring(1); 183 if (t.endsWith("\"")) 184 t = 185 t.substring(0, t.length() - 1); 186 this.type = t.getBytes(); 187 this.dtnf = DimeTypeNameFormat.URI; 188 return; 189 } 190 } 191 else if (t.toLowerCase().startsWith("uri=")) 192 { 193 if (-1 != t.indexOf('=')) 194 { 195 t = t.substring(t.indexOf('=')).trim(); 196 if (t.length() != 0) 197 { 198 t = t.trim(); 199 if (t.startsWith("\"")) 200 t = 201 t.substring(1); 202 203 if (t.endsWith("\"")) 204 t = t.substring(0, t.length() - 1); 205 this.type = t.getBytes(); 206 this.dtnf = DimeTypeNameFormat.URI; 207 return; 208 209 } 210 } 211 } 212 } 213 } 214 } 215 } 216 } 217 218 221 void write(java.io.OutputStream os, byte position, long maxchunk) 222 throws java.io.IOException 223 { 224 if (maxchunk < 1) 225 throw new IllegalArgumentException (Messages.getMessage("attach.dimeMaxChunkSize0", "" + maxchunk)); 226 if (maxchunk > MAX_DWORD) 227 throw new IllegalArgumentException (Messages.getMessage("attach.dimeMaxChunkSize1", "" + maxchunk)); 228 if (data instanceof byte[]) 229 send(os, position, (byte[])data, 230 maxchunk); 231 if (data instanceof DataHandler ) 232 send(os, position, 233 (DataHandler )data, maxchunk); 234 } 235 236 239 void write(java.io.OutputStream os, byte position) 240 throws java.io.IOException 241 { 242 write(os, position, MAX_DWORD); 243 } 244 245 private static final byte[] pad = new byte[4]; 246 247 void send(java.io.OutputStream os, byte position, byte[] data, 248 final long maxchunk) throws java.io.IOException 249 { 250 send(os, position, data, 0, data.length, maxchunk); 251 } 252 253 void send(java.io.OutputStream os, byte position, byte[] data, 254 int offset, final int length, final long maxchunk) 255 throws java.io.IOException 256 { 257 258 byte chunknext = 0; 259 260 do 261 { 262 int sendlength = (int)Math.min(maxchunk, length - offset); 263 264 sendChunk(os, position, data, offset, sendlength, (byte) 265 ((sendlength < (length - offset) ? CHUNK : 0) 266 | chunknext)); 267 offset += sendlength; 268 chunknext = CHUNK_NEXT; 269 } 270 while (offset < length); 271 } 272 273 void send(java.io.OutputStream os, byte position, DataHandler dh, 274 final long maxchunk) throws java.io.IOException 275 { 276 java.io.InputStream in = null; 278 try 279 { 280 byte chunknext = 0; 281 282 long dataSize = getDataSize(); 283 in = dh.getInputStream(); 284 byte[] readbuf = new byte[64 * 1024]; 285 int bytesread; 286 287 sendHeader(os, position, dataSize, (byte)0); 288 long totalsent = 0; 289 290 do 291 { 292 bytesread = in.read(readbuf); 293 if (bytesread > 0) 294 { 295 os.write(readbuf, 0, bytesread); 296 totalsent += bytesread; 297 } 298 } 299 while (bytesread > -1); 300 os.write(pad, 0, dimePadding(totalsent)); 301 } 302 finally 303 { 304 if (in != null) 305 { 306 try 307 { 308 in.close(); 309 } 310 catch (IOException e) 311 { 312 } 314 } 315 } 316 } 318 319 protected void sendChunk(java.io.OutputStream os, 320 final byte position, 321 byte[] data, byte chunk) throws java.io.IOException 322 { 323 324 sendChunk(os, position, data, 0, data.length, chunk); 325 } 326 327 protected void sendChunk(java.io.OutputStream os, 328 final byte position, byte[] data, int offset, int length, 329 byte chunk) throws java.io.IOException 330 { 331 332 sendHeader(os, position, length, chunk); 333 os.write(data, offset, length); 334 os.write(pad, 0, dimePadding(length)); 335 } 336 337 static final byte CURRENT_OPT_T = (byte)0; 338 339 protected void sendHeader(java.io.OutputStream os, 340 final byte position, 341 long length, byte chunk) throws java.io.IOException 342 { 343 byte[] fixedHeader = new byte[12]; 344 345 fixedHeader[0] = (byte)((DimeMultiPart.CURRENT_VERSION << 3) & 0xf8); 347 348 fixedHeader[0] |= (byte)((position & (byte)0x6) 350 & ((chunk & CHUNK) != 0 ? ~POSITION_LAST : ~0) & 351 ((chunk & CHUNK_NEXT) != 0 ? ~POSITION_FIRST : ~0)); 352 fixedHeader[0] |= (chunk & CHUNK); 353 354 if ((chunk & CHUNK_NEXT) == 0) fixedHeader[1] = (byte)((dtnf.toByte() << 4) & 0xf0); 357 358 fixedHeader[1] |= (byte)(CURRENT_OPT_T & 0xf); 360 361 fixedHeader[2] = (byte)0; 363 fixedHeader[3] = (byte)0; 364 365 if ((chunk & CHUNK_NEXT) == 0) 367 { fixedHeader[4] = (byte)((id.length >>> 8) & 0xff); 369 fixedHeader[5] = (byte)((id.length) & 0xff); 370 } 371 372 if ((chunk & CHUNK_NEXT) == 0) 374 { 375 fixedHeader[6] = (byte)((type.length >>> 8) & 0xff); 376 fixedHeader[7] = (byte)((type.length) & 0xff); 377 } 378 379 fixedHeader[8] = (byte)((length >>> 24) & 0xff); 381 fixedHeader[9] = (byte)((length >>> 16) & 0xff); 382 fixedHeader[10] = (byte)((length >>> 8) & 0xff); 383 fixedHeader[11] = (byte)(length & 0xff); 384 385 os.write(fixedHeader); 386 387 390 if ((chunk & CHUNK_NEXT) == 0) 392 { 393 os.write(id); 394 os.write(pad, 0, dimePadding(id.length)); 395 } 396 397 if ((chunk & CHUNK_NEXT) == 0) 399 { 400 os.write(type); 401 os.write(pad, 0, dimePadding(type.length)); 402 } 403 } 404 405 static final int dimePadding(long l) 406 { 407 return (int)((4L - (l & 0x3L)) & 0x03L); 408 } 409 410 long getTransmissionSize(long chunkSize) 411 { 412 long size = 0; 413 size += id.length; 414 size += dimePadding(id.length); 415 size += type.length; 416 size += dimePadding(type.length); 417 long dataSize = getDataSize(); 419 420 if (0 == dataSize) 421 { 422 size += 12; } 424 else 425 { 426 427 long fullChunks = dataSize / chunkSize; 428 long lastChunkSize = dataSize % chunkSize; 429 430 if (0 != lastChunkSize) size += 12; size += 12 * fullChunks; size += fullChunks * dimePadding(chunkSize); 433 size += dimePadding(lastChunkSize); 434 size += dataSize; 435 } 436 return size; 437 } 438 439 long getTransmissionSize() 440 { 441 return getTransmissionSize(MAX_DWORD); 442 } 443 444 protected long getDataSize() 445 { 446 if (data instanceof byte[]) return ((byte[])(data)).length; 447 if (data instanceof DataHandler ) 448 return getDataSize((DataHandler )data); 449 return -1; 450 } 451 452 protected long getDataSize(DataHandler dh) 453 { 454 long dataSize = -1L; 455 456 try 457 { 458 DataSource ds = dh.getDataSource(); 459 460 if (ds instanceof javax.activation.FileDataSource ) 463 { 464 javax.activation.FileDataSource fdh = 465 (javax.activation.FileDataSource )ds; 466 java.io.File df = fdh.getFile(); 467 468 if (!df.exists()) 469 { 470 throw new RuntimeException (Messages.getMessage("noFile", 471 df.getAbsolutePath())); 472 } 473 dataSize = df.length(); 474 } 475 else 476 { 477 dataSize = 0; 478 java.io.InputStream in = ds.getInputStream(); 479 byte[] readbuf = new byte[64 * 1024]; 480 int bytesread; 481 482 do 483 { 484 bytesread = in.read(readbuf); 485 if (bytesread > 0) dataSize += bytesread; 486 } 487 while (bytesread > -1); 488 489 if (in.markSupported()) 490 { 491 in.reset(); 494 } 495 else 496 { 497 in.close(); 498 } 499 } 500 } 501 catch (Exception e) 502 { 503 log.error(Messages.getMessage("exception00"), e); 504 } 505 return dataSize; 506 } 507 } 508 | Popular Tags |