46 |
import org.omg.CORBA.MARSHAL; |
import org.omg.CORBA.MARSHAL; |
47 |
import org.omg.CORBA.NO_IMPLEMENT; |
import org.omg.CORBA.NO_IMPLEMENT; |
48 |
import org.omg.CORBA.StringSeqHelper; |
import org.omg.CORBA.StringSeqHelper; |
49 |
|
import org.omg.CORBA.portable.*; |
50 |
import org.omg.CORBA.portable.InputStream; |
import org.omg.CORBA.portable.InputStream; |
51 |
import org.omg.CORBA.portable.OutputStream; |
import org.omg.CORBA.portable.OutputStream; |
52 |
import org.omg.CORBA.portable.Streamable; |
import org.omg.CORBA.portable.Streamable; |
56 |
import java.io.IOException; |
import java.io.IOException; |
57 |
import java.io.Serializable; |
import java.io.Serializable; |
58 |
|
|
59 |
|
import java.lang.reflect.Method; |
60 |
|
|
61 |
/** |
/** |
62 |
* A specialised class for reading and writing the value types. |
* A specialised class for reading and writing the value types. |
63 |
* |
* |
225 |
throw new MARSHAL("Unable to instantiate the value type"); |
throw new MARSHAL("Unable to instantiate the value type"); |
226 |
else |
else |
227 |
{ |
{ |
228 |
read_instance(input, ox, value_tag); |
read_instance(input, ox, value_tag, null); |
229 |
return (Serializable) ox; |
return (Serializable) ox; |
230 |
} |
} |
231 |
} |
} |
288 |
} |
} |
289 |
} |
} |
290 |
|
|
291 |
read_instance(input, ox, value_tag); |
read_instance(input, ox, value_tag, null); |
292 |
return (Serializable) ox; |
return (Serializable) ox; |
293 |
} |
} |
294 |
catch (Exception ex) |
catch (Exception ex) |
304 |
* an instance. |
* an instance. |
305 |
* |
* |
306 |
* @param input a stream to read from. |
* @param input a stream to read from. |
307 |
* @param value_instance an instance of the value. |
* |
308 |
|
* @param value_instance an pre-created instance of the value. If the |
309 |
|
* helper is not null, this parameter is ignored an should be null. |
310 |
|
* |
311 |
|
* @param helper a helper to create an instance and read the object- |
312 |
|
* specific part of the record. If the value_instance is used instead, |
313 |
|
* this parameter should be null. |
314 |
* |
* |
315 |
* @return the loaded value. |
* @return the loaded value. |
316 |
* |
* |
317 |
* @throws MARSHAL if the reading has failed due any reason. |
* @throws MARSHAL if the reading has failed due any reason. |
318 |
*/ |
*/ |
319 |
public static Serializable read(InputStream input, Serializable value_instance) |
public static Object read(InputStream input, Object value_instance, |
320 |
|
Object helper |
321 |
|
) |
322 |
{ |
{ |
|
// Explicitly prevent the stream from closing as we may need |
|
|
// to read the subsequent bytes as well. Stream may be auto-closed |
|
|
// in its finalizer. |
|
323 |
try |
try |
324 |
{ |
{ |
325 |
int value_tag = input.read_long(); |
int value_tag = input.read_long(); |
353 |
} |
} |
354 |
} |
} |
355 |
|
|
356 |
read_instance(input, value_instance, value_tag); |
value_instance = |
357 |
return (Serializable) value_instance; |
read_instance(input, value_instance, value_tag, helper); |
358 |
|
return value_instance; |
359 |
} |
} |
360 |
catch (Exception ex) |
catch (Exception ex) |
361 |
{ |
{ |
364 |
} |
} |
365 |
|
|
366 |
/** |
/** |
367 |
|
* Read using provided boxed value helper. This method expects |
368 |
|
* the full value type header, followed by contents, that are |
369 |
|
* delegated to the provided helper. It handles null. |
370 |
|
* |
371 |
|
* @param input the stream to read from. |
372 |
|
* @param helper the helper that reads the type-specific part of |
373 |
|
* the content. |
374 |
|
* |
375 |
|
* @return the value, created by the helper, or null if the |
376 |
|
* header indicates that null was previously written. |
377 |
|
*/ |
378 |
|
public static Serializable read(InputStream input, Object helper) |
379 |
|
{ |
380 |
|
return (Serializable) read(input, null, helper); |
381 |
|
} |
382 |
|
|
383 |
|
/** |
384 |
* Fill in the instance fields by the data from the input stream. |
* Fill in the instance fields by the data from the input stream. |
385 |
* The method assumes that the value header, if any, is already |
* The method assumes that the value header, if any, is already |
386 |
* behind. The information from the stream is stored into the |
* behind. The information from the stream is stored into the |
387 |
* passed ox parameter. |
* passed ox parameter. |
388 |
* |
* |
389 |
* @param input an input stream to read from. |
* @param input an input stream to read from. |
390 |
* @param value a value type object, must be either Streamable or |
* |
391 |
* CustomMarshal. |
* @param value a pre-instantiated value type object, must be either |
392 |
*/ |
* Streamable or CustomMarshal. If the helper is used, this parameter |
393 |
public static void read_instance(InputStream input, Object value, |
* is ignored and should be null. |
394 |
int value_tag |
* |
395 |
) |
* @param value_tag the tag that must be read previously. |
396 |
|
* @param helper the helper for read object specific part; may be |
397 |
|
* null to read in using other methods. |
398 |
|
* |
399 |
|
* @return the value that was read. |
400 |
|
*/ |
401 |
|
private static Object read_instance(InputStream input, Object value, |
402 |
|
int value_tag, Object helper |
403 |
|
) |
404 |
{ |
{ |
405 |
try |
try |
406 |
{ |
{ |
411 |
|
|
412 |
// Read all chunks. |
// Read all chunks. |
413 |
int chunk_size = input.read_long(); |
int chunk_size = input.read_long(); |
414 |
if (chunk_size <= 0) |
if (chunk_size < 0) |
415 |
throw new MARSHAL("Invalid first chunk size " + chunk_size); |
throw new MARSHAL("Invalid first chunk size " + chunk_size); |
416 |
|
|
417 |
byte[] r = new byte[ chunk_size ]; |
byte[] r = new byte[ chunk_size ]; |
446 |
// More than one chunk was present. |
// More than one chunk was present. |
447 |
// Add the last chunk. |
// Add the last chunk. |
448 |
bout.write(r, 0, n); |
bout.write(r, 0, n); |
449 |
input = new cdrBufInput(bout.toByteArray()); |
input = new noHeaderInput(bout.toByteArray()); |
450 |
} |
} |
451 |
else |
else |
452 |
{ |
{ |
453 |
// Only one chunk was present. |
// Only one chunk was present. |
454 |
input = new cdrBufInput(r); |
input = new noHeaderInput(r); |
455 |
|
} |
456 |
|
} |
457 |
|
else |
458 |
|
{ |
459 |
|
if (input instanceof cdrBufInput) |
460 |
|
{ |
461 |
|
// Highly probable case. |
462 |
|
input = |
463 |
|
new noHeaderInput(((cdrBufInput) input).buffer.getBuffer()); |
464 |
|
} |
465 |
|
else |
466 |
|
{ |
467 |
|
cdrBufOutput bout = new cdrBufOutput(); |
468 |
|
int c; |
469 |
|
while ((c = input.read()) >= 0) |
470 |
|
bout.write((byte) c); |
471 |
|
input = new noHeaderInput(bout.buffer.toByteArray()); |
472 |
} |
} |
473 |
} |
} |
474 |
} |
} |
498 |
{ |
{ |
499 |
((Streamable) value)._read(input); |
((Streamable) value)._read(input); |
500 |
} |
} |
501 |
|
else if (helper instanceof BoxedValueHelper) |
502 |
|
value = ((BoxedValueHelper) helper).read_value(input); |
503 |
|
else if (helper instanceof ValueFactory) |
504 |
|
value = |
505 |
|
((ValueFactory) helper).read_value((org.omg.CORBA_2_3.portable.InputStream) input); |
506 |
else |
else |
507 |
|
|
508 |
// Stating the interfaces that the USER should use. |
// Stating the interfaces that the USER should use. |
518 |
if (eor >= 0) |
if (eor >= 0) |
519 |
throw new MARSHAL("End of state marker has an invalid value " + eor); |
throw new MARSHAL("End of state marker has an invalid value " + eor); |
520 |
} |
} |
521 |
|
|
522 |
|
return value; |
523 |
} |
} |
524 |
|
|
525 |
/** |
/** |
585 |
if (value == null) |
if (value == null) |
586 |
output.write_long(vt_NULL); |
output.write_long(vt_NULL); |
587 |
else |
else |
588 |
write_instance(output, value, id); |
write_instance(output, value, id, null); |
589 |
|
} |
590 |
|
|
591 |
|
/** |
592 |
|
* Write standard value type header, followed by contents, produced |
593 |
|
* by the boxed value helper. |
594 |
|
* |
595 |
|
* @param output the stream to write to. |
596 |
|
* @param value the value to write, can be null. |
597 |
|
* @param helper the helper that writes the value content if it is |
598 |
|
* not null. |
599 |
|
*/ |
600 |
|
public static void write(OutputStream output, Serializable value, |
601 |
|
Object helper |
602 |
|
) |
603 |
|
{ |
604 |
|
if (value == null) |
605 |
|
output.write_long(vt_NULL); |
606 |
|
else |
607 |
|
{ |
608 |
|
String id; |
609 |
|
|
610 |
|
if (helper instanceof BoxedValueHelper) |
611 |
|
id = ((BoxedValueHelper) helper).get_id(); |
612 |
|
else |
613 |
|
id = ""; |
614 |
|
|
615 |
|
write_instance(output, value, id, helper); |
616 |
|
} |
617 |
} |
} |
618 |
|
|
619 |
/** |
/** |
623 |
* @param output an output stream to write into. |
* @param output an output stream to write into. |
624 |
* @param value a value to write. |
* @param value a value to write. |
625 |
* @param id a value repository id. |
* @param id a value repository id. |
626 |
|
* @param helper a helper, writing object - specifica part. Can be null |
627 |
|
* if the value should be written unsing other methods. |
628 |
*/ |
*/ |
629 |
private static void write_instance(OutputStream output, Serializable value, |
private static void write_instance(OutputStream output, Serializable value, |
630 |
String id |
String id, Object helper |
631 |
) |
) |
632 |
{ |
{ |
633 |
// This implementation always writes a single repository id. |
// This implementation always writes a single repository id. |
651 |
output.write_long(value_tag); |
output.write_long(value_tag); |
652 |
output.write_string(id); |
output.write_string(id); |
653 |
|
|
654 |
|
if (helper instanceof BoxedValueHelper) |
655 |
|
{ |
656 |
|
((BoxedValueHelper) helper).write_value(outObj, value); |
657 |
|
} |
658 |
|
else |
659 |
// User defince write method is present. |
// User defince write method is present. |
660 |
if (value instanceof CustomMarshal) |
if (value instanceof CustomMarshal) |
661 |
{ |
{ |
673 |
((Streamable) value)._write(outObj); |
((Streamable) value)._write(outObj); |
674 |
} |
} |
675 |
else |
else |
676 |
|
{ |
677 |
|
// Try to find helper via class loader. |
678 |
|
boolean ok = false; |
679 |
|
try |
680 |
|
{ |
681 |
|
Class helperClass = Class.forName(ObjectCreator.toHelperName(id)); |
682 |
|
|
683 |
// Stating the interfaces that the USER should use. |
// It will be the helper for the encapsulated boxed value, not the |
684 |
throw new MARSHAL("The " + value.getClass().getName() + |
// for the global boxed value type itself. |
685 |
" must implement either StreamableValue or CustomValue." |
Method write = |
686 |
); |
helperClass.getMethod("write", |
687 |
|
new Class[] |
688 |
|
{ |
689 |
|
org.omg.CORBA.portable.OutputStream.class, |
690 |
|
value.getClass() |
691 |
|
} |
692 |
|
); |
693 |
|
write.invoke(null, new Object[] { outObj, value }); |
694 |
|
ok = true; |
695 |
|
} |
696 |
|
catch (Exception ex) |
697 |
|
{ |
698 |
|
ok = false; |
699 |
|
} |
700 |
|
|
701 |
|
// Stating the interfaces that the USER should use. |
702 |
|
if (!ok) |
703 |
|
throw new MARSHAL("The " + value.getClass().getName() + |
704 |
|
" must implement either StreamableValue" + |
705 |
|
" or CustomValue." |
706 |
|
); |
707 |
|
} |
708 |
|
|
709 |
if (USE_CHUNKING) |
if (USE_CHUNKING) |
710 |
{ |
{ |
731 |
* |
* |
732 |
* @throws NO_IMPLEMENT, always. |
* @throws NO_IMPLEMENT, always. |
733 |
*/ |
*/ |
734 |
private static void incorrect_plug_in(Throwable ex) |
static void incorrect_plug_in(Throwable ex) |
735 |
throws NO_IMPLEMENT |
throws NO_IMPLEMENT |
736 |
{ |
{ |
737 |
NO_IMPLEMENT no = new NO_IMPLEMENT("Incorrect CORBA plug-in"); |
NO_IMPLEMENT no = new NO_IMPLEMENT("Incorrect CORBA plug-in"); |
738 |
no.initCause(ex); |
no.initCause(ex); |