    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jfreechart/index.html
    008     *
    009     * This library is free software; you can redistribute it and/or modify it
    010     * under the terms of the GNU Lesser General Public License as published by
    011     * the Free Software Foundation; either version 2.1 of the License, or
    012     * (at your option) any later version.
    013     *
    014     * This library is distributed in the hope that it will be useful, but
    015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017     * License for more details.
    018     *
    019     * You should have received a copy of the GNU Lesser General Public
    020     * License along with this library; if not, write to the Free Software
    021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022     * USA.
    023     *
    024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    025     * in the United States and other countries.]
    026     *
    027     * -------------------------
    028     * OHLCSeriesCollection.java
    029     * -------------------------
    030     * (C) Copyright 2006, 2007, by Object Refinery Limited.
    031     *
    032     * Original Author:  David Gilbert (for Object Refinery Limited);
    033     * Contributor(s):   -;
    034     *
    035     * Changes
    036     * -------
    037     * 04-Dec-2006 : Version 1 (DG);
    038     *
    039     */
    040
    041    package org.jfree.data.time.ohlc;
    042
    043    import java.io.Serializable;
    044    import java.util.List;
    045
    046    import org.jfree.data.general.DatasetChangeEvent;
    047    import org.jfree.data.time.RegularTimePeriod;
    048    import org.jfree.data.time.TimePeriodAnchor;
    049    import org.jfree.data.xy.AbstractXYDataset;
    050    import org.jfree.data.xy.OHLCDataset;
    051    import org.jfree.util.ObjectUtilities;
    052
    053    /**
    054     * A collection of {@link OHLCSeries} objects.
    055     *
    056     * @since 1.0.4
    057     *
    058     * @see OHLCSeries
    059     */
    060    public class OHLCSeriesCollection extends AbstractXYDataset
    061                                    implements OHLCDataset, Serializable {
    062
    063        /** Storage for the data series. */
    064        private List data;
    065
    066        private TimePeriodAnchor xPosition = TimePeriodAnchor.MIDDLE;
    067
    068        /**
    069         * Creates a new instance of <code>OHLCSeriesCollection</code>.
    070         */
    071        public OHLCSeriesCollection() {
    072            this.data = new java.util.ArrayList();
    073        }
    074
    075        /**
    076         * Adds a series to the collection and sends a {@link DatasetChangeEvent}
    077         * to all registered listeners.
    078         *
    079         * @param series  the series (<code>null</code> not permitted).
    080         */
    081        public void addSeries(OHLCSeries series) {
    082            if (series == null) {
    083                throw new IllegalArgumentException("Null 'series' argument.");
    084            }
    085            this.data.add(series);
    086            series.addChangeListener(this);
    087            fireDatasetChanged();
    088        }
    089
    090        /**
    091         * Returns the number of series in the collection.
    092         *
    093         * @return The series count.
    094         */
    095        public int getSeriesCount() {
    096            return this.data.size();
    097        }
    098
    099        /**
    100         * Returns a series from the collection.
    101         *
    102         * @param series  the series index (zero-based).
    103         *
    104         * @return The series.
    105         *
    106         * @throws IllegalArgumentException if <code>series</code> is not in the
    107         *     range <code>0</code> to <code>getSeriesCount() - 1</code>.
    108         */
    109        public OHLCSeries getSeries(int series) {
    110            if ((series < 0) || (series >= getSeriesCount())) {
    111                throw new IllegalArgumentException("Series index out of bounds");
    112            }
    113            return (OHLCSeries) this.data.get(series);
    114        }
    115
    116        /**
    117         * Returns the key for a series.
    118         *
    119         * @param series  the series index (in the range <code>0</code> to
    120         *     <code>getSeriesCount() - 1</code>).
    121         *
    122         * @return The key for a series.
    123         *
    124         * @throws IllegalArgumentException if <code>series</code> is not in the
    125         *     specified range.
    126         */
    127        public Comparable getSeriesKey(int series) {
    128            // defer argument checking
    129            return getSeries(series).getKey();
    130        }
    131
    132        /**
    133         * Returns the number of items in the specified series.
    134         *
    135         * @param series  the series (zero-based index).
    136         *
    137         * @return The item count.
    138         *
    139         * @throws IllegalArgumentException if <code>series</code> is not in the
    140         *     range <code>0</code> to <code>getSeriesCount() - 1</code>.
    141         */
    142        public int getItemCount(int series) {
    143            // defer argument checking
    144            return getSeries(series).getItemCount();
    145        }
    146
    147        /**
    148         * Returns the x-value for a time period.
    149         *
    150         * @param period  the time period (<code>null</code> not permitted).
    151         *
    152         * @return The x-value.
    153         */
    154        protected synchronized long getX(RegularTimePeriod period) {
    155            long result = 0L;
    156            if (this.xPosition == TimePeriodAnchor.START) {
    157                result = period.getFirstMillisecond();
    158            }
    159            else if (this.xPosition == TimePeriodAnchor.MIDDLE) {
    160                result = period.getMiddleMillisecond();
    161            }
    162            else if (this.xPosition == TimePeriodAnchor.END) {
    163                result = period.getLastMillisecond();
    164            }
    165            return result;
    166        }
    167
    168        /**
    169         * Returns the x-value for an item within a series.
    170         *
    171         * @param series  the series index.
    172         * @param item  the item index.
    173         *
    174         * @return The x-value.
    175         */
    176        public double getXValue(int series, int item) {
    177            OHLCSeries s = (OHLCSeries) this.data.get(series);
    178            OHLCItem di = (OHLCItem) s.getDataItem(item);
    179            RegularTimePeriod period = di.getPeriod();
    180            return getX(period);
    181        }
    182
    183        /**
    184         * Returns the x-value for an item within a series.
    185         *
    186         * @param series  the series index.
    187         * @param item  the item index.
    188         *
    189         * @return The x-value.
    190         */
    191        public Number getX(int series, int item) {
    192            return new Double(getXValue(series, item));
    193        }
    194
    195        /**
    196         * Returns the y-value for an item within a series.
    197         *
    198         * @param series  the series index.
    199         * @param item  the item index.
    200         *
    201         * @return The y-value.
    202         */
    203        public Number getY(int series, int item) {
    204            OHLCSeries s = (OHLCSeries) this.data.get(series);
    205            OHLCItem di = (OHLCItem) s.getDataItem(item);
    206            return new Double(di.getYValue());
    207        }
    208
    209        /**
    210         * Returns the open-value for an item within a series.
    211         *
    212         * @param series  the series index.
    213         * @param item  the item index.
    214         *
    215         * @return The open-value.
    216         */
    217        public double getOpenValue(int series, int item) {
    218            OHLCSeries s = (OHLCSeries) this.data.get(series);
    219            OHLCItem di = (OHLCItem) s.getDataItem(item);
    220            return di.getOpenValue();
    221        }
    222
    223        /**
    224         * Returns the open-value for an item within a series.
    225         *
    226         * @param series  the series index.
    227         * @param item  the item index.
    228         *
    229         * @return The open-value.
    230         */
    231        public Number getOpen(int series, int item) {
    232            return new Double(getOpenValue(series, item));
    233        }
    234
    235        /**
    236         * Returns the close-value for an item within a series.
    237         *
    238         * @param series  the series index.
    239         * @param item  the item index.
    240         *
    241         * @return The close-value.
    242         */
    243        public double getCloseValue(int series, int item) {
    244            OHLCSeries s = (OHLCSeries) this.data.get(series);
    245            OHLCItem di = (OHLCItem) s.getDataItem(item);
    246            return di.getCloseValue();
    247        }
    248
    249        /**
    250         * Returns the close-value for an item within a series.
    251         *
    252         * @param series  the series index.
    253         * @param item  the item index.
    254         *
    255         * @return The close-value.
    256         */
    257        public Number getClose(int series, int item) {
    258            return new Double(getCloseValue(series, item));
    259        }
    260
    261        /**
    262         * Returns the high-value for an item within a series.
    263         *
    264         * @param series  the series index.
    265         * @param item  the item index.
    266         *
    267         * @return The high-value.
    268         */
    269        public double getHighValue(int series, int item) {
    270            OHLCSeries s = (OHLCSeries) this.data.get(series);
    271            OHLCItem di = (OHLCItem) s.getDataItem(item);
    272            return di.getHighValue();
    273        }
    274
    275        /**
    276         * Returns the high-value for an item within a series.
    277         *
    278         * @param series  the series index.
    279         * @param item  the item index.
    280         *
    281         * @return The high-value.
    282         */
    283        public Number getHigh(int series, int item) {
    284            return new Double(getHighValue(series, item));
    285        }
    286
    287        /**
    288         * Returns the low-value for an item within a series.
    289         *
    290         * @param series  the series index.
    291         * @param item  the item index.
    292         *
    293         * @return The low-value.
    294         */
    295        public double getLowValue(int series, int item) {
    296            OHLCSeries s = (OHLCSeries) this.data.get(series);
    297            OHLCItem di = (OHLCItem) s.getDataItem(item);
    298            return di.getLowValue();
    299        }
    300
    301        /**
    302         * Returns the low-value for an item within a series.
    303         *
    304         * @param series  the series index.
    305         * @param item  the item index.
    306         *
    307         * @return The low-value.
    308         */
    309        public Number getLow(int series, int item) {
    310            return new Double(getLowValue(series, item));
    311        }
    312
    313        public Number getVolume(int series, int item) {
    314            return null;
    315        }
    316
    317        public double getVolumeValue(int series, int item) {
    318            return Double.NaN;
    319        }
    320
    321        /**
    322         * Tests this instance for equality with an arbitrary object.
    323         *
    324         * @param obj  the object (<code>null</code> permitted).
    325         *
    326         * @return A boolean.
    327         */
    328        public boolean equals(Object obj) {
    329            if (obj == this) {
    330                return true;
    331            }
    332            if (!(obj instanceof OHLCSeriesCollection)) {
    333                return false;
    334            }
    335            OHLCSeriesCollection that = (OHLCSeriesCollection) obj;
    336            return ObjectUtilities.equal(this.data, that.data);
    337        }
    338
    339        /**
    340         * Returns a clone of this instance.
    341         *
    342         * @return A clone.
    343         *
    344         * @throws CloneNotSupportedException if there is a problem.
    345         */
    346        public Object clone() throws CloneNotSupportedException {
    347            OHLCSeriesCollection clone
    348                    = (OHLCSeriesCollection) super.clone();
    349            clone.data = (List) ObjectUtilities.deepClone(this.data);
    350            return clone;
    351        }
    352
    353    }