001: /*
002: * Copyright 2001-2005 Stephen Colebourne
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.joda.time;
017:
018: import java.util.Locale;
019:
020: /**
021: * Defines the calculation engine for date and time fields.
022: * The interface defines a set of methods that manipulate a millisecond datetime
023: * with regards to a single field, such as monthOfYear or secondOfMinute.
024: * <p>
025: * This design is extensible so, if you wish, you can extract a different field from
026: * the milliseconds. A number of standard implementations are provided to assist.
027: *
028: * @author Guy Allard
029: * @author Stephen Colebourne
030: * @author Brian S O'Neill
031: * @since 1.0
032: */
033: public abstract class DateTimeField {
034:
035: /**
036: * Get the type of the field.
037: *
038: * @return field type
039: */
040: public abstract DateTimeFieldType getType();
041:
042: /**
043: * Get the name of the field.
044: * <p>
045: * By convention, names follow a pattern of "dddOfRrr", where "ddd" represents
046: * the (singular) duration unit field name and "Rrr" represents the (singular)
047: * duration range field name. If the range field is not applicable, then
048: * the name of the field is simply the (singular) duration field name.
049: *
050: * @return field name
051: */
052: public abstract String getName();
053:
054: /**
055: * Returns true if this field is supported.
056: *
057: * @return true if this field is supported
058: */
059: public abstract boolean isSupported();
060:
061: /**
062: * Returns true if the set method is lenient. If so, it accepts values that
063: * are out of bounds. For example, a lenient day of month field accepts 32
064: * for January, converting it to February 1.
065: *
066: * @return true if this field is lenient
067: */
068: public abstract boolean isLenient();
069:
070: // Main access API
071: //------------------------------------------------------------------------
072: /**
073: * Get the value of this field from the milliseconds.
074: *
075: * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
076: * @return the value of the field, in the units of the field
077: */
078: public abstract int get(long instant);
079:
080: /**
081: * Get the human-readable, text value of this field from the milliseconds.
082: * If the specified locale is null, the default locale is used.
083: *
084: * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
085: * @param locale the locale to use for selecting a text symbol, null for default
086: * @return the text value of the field
087: */
088: public abstract String getAsText(long instant, Locale locale);
089:
090: /**
091: * Get the human-readable, text value of this field from the milliseconds.
092: *
093: * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
094: * @return the text value of the field
095: */
096: public abstract String getAsText(long instant);
097:
098: /**
099: * Get the human-readable, text value of this field from a partial instant.
100: * If the specified locale is null, the default locale is used.
101: *
102: * @param partial the partial instant to query
103: * @param fieldValue the field value of this field, provided for performance
104: * @param locale the locale to use for selecting a text symbol, null for default
105: * @return the text value of the field
106: */
107: public abstract String getAsText(ReadablePartial partial,
108: int fieldValue, Locale locale);
109:
110: /**
111: * Get the human-readable, text value of this field from a partial instant.
112: * If the specified locale is null, the default locale is used.
113: *
114: * @param partial the partial instant to query
115: * @param locale the locale to use for selecting a text symbol, null for default
116: * @return the text value of the field
117: */
118: public abstract String getAsText(ReadablePartial partial,
119: Locale locale);
120:
121: /**
122: * Get the human-readable, text value of this field from the field value.
123: * If the specified locale is null, the default locale is used.
124: *
125: * @param fieldValue the numeric value to convert to text
126: * @param locale the locale to use for selecting a text symbol, null for default
127: * @return the text value of the field
128: */
129: public abstract String getAsText(int fieldValue, Locale locale);
130:
131: /**
132: * Get the human-readable, short text value of this field from the
133: * milliseconds. If the specified locale is null, the default locale is used.
134: *
135: * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
136: * @param locale the locale to use for selecting a text symbol, null for default
137: * @return the short text value of the field
138: */
139: public abstract String getAsShortText(long instant, Locale locale);
140:
141: /**
142: * Get the human-readable, short text value of this field from the
143: * milliseconds.
144: *
145: * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
146: * @return the short text value of the field
147: */
148: public abstract String getAsShortText(long instant);
149:
150: /**
151: * Get the human-readable, short text value of this field from a partial instant.
152: * If the specified locale is null, the default locale is used.
153: *
154: * @param partial the partial instant to query
155: * @param fieldValue the field value of this field, provided for performance
156: * @param locale the locale to use for selecting a text symbol, null for default
157: * @return the text value of the field
158: */
159: public abstract String getAsShortText(ReadablePartial partial,
160: int fieldValue, Locale locale);
161:
162: /**
163: * Get the human-readable, short text value of this field from a partial instant.
164: * If the specified locale is null, the default locale is used.
165: *
166: * @param partial the partial instant to query
167: * @param locale the locale to use for selecting a text symbol, null for default
168: * @return the text value of the field
169: */
170: public abstract String getAsShortText(ReadablePartial partial,
171: Locale locale);
172:
173: /**
174: * Get the human-readable, short text value of this field from the field value.
175: * If the specified locale is null, the default locale is used.
176: *
177: * @param fieldValue the numeric value to convert to text
178: * @param locale the locale to use for selecting a text symbol, null for default
179: * @return the text value of the field
180: */
181: public abstract String getAsShortText(int fieldValue, Locale locale);
182:
183: /**
184: * Adds a value (which may be negative) to the millis value,
185: * overflowing into larger fields if necessary.
186: * <p>
187: * The value will be added to this field. If the value is too large to be
188: * added solely to this field, larger fields will increase as required.
189: * Smaller fields should be unaffected, except where the result would be
190: * an invalid value for a smaller field. In this case the smaller field is
191: * adjusted to be in range.
192: * <p>
193: * For example, in the ISO chronology:<br>
194: * 2000-08-20 add six months is 2001-02-20<br>
195: * 2000-08-20 add twenty months is 2002-04-20<br>
196: * 2000-08-20 add minus nine months is 1999-11-20<br>
197: * 2001-01-31 add one month is 2001-02-28<br>
198: * 2001-01-31 add two months is 2001-03-31<br>
199: *
200: * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
201: * @param value the value to add, in the units of the field
202: * @return the updated milliseconds
203: */
204: public abstract long add(long instant, int value);
205:
206: /**
207: * Adds a value (which may be negative) to the millis value,
208: * overflowing into larger fields if necessary.
209: *
210: * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
211: * @param value the long value to add, in the units of the field
212: * @return the updated milliseconds
213: * @throws IllegalArgumentException if value is too large
214: * @see #add(long,int)
215: */
216: public abstract long add(long instant, long value);
217:
218: /**
219: * Adds a value (which may be negative) to the partial instant,
220: * throwing an exception if the maximum size of the instant is reached.
221: * <p>
222: * The value will be added to this field, overflowing into larger fields
223: * if necessary. Smaller fields should be unaffected, except where the
224: * result would be an invalid value for a smaller field. In this case the
225: * smaller field is adjusted to be in range.
226: * <p>
227: * Partial instants only contain some fields. This may result in a maximum
228: * possible value, such as TimeOfDay being limited to 23:59:59:999. If this
229: * limit is breached by the add an exception is thrown.
230: * <p>
231: * For example, in the ISO chronology:<br>
232: * 2000-08-20 add six months is 2000-02-20<br>
233: * 2000-08-20 add twenty months is 2000-04-20<br>
234: * 2000-08-20 add minus nine months is 2000-11-20<br>
235: * 2001-01-31 add one month is 2001-02-28<br>
236: * 2001-01-31 add two months is 2001-03-31<br>
237: *
238: * @param instant the partial instant
239: * @param fieldIndex the index of this field in the instant
240: * @param values the values of the partial instant which should be updated
241: * @param valueToAdd the value to add, in the units of the field
242: * @return the passed in values
243: * @throws IllegalArgumentException if the value is invalid or the maximum instant is reached
244: */
245: public abstract int[] add(ReadablePartial instant, int fieldIndex,
246: int[] values, int valueToAdd);
247:
248: /**
249: * Adds a value (which may be negative) to the partial instant,
250: * wrapping the whole partial if the maximum size of the partial is reached.
251: * <p>
252: * The value will be added to this field, overflowing into larger fields
253: * if necessary. Smaller fields should be unaffected, except where the
254: * result would be an invalid value for a smaller field. In this case the
255: * smaller field is adjusted to be in range.
256: * <p>
257: * Partial instants only contain some fields. This may result in a maximum
258: * possible value, such as TimeOfDay normally being limited to 23:59:59:999.
259: * If ths limit is reached by the addition, this method will wrap back to
260: * 00:00:00.000. In fact, you would generally only use this method for
261: * classes that have a limitation such as this.
262: * <p>
263: * For example, in the ISO chronology:<br>
264: * 10:20:30 add 20 minutes is 10:40:30<br>
265: * 10:20:30 add 45 minutes is 11:05:30<br>
266: * 10:20:30 add 16 hours is 02:20:30<br>
267: *
268: * @param instant the partial instant
269: * @param fieldIndex the index of this field in the partial
270: * @param values the values of the partial instant which should be updated
271: * @param valueToAdd the value to add, in the units of the field
272: * @return the passed in values
273: * @throws IllegalArgumentException if the value is invalid or the maximum instant is reached
274: */
275: public abstract int[] addWrapPartial(ReadablePartial instant,
276: int fieldIndex, int[] values, int valueToAdd);
277:
278: /**
279: * Adds a value (which may be negative) to the millis value,
280: * wrapping within this field.
281: * <p>
282: * The value will be added to this field. If the value is too large to be
283: * added solely to this field then it wraps. Larger fields are always
284: * unaffected. Smaller fields should be unaffected, except where the
285: * result would be an invalid value for a smaller field. In this case the
286: * smaller field is adjusted to be in range.
287: * <p>
288: * For example, in the ISO chronology:<br>
289: * 2000-08-20 addWrapField six months is 2000-02-20<br>
290: * 2000-08-20 addWrapField twenty months is 2000-04-20<br>
291: * 2000-08-20 addWrapField minus nine months is 2000-11-20<br>
292: * 2001-01-31 addWrapField one month is 2001-02-28<br>
293: * 2001-01-31 addWrapField two months is 2001-03-31<br>
294: *
295: * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to
296: * @param value the value to add, in the units of the field
297: * @return the updated milliseconds
298: */
299: public abstract long addWrapField(long instant, int value);
300:
301: /**
302: * Adds a value (which may be negative) to the partial instant,
303: * wrapping within this field.
304: * <p>
305: * The value will be added to this field. If the value is too large to be
306: * added solely to this field then it wraps. Larger fields are always
307: * unaffected. Smaller fields should be unaffected, except where the
308: * result would be an invalid value for a smaller field. In this case the
309: * smaller field is adjusted to be in range.
310: * <p>
311: * For example, in the ISO chronology:<br>
312: * 2000-08-20 addWrapField six months is 2000-02-20<br>
313: * 2000-08-20 addWrapField twenty months is 2000-04-20<br>
314: * 2000-08-20 addWrapField minus nine months is 2000-11-20<br>
315: * 2001-01-31 addWrapField one month is 2001-02-28<br>
316: * 2001-01-31 addWrapField two months is 2001-03-31<br>
317: *
318: * @param instant the partial instant
319: * @param fieldIndex the index of this field in the instant
320: * @param values the values of the partial instant which should be updated
321: * @param valueToAdd the value to add, in the units of the field
322: * @return the passed in values
323: * @throws IllegalArgumentException if the value is invalid
324: */
325: public abstract int[] addWrapField(ReadablePartial instant,
326: int fieldIndex, int[] values, int valueToAdd);
327:
328: /**
329: * Computes the difference between two instants, as measured in the units
330: * of this field. Any fractional units are dropped from the result. Calling
331: * getDifference reverses the effect of calling add. In the following code:
332: *
333: * <pre>
334: * long instant = ...
335: * int v = ...
336: * int age = getDifference(add(instant, v), instant);
337: * </pre>
338: *
339: * The value 'age' is the same as the value 'v'.
340: *
341: * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
342: * subtract from
343: * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
344: * subtract off the minuend
345: * @return the difference in the units of this field
346: */
347: public abstract int getDifference(long minuendInstant,
348: long subtrahendInstant);
349:
350: /**
351: * Computes the difference between two instants, as measured in the units
352: * of this field. Any fractional units are dropped from the result. Calling
353: * getDifference reverses the effect of calling add. In the following code:
354: *
355: * <pre>
356: * long instant = ...
357: * long v = ...
358: * long age = getDifferenceAsLong(add(instant, v), instant);
359: * </pre>
360: *
361: * The value 'age' is the same as the value 'v'.
362: *
363: * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to
364: * subtract from
365: * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to
366: * subtract off the minuend
367: * @return the difference in the units of this field
368: */
369: public abstract long getDifferenceAsLong(long minuendInstant,
370: long subtrahendInstant);
371:
372: /**
373: * Sets a value in the milliseconds supplied.
374: * <p>
375: * The value of this field will be set.
376: * If the value is invalid, an exception if thrown.
377: * <p>
378: * If setting this field would make other fields invalid, then those fields
379: * may be changed. For example if the current date is the 31st January, and
380: * the month is set to February, the day would be invalid. Instead, the day
381: * would be changed to the closest value - the 28th/29th February as appropriate.
382: *
383: * @param instant the milliseconds from 1970-01-01T00:00:00Z to set in
384: * @param value the value to set, in the units of the field
385: * @return the updated milliseconds
386: * @throws IllegalArgumentException if the value is invalid
387: */
388: public abstract long set(long instant, int value);
389:
390: /**
391: * Sets a value using the specified partial instant.
392: * <p>
393: * The value of this field (specified by the index) will be set.
394: * If the value is invalid, an exception if thrown.
395: * <p>
396: * If setting this field would make other fields invalid, then those fields
397: * may be changed. For example if the current date is the 31st January, and
398: * the month is set to February, the day would be invalid. Instead, the day
399: * would be changed to the closest value - the 28th/29th February as appropriate.
400: *
401: * @param instant the partial instant
402: * @param fieldIndex the index of this field in the instant
403: * @param values the values of the partial instant which should be updated
404: * @param newValue the value to set, in the units of the field
405: * @return the passed in values
406: * @throws IllegalArgumentException if the value is invalid
407: */
408: public abstract int[] set(ReadablePartial instant, int fieldIndex,
409: int[] values, int newValue);
410:
411: /**
412: * Sets a value in the milliseconds supplied from a human-readable, text value.
413: * If the specified locale is null, the default locale is used.
414: * <p>
415: * If setting this field would make other fields invalid, then those fields
416: * may be changed. For example if the current date is the 31st January, and
417: * the month is set to February, the day would be invalid. Instead, the day
418: * would be changed to the closest value - the 28th/29th February as appropriate.
419: *
420: * @param instant the milliseconds from 1970-01-01T00:00:00Z to set in
421: * @param text the text value to set
422: * @param locale the locale to use for selecting a text symbol, null for default
423: * @return the updated milliseconds
424: * @throws IllegalArgumentException if the text value is invalid
425: */
426: public abstract long set(long instant, String text, Locale locale);
427:
428: /**
429: * Sets a value in the milliseconds supplied from a human-readable, text value.
430: * <p>
431: * If setting this field would make other fields invalid, then those fields
432: * may be changed. For example if the current date is the 31st January, and
433: * the month is set to February, the day would be invalid. Instead, the day
434: * would be changed to the closest value - the 28th/29th February as appropriate.
435: *
436: * @param instant the milliseconds from 1970-01-01T00:00:00Z to set in
437: * @param text the text value to set
438: * @return the updated milliseconds
439: * @throws IllegalArgumentException if the text value is invalid
440: */
441: public abstract long set(long instant, String text);
442:
443: /**
444: * Sets a value in the milliseconds supplied from a human-readable, text value.
445: * If the specified locale is null, the default locale is used.
446: * <p>
447: * If setting this field would make other fields invalid, then those fields
448: * may be changed. For example if the current date is the 31st January, and
449: * the month is set to February, the day would be invalid. Instead, the day
450: * would be changed to the closest value - the 28th/29th February as appropriate.
451: *
452: * @param instant the partial instant
453: * @param fieldIndex the index of this field in the instant
454: * @param values the values of the partial instant which should be updated
455: * @param text the text value to set
456: * @param locale the locale to use for selecting a text symbol, null for default
457: * @return the passed in values
458: * @throws IllegalArgumentException if the text value is invalid
459: */
460: public abstract int[] set(ReadablePartial instant, int fieldIndex,
461: int[] values, String text, Locale locale);
462:
463: // Extra information API
464: //------------------------------------------------------------------------
465: /**
466: * Returns the duration per unit value of this field. For example, if this
467: * field represents "hour of day", then the duration is an hour.
468: *
469: * @return the duration of this field, or UnsupportedDurationField if field
470: * has no duration
471: */
472: public abstract DurationField getDurationField();
473:
474: /**
475: * Returns the range duration of this field. For example, if this field
476: * represents "hour of day", then the range duration is a day.
477: *
478: * @return the range duration of this field, or null if field has no range
479: */
480: public abstract DurationField getRangeDurationField();
481:
482: /**
483: * Returns whether this field is 'leap' for the specified instant.
484: * <p>
485: * For example, a leap year would return true, a non leap year would return
486: * false.
487: *
488: * @param instant the instant to check for leap status
489: * @return true if the field is 'leap'
490: */
491: public abstract boolean isLeap(long instant);
492:
493: /**
494: * Gets the amount by which this field is 'leap' for the specified instant.
495: * <p>
496: * For example, a leap year would return one, a non leap year would return
497: * zero.
498: *
499: * @param instant the instant to check for leap status
500: * @return the amount, in units of the leap duration field, that the field is leap
501: */
502: public abstract int getLeapAmount(long instant);
503:
504: /**
505: * If this field were to leap, then it would be in units described by the
506: * returned duration. If this field doesn't ever leap, null is returned.
507: *
508: * @return the leap duration field if field can be leap, null if it can't
509: */
510: public abstract DurationField getLeapDurationField();
511:
512: /**
513: * Get the minimum allowable value for this field.
514: *
515: * @return the minimum valid value for this field, in the units of the
516: * field
517: */
518: public abstract int getMinimumValue();
519:
520: /**
521: * Get the minimum value for this field evaluated at the specified time.
522: *
523: * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
524: * @return the minimum value for this field, in the units of the field
525: */
526: public abstract int getMinimumValue(long instant);
527:
528: /**
529: * Get the minimum value for this field evaluated at the specified time.
530: *
531: * @param instant the partial instant to query
532: * @return the minimum value for this field, in the units of the field
533: */
534: public abstract int getMinimumValue(ReadablePartial instant);
535:
536: /**
537: * Get the minimum value for this field using the partial instant and
538: * the specified values.
539: *
540: * @param instant the partial instant to query
541: * @param values the values to use
542: * @return the minimum value for this field, in the units of the field
543: */
544: public abstract int getMinimumValue(ReadablePartial instant,
545: int[] values);
546:
547: /**
548: * Get the maximum allowable value for this field.
549: *
550: * @return the maximum valid value for this field, in the units of the
551: * field
552: */
553: public abstract int getMaximumValue();
554:
555: /**
556: * Get the maximum value for this field evaluated at the specified time.
557: *
558: * @param instant the milliseconds from 1970-01-01T00:00:00Z to query
559: * @return the maximum value for this field, in the units of the field
560: */
561: public abstract int getMaximumValue(long instant);
562:
563: /**
564: * Get the maximum value for this field evaluated at the specified time.
565: *
566: * @param instant the partial instant to query
567: * @return the maximum value for this field, in the units of the field
568: */
569: public abstract int getMaximumValue(ReadablePartial instant);
570:
571: /**
572: * Get the maximum value for this field using the partial instant and
573: * the specified values.
574: *
575: * @param instant the partial instant to query
576: * @param values the values to use
577: * @return the maximum value for this field, in the units of the field
578: */
579: public abstract int getMaximumValue(ReadablePartial instant,
580: int[] values);
581:
582: /**
583: * Get the maximum text value for this field.
584: *
585: * @param locale the locale to use for selecting a text symbol
586: * @return the maximum text length
587: */
588: public abstract int getMaximumTextLength(Locale locale);
589:
590: /**
591: * Get the maximum short text value for this field.
592: *
593: * @param locale the locale to use for selecting a text symbol
594: * @return the maximum short text length
595: */
596: public abstract int getMaximumShortTextLength(Locale locale);
597:
598: // Calculation API
599: //------------------------------------------------------------------------
600: /**
601: * Round to the lowest whole unit of this field. After rounding, the value
602: * of this field and all fields of a higher magnitude are retained. The
603: * fractional millis that cannot be expressed in whole increments of this
604: * field are set to minimum.
605: * <p>
606: * For example, a datetime of 2002-11-02T23:34:56.789, rounded to the
607: * lowest whole hour is 2002-11-02T23:00:00.000.
608: *
609: * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
610: * @return rounded milliseconds
611: */
612: public abstract long roundFloor(long instant);
613:
614: /**
615: * Round to the highest whole unit of this field. The value of this field
616: * and all fields of a higher magnitude may be incremented in order to
617: * achieve this result. The fractional millis that cannot be expressed in
618: * whole increments of this field are set to minimum.
619: * <p>
620: * For example, a datetime of 2002-11-02T23:34:56.789, rounded to the
621: * highest whole hour is 2002-11-03T00:00:00.000.
622: *
623: * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
624: * @return rounded milliseconds
625: */
626: public abstract long roundCeiling(long instant);
627:
628: /**
629: * Round to the nearest whole unit of this field. If the given millisecond
630: * value is closer to the floor or is exactly halfway, this function
631: * behaves like roundFloor. If the millisecond value is closer to the
632: * ceiling, this function behaves like roundCeiling.
633: *
634: * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
635: * @return rounded milliseconds
636: */
637: public abstract long roundHalfFloor(long instant);
638:
639: /**
640: * Round to the nearest whole unit of this field. If the given millisecond
641: * value is closer to the floor, this function behaves like roundFloor. If
642: * the millisecond value is closer to the ceiling or is exactly halfway,
643: * this function behaves like roundCeiling.
644: *
645: * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
646: * @return rounded milliseconds
647: */
648: public abstract long roundHalfCeiling(long instant);
649:
650: /**
651: * Round to the nearest whole unit of this field. If the given millisecond
652: * value is closer to the floor, this function behaves like roundFloor. If
653: * the millisecond value is closer to the ceiling, this function behaves
654: * like roundCeiling.
655: * <p>
656: * If the millisecond value is exactly halfway between the floor and
657: * ceiling, the ceiling is chosen over the floor only if it makes this
658: * field's value even.
659: *
660: * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
661: * @return rounded milliseconds
662: */
663: public abstract long roundHalfEven(long instant);
664:
665: /**
666: * Returns the fractional duration milliseconds of this field. In other
667: * words, calling remainder returns the duration that roundFloor would
668: * subtract.
669: * <p>
670: * For example, on a datetime of 2002-11-02T23:34:56.789, the remainder by
671: * hour is 34 minutes and 56.789 seconds.
672: *
673: * @param instant the milliseconds from 1970-01-01T00:00:00Z to get the
674: * remainder
675: * @return remainder duration, in milliseconds
676: */
677: public abstract long remainder(long instant);
678:
679: /**
680: * Get a suitable debug string.
681: *
682: * @return debug string
683: */
684: public abstract String toString();
685:
686: }
|