001 package jigcell.compare.data;
002
003 import java.awt.datatransfer.DataFlavor;
004 import java.awt.datatransfer.UnsupportedFlavorException;
005 import java.io.IOException;
006 import java.io.InputStream;
007 import java.io.PipedReader;
008 import java.io.PipedWriter;
009 import java.io.Reader;
010 import java.text.NumberFormat;
011 import jigcell.compare.IDataElement;
012 import jigcell.compare.IEditableDataElement;
013 import jigcell.compare.impl.ComparatorDataFlavor;
014 import jigcell.compare.impl.Transferer;
015
016 /**
017 * A helper implementation for data element classes. Provides a default implementation for every method required by DataElement. All of the
018 * access methods act as if this element is empty.
019 *
020 * <p>
021 * This code is licensed under the DARPA BioCOMP Open Source License. See LICENSE for more details.
022 * </p>
023 *
024 * @author Nicholas Allen
025 */
026
027 public class DataElement extends Transferer implements IDataElement {
028
029 /**
030 * Size of long constant pool
031 */
032
033 public final static int SIZE_LONGPOOL = 128;
034
035 /**
036 * Long constant pool
037 */
038
039 public final static Long LONGPOOL [];
040
041 /**
042 * Pattern for boolean false
043 */
044
045 public final static String PATTERN_FALSE = "false";
046
047 /**
048 * Pattern for NaN
049 */
050
051 public final static String PATTERN_NAN = "nan";
052
053 /**
054 * Pattern for -Infinity
055 */
056
057 public final static String PATTERN_NINFINITY = "-infinity";
058
059 /**
060 * Alternate pattern for -Infinity
061 */
062
063 public final static String PATTERN_NINFINITY2 = "-inf";
064
065 /**
066 * Pattern for null
067 */
068
069 public final static String PATTERN_NULL = "null";
070
071 /**
072 * Pattern for +Infinity
073 */
074
075 public final static String PATTERN_PINFINITY = "infinity";
076
077 /**
078 * Alternate pattern for +Infinity
079 */
080
081 public final static String PATTERN_PINFINITY2 = "inf";
082
083 /**
084 * Pattern for boolean true
085 */
086
087 public final static String PATTERN_TRUE = "true";
088
089 /**
090 * Pattern for void
091 */
092
093 public final static String PATTERN_VOID = "no value";
094
095 /**
096 * Count of number of locking operations committed to
097 */
098
099 protected transient int lockCount;
100
101 static {
102 addFlavor (IDataElement.class, new ComparatorDataFlavor ("Data Element", IDataElement.class, ComparatorDataFlavor.FLAVOR_LOCALOBJECT));
103 addFlavor (IDataElement.class,
104 new ComparatorDataFlavor ("Data Element", InputStream.class, ComparatorDataFlavor.FLAVOR_XMLSERIALIZEDOBJECT));
105 addFlavor (IDataElement.class,
106 new ComparatorDataFlavor ("Data Element", IDataElement.class, ComparatorDataFlavor.FLAVOR_SERIALIZEDOBJECT));
107 addFlavor (IDataElement.class, new ComparatorDataFlavor ("Data Element", Reader.class, ComparatorDataFlavor.FLAVOR_TEXTPLAIN));
108 LONGPOOL = new Long [SIZE_LONGPOOL + 1];
109 for (int i = 0, l = LONGPOOL.length; i < l; i++)
110 LONGPOOL [i] = new Long (i - 1);
111 }
112
113 /**
114 * Returns a constant out of the long constant pool or a new constant.
115 *
116 * @param value Value
117 */
118
119 public static Long getLongObject (long value) {
120 return value >= -1 && value < SIZE_LONGPOOL ? LONGPOOL [(int) value + 1] : new Long (value);
121 }
122
123 /**
124 * Whether a text string represents a special non-numeric value.
125 *
126 * @param text String to parse
127 */
128
129 public static boolean isSpecialNonNumeric (String text) {
130 text = text.trim ().toLowerCase ();
131 return PATTERN_FALSE.equals (text) || PATTERN_TRUE.equals (text) || PATTERN_VOID.equals (text) || PATTERN_NAN.equals (text) ||
132 PATTERN_PINFINITY.equals (text) || PATTERN_PINFINITY2.equals (text) || PATTERN_NINFINITY.equals (text) ||
133 PATTERN_NINFINITY2.equals (text);
134 }
135
136 /**
137 * Renders the DataElement as an ordered tuple.
138 *
139 * @param element DataElement
140 */
141
142 public static String toString (IDataElement element) {
143 if (element == null)
144 return "No Value";
145 if (element.isScalar ()) {
146 IDataElement.Type type = element.getType ();
147 return type == IDataElement.Type.NONE ? "No Value" :
148 type == IDataElement.Type.BOOLEAN ? String.valueOf (element.getBooleanValue ()) :
149 type == IDataElement.Type.INTEGRAL ? String.valueOf (element.getIntegralValue ()) :
150 type == IDataElement.Type.LITERAL ? "\"" + element.getLiteralValue () + "\"" : String.valueOf (element.getRealValue ());
151 }
152 try {
153 element.memoryLock ();
154 StringBuffer value = new StringBuffer ("(");
155 for (long i = 1, l = element.getLength (); i <= l; i++)
156 value.append ((i == 1 ? "" : ", ") + DataElement.toString (element, i));
157 return value.append (")").toString ();
158 } finally {
159 element.memoryUnlock ();
160 }
161 }
162
163 /**
164 * Renders the value of a specified position.
165 *
166 * @param element DataElement
167 * @param pos Render position
168 */
169
170 public static String toString (IDataElement element, long pos) {
171 IDataElement.Type type = element.getType (pos);
172 return type == IDataElement.Type.NONE ? "No Value" :
173 type == IDataElement.Type.BOOLEAN ? String.valueOf (element.getBooleanValue (pos)) :
174 type == IDataElement.Type.INTEGRAL ? String.valueOf (element.getIntegralValue (pos)) :
175 type == IDataElement.Type.REAL ? String.valueOf (element.getRealValue (pos)) :
176 type == IDataElement.Type.LITERAL ? "\"" + element.getLiteralValue (pos) + "\"" : DataElement.toString (element.getListValue (pos));
177 }
178
179 /**
180 * Renders the DataElement as an ordered tuple.
181 *
182 * @param element DataElement
183 * @param format Format
184 */
185
186 public static String toString (IDataElement element, NumberFormat format) {
187 if (element == null)
188 return "No Value";
189 if (element.isScalar ()) {
190 IDataElement.Type type = element.getType ();
191 return type == IDataElement.Type.NONE ? "No Value" :
192 type == IDataElement.Type.BOOLEAN ? String.valueOf (element.getBooleanValue ()) :
193 type == IDataElement.Type.INTEGRAL ? format.format (element.getIntegralValue ()) :
194 type == IDataElement.Type.LITERAL ? "\"" + element.getLiteralValue () + "\"" : format.format (element.getRealValue ());
195 }
196 try {
197 element.memoryLock ();
198 StringBuffer value = new StringBuffer ("(");
199 for (long i = 1, l = element.getLength (); i <= l; i++)
200 value.append ((i == 1 ? "" : ", ") + DataElement.toString (element, i, format));
201 return value.append (")").toString ();
202 } finally {
203 element.memoryUnlock ();
204 }
205 }
206
207 /**
208 * Renders the DataElement as an ordered tuple.
209 *
210 * @param element DataElement
211 * @param limit Whether to abbreviate the string.
212 * @param size Approximate length before abbreviation occurs.
213 */
214
215 public static String toString (IDataElement element, boolean limit, int size) {
216 if (element == null)
217 return "No Value";
218 if (element.isScalar ()) {
219 IDataElement.Type type = element.getType ();
220 return type == IDataElement.Type.NONE ? "No Value" :
221 type == IDataElement.Type.BOOLEAN ? String.valueOf (element.getBooleanValue ()) :
222 type == IDataElement.Type.INTEGRAL ? String.valueOf (element.getIntegralValue ()) :
223 type == IDataElement.Type.LITERAL ? "\"" + element.getLiteralValue () + "\"" : String.valueOf (element.getRealValue ());
224 }
225 StringBuffer value = new StringBuffer ("(");
226 if (limit)
227 for (long i = 1, l = element.getLength (); i <= l; i++) {
228 int remain = size - value.length ();
229 if (remain <= 0) {
230 value.append ("...");
231 break;
232 } else
233 value.append ((i == 1 ? "" : ", ") + DataElement.toString (element, true, remain, i));
234 }
235 else
236 for (long i = 1, l = element.getLength (); i <= l; i++)
237 value.append ((i == 1 ? "" : ", ") + DataElement.toString (element, i));
238 return value.append (")").toString ();
239 }
240
241 /**
242 * Renders the value of a specified position.
243 *
244 * @param element DataElement
245 * @param pos Render position
246 * @param format Format
247 */
248
249 public static String toString (IDataElement element, long pos, NumberFormat format) {
250 IDataElement.Type type = element.getType (pos);
251 return type == IDataElement.Type.NONE ? "No Value" :
252 type == IDataElement.Type.BOOLEAN ? String.valueOf (element.getBooleanValue (pos)) :
253 type == IDataElement.Type.INTEGRAL ? format.format (element.getIntegralValue (pos)) :
254 type == IDataElement.Type.REAL ? format.format (element.getRealValue (pos)) :
255 type == IDataElement.Type.LITERAL ? "\"" + element.getLiteralValue (pos) + "\"" :
256 DataElement.toString (element.getListValue (pos), format);
257 }
258
259 /**
260 * Renders the DataElement as an ordered tuple.
261 *
262 * @param element DataElement
263 * @param limit Whether to abbreviate the string.
264 * @param size Approximate length before abbreviation occurs.
265 * @param format Format
266 */
267
268 public static String toString (IDataElement element, boolean limit, int size, NumberFormat format) {
269 if (element == null)
270 return "No Value";
271 if (element.isScalar ()) {
272 IDataElement.Type type = element.getType ();
273 return type == IDataElement.Type.NONE ? "No Value" :
274 type == IDataElement.Type.BOOLEAN ? String.valueOf (element.getBooleanValue ()) :
275 type == IDataElement.Type.INTEGRAL ? format.format (element.getIntegralValue ()) :
276 type == IDataElement.Type.LITERAL ? "\"" + element.getLiteralValue () + "\"" : format.format (element.getRealValue ());
277 }
278 StringBuffer value = new StringBuffer ("(");
279 if (limit)
280 for (long i = 1, l = element.getLength (); i <= l; i++) {
281 int remain = size - value.length ();
282 if (remain <= 0) {
283 value.append ("...");
284 break;
285 } else
286 value.append ((i == 1 ? "" : ", ") + DataElement.toString (element, true, remain, i, format));
287 }
288 else
289 for (long i = 1, l = element.getLength (); i <= l; i++)
290 value.append ((i == 1 ? "" : ", ") + DataElement.toString (element, i, format));
291 return value.append (")").toString ();
292 }
293
294 /**
295 * Renders the value of a specified position.
296 *
297 * @param element DataElement
298 * @param limit Whether to abbreviate the string.
299 * @param size Approximate length before abbreviation occurs.
300 * @param pos Render position
301 */
302
303 public static String toString (IDataElement element, boolean limit, int size, long pos) {
304 IDataElement.Type type = element.getType (pos);
305 return type == IDataElement.Type.NONE ? "No Value" :
306 type == IDataElement.Type.BOOLEAN ? String.valueOf (element.getBooleanValue (pos)) :
307 type == IDataElement.Type.INTEGRAL ? String.valueOf (element.getIntegralValue (pos)) :
308 type == IDataElement.Type.REAL ? String.valueOf (element.getRealValue (pos)) :
309 type == IDataElement.Type.LITERAL ? "\"" + element.getLiteralValue () + "\"" :
310 limit ? DataElement.toString (element.getListValue (pos), limit, size) : DataElement.toString (element.getListValue (pos));
311 }
312
313 /**
314 * Renders the value of a specified position.
315 *
316 * @param element DataElement
317 * @param limit Whether to abbreviate the string.
318 * @param size Approximate length before abbreviation occurs.
319 * @param pos Render position
320 * @param format Format
321 */
322
323 public static String toString (IDataElement element, boolean limit, int size, long pos, NumberFormat format) {
324 IDataElement.Type type = element.getType (pos);
325 return type == IDataElement.Type.NONE ? "No Value" :
326 type == IDataElement.Type.BOOLEAN ? String.valueOf (element.getBooleanValue (pos)) :
327 type == IDataElement.Type.INTEGRAL ? format.format (element.getIntegralValue (pos)) :
328 type == IDataElement.Type.REAL ? format.format (element.getRealValue (pos)) :
329 type == IDataElement.Type.LITERAL ? "\"" + element.getLiteralValue () + "\"" :
330 limit ? DataElement.toString (element.getListValue (pos), limit, size, format) :
331 DataElement.toString (element.getListValue (pos), format);
332 }
333
334 /**
335 * Creates a new data element.
336 */
337
338 public DataElement () {
339 super ();
340 }
341
342 /**
343 * {@inheritDoc}
344 */
345
346 public boolean forceBooleanValue () {
347 return forceBooleanValue (0);
348 }
349
350 /**
351 * {@inheritDoc}
352 */
353
354 public boolean forceBooleanValue (long pos) {
355 IDataElement.Type type = getType (pos);
356 return type == IDataElement.Type.BOOLEAN ? getBooleanValue (pos) :
357 type == IDataElement.Type.INTEGRAL ? getIntegralValue (pos) != 0 :
358 type == IDataElement.Type.REAL ? getRealValue (pos) != 0.0 :
359 type == IDataElement.Type.LITERAL ? Boolean.valueOf (getLiteralValue (pos)).booleanValue () : type == IDataElement.Type.MULTIPLE;
360 }
361
362 /**
363 * {@inheritDoc}
364 */
365
366 public long forceIntegralValue () {
367 return forceIntegralValue (0);
368 }
369
370 /**
371 * {@inheritDoc}
372 */
373
374 public long forceIntegralValue (long pos) {
375 IDataElement.Type type = getType (pos);
376 if (type == IDataElement.Type.INTEGRAL)
377 return getIntegralValue (pos);
378 if (type == IDataElement.Type.REAL)
379 return Math.round (getRealValue (pos));
380 if (type == IDataElement.Type.BOOLEAN)
381 return getBooleanValue (pos) ? 1 : 0;
382 if (type == IDataElement.Type.LITERAL)
383 try {
384 return Long.valueOf (getLiteralValue (pos)).longValue ();
385 } catch (Exception e) {}
386 return 0;
387 }
388
389 /**
390 * {@inheritDoc}
391 */
392
393 public IDataElement forceListValue (long pos) {
394 IDataElement.Type type = getType (pos);
395 if (type == IDataElement.Type.MULTIPLE)
396 return getListValue (pos);
397 IEditableDataElement element = new SparseTreeDataElement ();
398 if (type == IDataElement.Type.INTEGRAL)
399 element.setValue (1, getIntegralValue (pos));
400 else if (type == IDataElement.Type.REAL)
401 element.setValue (1, getRealValue (pos));
402 else if (type == IDataElement.Type.BOOLEAN)
403 element.setValue (1, getBooleanValue (pos));
404 else if (type == IDataElement.Type.LITERAL)
405 element.setValue (1, getLiteralValue (pos));
406 return element;
407 }
408
409 /**
410 * {@inheritDoc}
411 */
412
413 public String forceLiteralValue () {
414 String value = getLiteralValue ();
415 return value == null ? toString () : value;
416 }
417
418 /**
419 * {@inheritDoc}
420 */
421
422 public String forceLiteralValue (long pos) {
423 String value = getLiteralValue ();
424 return value == null ? toString (pos) : value;
425 }
426
427 /**
428 * {@inheritDoc}
429 */
430
431 public double forceRealValue () {
432 return forceRealValue (0);
433 }
434
435 /**
436 * {@inheritDoc}
437 */
438
439 public double forceRealValue (long pos) {
440 IDataElement.Type type = getType (pos);
441 if (type == IDataElement.Type.REAL)
442 return getRealValue (pos);
443 if (type == IDataElement.Type.INTEGRAL)
444 return (double) getIntegralValue (pos);
445 if (type == IDataElement.Type.BOOLEAN)
446 return getBooleanValue (pos) ? 1.0 : 0.0;
447 if (type == IDataElement.Type.LITERAL)
448 try {
449 return Double.valueOf (getLiteralValue (pos)).doubleValue ();
450 } catch (Exception e) {}
451 return Double.NaN;
452 }
453
454 /**
455 * {@inheritDoc}
456 */
457
458 public boolean [] forceSlice (boolean slice [], long start, int length, long stride) {
459 boolean value [] = getSlice (slice, start, length, stride);
460 if (value != null)
461 return value;
462 value = slice == null || slice.length < length ? new boolean [length] : slice;
463 long pos = start;
464 for (int i = 0; i < length; pos += stride) {
465 IDataElement.Type type = getType (pos);
466 value [i++] = type == IDataElement.Type.BOOLEAN ? getBooleanValue (pos) :
467 type == IDataElement.Type.INTEGRAL ? getIntegralValue (pos) != 0 :
468 type == IDataElement.Type.REAL ? getRealValue (pos) != 0.0 :
469 type == IDataElement.Type.LITERAL ? Boolean.valueOf (getLiteralValue (pos)).booleanValue () : type == IDataElement.Type.MULTIPLE;
470 }
471 return value;
472 }
473
474 /**
475 * {@inheritDoc}
476 */
477
478 public IDataElement [] forceSlice (IDataElement slice [], long start, int length, long stride) {
479 IDataElement value [] = getSlice (slice, start, length, stride);
480 if (value != null)
481 return value;
482 value = slice == null || slice.length < length ? new IDataElement [length] : slice;
483 long pos = start;
484 for (int i = 0; i < length; pos += stride) {
485 IDataElement.Type type = getType (pos);
486 if (type == IDataElement.Type.MULTIPLE) {
487 value [i++] = getListValue (pos);
488 continue;
489 }
490 IEditableDataElement element = new SparseTreeDataElement ();
491 if (type == IDataElement.Type.INTEGRAL)
492 element.setValue (1, getIntegralValue (pos));
493 else if (type == IDataElement.Type.REAL)
494 element.setValue (1, getRealValue (pos));
495 else if (type == IDataElement.Type.BOOLEAN)
496 element.setValue (1, getBooleanValue (pos));
497 else if (type == IDataElement.Type.LITERAL)
498 element.setValue (1, getLiteralValue (pos));
499 value [i++] = element;
500 }
501 return value;
502 }
503
504 /**
505 * {@inheritDoc}
506 */
507
508 public double [] forceSlice (double slice [], long start, int length, long stride) {
509 double value [] = getSlice (slice, start, length, stride);
510 if (value != null)
511 return value;
512 value = slice == null || slice.length < length ? new double [length] : slice;
513 long pos = start;
514 for (int i = 0; i < length; pos += stride) {
515 IDataElement.Type type = getType (pos);
516 value [i++] = type == IDataElement.Type.REAL ? getRealValue (pos) :
517 type == IDataElement.Type.INTEGRAL ? (double) getIntegralValue (pos) :
518 type == IDataElement.Type.BOOLEAN ? getBooleanValue (pos) ? 1.0 : 0.0 :
519 type == IDataElement.Type.LITERAL ? Double.valueOf (getLiteralValue (pos)).doubleValue () : Double.NaN;
520 }
521 return value;
522 }
523
524 /**
525 * {@inheritDoc}
526 */
527
528 public long [] forceSlice (long slice [], long start, int length, long stride) {
529 long value [] = getSlice (slice, start, length, stride);
530 if (value != null)
531 return value;
532 value = slice == null || slice.length < length ? new long [length] : slice;
533 long pos = start;
534 for (int i = 0; i < length; pos += stride) {
535 IDataElement.Type type = getType (pos);
536 value [i++] = type == IDataElement.Type.INTEGRAL ? getIntegralValue (pos) :
537 type == IDataElement.Type.REAL ? Math.round (getRealValue (pos)) :
538 type == IDataElement.Type.BOOLEAN ? getBooleanValue (pos) ? 1 : 0 :
539 type == IDataElement.Type.LITERAL ? Long.valueOf (getLiteralValue (pos)).longValue () : 0;
540 }
541 return value;
542 }
543
544 /**
545 * {@inheritDoc}
546 */
547
548 public String [] forceSlice (String slice [], long start, int length, long stride) {
549 String value [] = getSlice (slice, start, length, stride);
550 if (value != null)
551 return value;
552 value = slice == null || slice.length < length ? new String [length] : slice;
553 long pos = start;
554 for (int i = 0; i < length; pos += stride) {
555 String literal = getLiteralValue (pos);
556 value [i++] = literal == null ? toString (pos) : literal;
557 }
558 return value;
559 }
560
561 /**
562 * {@inheritDoc}
563 */
564
565 public boolean getBooleanValue () {
566 return getBooleanValue (0);
567 }
568
569 /**
570 * {@inheritDoc}
571 */
572
573 public boolean getBooleanValue (long pos) {
574 return false;
575 }
576
577 /**
578 * {@inheritDoc}
579 */
580
581 public long getIntegralValue () {
582 return getIntegralValue (0);
583 }
584
585 /**
586 * {@inheritDoc}
587 */
588
589 public long getIntegralValue (long pos) {
590 return 0;
591 }
592
593 /**
594 * {@inheritDoc}
595 */
596
597 public long getLength () {
598 return 0;
599 }
600
601 /**
602 * {@inheritDoc}
603 */
604
605 public IDataElement getListValue (long pos) {
606 return null;
607 }
608
609 /**
610 * {@inheritDoc}
611 */
612
613 public String getLiteralValue () {
614 return getLiteralValue (0);
615 }
616
617 /**
618 * {@inheritDoc}
619 */
620
621 public String getLiteralValue (long pos) {
622 return null;
623 }
624
625 /**
626 * {@inheritDoc}
627 */
628
629 public double getRealValue () {
630 return getRealValue (0);
631 }
632
633 /**
634 * {@inheritDoc}
635 */
636
637 public double getRealValue (long pos) {
638 return Double.NaN;
639 }
640
641 /**
642 * {@inheritDoc}
643 */
644
645 public boolean [] getSlice (boolean slice [], long start, int length, long stride) {
646 boolean value [] = slice == null || slice.length < length ? new boolean [length] : slice;
647 long pos = start;
648 for (int i = 0; i < length; pos += stride) {
649 IDataElement.Type type = getType (pos);
650 if (type == IDataElement.Type.BOOLEAN)
651 value [i++] = getBooleanValue (pos);
652 else
653 return null;
654 }
655 return value;
656 }
657
658 /**
659 * {@inheritDoc}
660 */
661
662 public IDataElement [] getSlice (IDataElement slice [], long start, int length, long stride) {
663 IDataElement value [] = slice == null || slice.length < length ? new IDataElement [length] : slice;
664 long pos = start;
665 for (int i = 0; i < length; pos += stride) {
666 IDataElement.Type type = getType (pos);
667 if (type == IDataElement.Type.MULTIPLE)
668 value [i++] = getListValue (pos);
669 else
670 return null;
671 }
672 return value;
673 }
674
675 /**
676 * {@inheritDoc}
677 */
678
679 public double [] getSlice (double slice [], long start, int length, long stride) {
680 double value [] = slice == null || slice.length < length ? new double [length] : slice;
681 long pos = start;
682 for (int i = 0; i < length; pos += stride) {
683 IDataElement.Type type = getType (pos);
684 if (type == IDataElement.Type.REAL)
685 value [i++] = getRealValue (pos);
686 else
687 return null;
688 }
689 return value;
690 }
691
692 /**
693 * {@inheritDoc}
694 */
695
696 public long [] getSlice (long slice [], long start, int length, long stride) {
697 long value [] = slice == null || slice.length < length ? new long [length] : slice;
698 long pos = start;
699 for (int i = 0; i < length; pos += stride) {
700 IDataElement.Type type = getType (pos);
701 if (type == IDataElement.Type.INTEGRAL)
702 value [i++] = getIntegralValue (pos);
703 else
704 return null;
705 }
706 return value;
707 }
708
709 /**
710 * {@inheritDoc}
711 */
712
713 public String [] getSlice (String slice [], long start, int length, long stride) {
714 String value [] = slice == null || slice.length < length ? new String [length] : slice;
715 long pos = start;
716 for (int i = 0; i < length; pos += stride) {
717 IDataElement.Type type = getType (pos);
718 if (type == IDataElement.Type.LITERAL)
719 value [i++] = getLiteralValue (pos);
720 else
721 return null;
722 }
723 return value;
724 }
725
726 /**
727 * {@inheritDoc}
728 */
729
730 public Object getTransferData (DataFlavor flavor) throws UnsupportedFlavorException, IOException {
731 if (!(flavor instanceof ComparatorDataFlavor))
732 throw new UnsupportedFlavorException (flavor);
733 ComparatorDataFlavor type = (ComparatorDataFlavor) flavor;
734 if (!type.isFlavorPlainTextType () || !type.getRepresentationClass ().isAssignableFrom (PipedReader.class))
735 return super.getTransferData (flavor);
736 PipedWriter out = new PipedWriter ();
737 out.write (toString ());
738 return new PipedReader (out);
739 }
740
741 /**
742 * {@inheritDoc}
743 */
744
745 public IDataElement.Type getType () {
746 return getType (0);
747 }
748
749 /**
750 * {@inheritDoc}
751 */
752
753 public IDataElement.Type getType (long pos) {
754 return IDataElement.Type.NONE;
755 }
756
757 /**
758 * {@inheritDoc}
759 */
760
761 public boolean isAvailable () {
762 if (lockCount > 0)
763 return true;
764 for (long i = 1, l = getLength (); i < l; i++) {
765 IDataElement value = getListValue (i);
766 if (value != null && !value.isAvailable ())
767 return false;
768 }
769 return true;
770 }
771
772 /**
773 * {@inheritDoc}
774 */
775
776 public boolean isScalar () {
777 return getLength () == 0;
778 }
779
780 /**
781 * {@inheritDoc}
782 */
783
784 public void memoryLock () {
785 if (lockCount++ > 0)
786 return;
787 for (long i = 1, l = getLength (); i < l; i++) {
788 IDataElement value = getListValue (i);
789 if (value != null)
790 value.memoryLock ();
791 }
792 }
793
794 /**
795 * {@inheritDoc}
796 */
797
798 public void memoryUnlock () {
799 if (--lockCount > 0)
800 return;
801 for (long i = 1, l = getLength (); i < l; i++) {
802 IDataElement value = getListValue (i);
803 if (value != null)
804 value.memoryUnlock ();
805 }
806 }
807
808 /**
809 * Renders the DataElement as an ordered tuple.
810 */
811
812 public String toString () {
813 return toString (this);
814 }
815
816 /**
817 * {@inheritDoc}
818 */
819
820 public String toString (NumberFormat format) {
821 return toString (this, format);
822 }
823
824 /**
825 * {@inheritDoc}
826 */
827
828 public String toString (long pos) {
829 return toString (this, pos);
830 }
831
832 /**
833 * {@inheritDoc}
834 */
835
836 public String toString (boolean limit, int size) {
837 return toString (this, limit, size);
838 }
839
840 /**
841 * {@inheritDoc}
842 */
843
844 public String toString (long pos, NumberFormat format) {
845 return toString (this, pos, format);
846 }
847
848 /**
849 * {@inheritDoc}
850 */
851
852 public String toString (boolean limit, int size, NumberFormat format) {
853 return toString (this, limit, size, format);
854 }
855
856 /**
857 * {@inheritDoc}
858 */
859
860 public String toString (boolean limit, int size, long pos) {
861 return toString (this, limit, size, pos);
862 }
863
864 /**
865 * {@inheritDoc}
866 */
867
868 public String toString (boolean limit, int size, long pos, NumberFormat format) {
869 return toString (this, limit, size, pos, format);
870 }
871 }