Coverage Report - com.sun.javafx.runtime.sequence.BoundSequenceSlice
 
Classes in this File Line Coverage Branch Coverage Complexity
BoundSequenceSlice
96%
27/28
100%
18/18
0
BoundSequenceSlice$1
100%
5/5
100%
2/2
0
BoundSequenceSlice$2
100%
9/9
67%
8/12
0
BoundSequenceSlice$3
100%
11/11
67%
8/12
0
 
 1  
 /*
 2  
  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
 3  
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 4  
  *
 5  
  * This code is free software; you can redistribute it and/or modify it
 6  
  * under the terms of the GNU General Public License version 2 only, as
 7  
  * published by the Free Software Foundation.  Sun designates this
 8  
  * particular file as subject to the "Classpath" exception as provided
 9  
  * by Sun in the LICENSE file that accompanied this code.
 10  
  *
 11  
  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  
  * version 2 for more details (a copy is included in the LICENSE file that
 15  
  * accompanied this code).
 16  
  *
 17  
  * You should have received a copy of the GNU General Public License version
 18  
  * 2 along with this work; if not, write to the Free Software Foundation,
 19  
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  
  *
 21  
  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 22  
  * CA 95054 USA or visit www.sun.com if you need additional information or
 23  
  * have any questions.
 24  
  */
 25  
 
 26  
 package com.sun.javafx.runtime.sequence;
 27  
 
 28  
 import com.sun.javafx.runtime.location.IntLocation;
 29  
 import com.sun.javafx.runtime.location.SequenceLocation;
 30  
 import com.sun.javafx.runtime.location.SequenceChangeListener;
 31  
 import com.sun.javafx.runtime.location.IntChangeListener;
 32  
 
 33  
 /**
 34  
  * BoundSequenceSlice
 35  
  *
 36  
  * @author Brian Goetz
 37  
  * @author Zhiqun Chen
 38  
  */
 39  271
 class BoundSequenceSlice<T> extends AbstractBoundSequence<T> implements SequenceLocation<T> {
 40  
     private final SequenceLocation<T> sequenceLoc;
 41  
     private final IntLocation lowerLoc;
 42  
     private final IntLocation upperLoc;
 43  
     private final boolean isExclusive;
 44  
     private int lower, upper;
 45  
     private int size;
 46  
 
 47  
     BoundSequenceSlice(Class<T> clazz, SequenceLocation<T> sequenceLoc, IntLocation lowerLoc, IntLocation upperLoc, boolean isExclusive) {
 48  8
         super(clazz);
 49  8
         this.sequenceLoc = sequenceLoc;
 50  8
         this.lowerLoc = lowerLoc;
 51  8
         this.upperLoc = upperLoc;
 52  8
         this.isExclusive = isExclusive;
 53  8
         setInitialValue(computeValue());
 54  8
         addTriggers();
 55  8
     }
 56  
 
 57  
     private Sequence<T> computeValue() {
 58  8
         computeBounds(true, true);
 59  8
         return sequenceLoc.get().getSlice(lower, upper);
 60  
     }
 61  
     
 62  
     /**
 63  
      * adjust for exclusive upper bound
 64  
      */
 65  
     private int adjusted(int upperValue) {
 66  48
         return (isExclusive ? -1 : 0) + upperValue;
 67  
     }
 68  
 
 69  
     private void computeBounds(boolean updateLower, boolean updateUpper) {
 70  54
         int seqSize = sequenceLoc.getAsSequence().size();
 71  
         
 72  54
         if (updateLower) {
 73  42
             lower = lowerLoc.get();
 74  
         }
 75  54
         if (updateUpper) {
 76  44
             upper = adjusted(upperLoc == null ? seqSize-1 : upperLoc.get());
 77  
         }
 78  
         
 79  54
         if (seqSize == 0) {
 80  1
             size = 0;
 81  
         } else {
 82  53
             int range = ((upper >= seqSize)? seqSize-1:upper) - ((lower<0)? 0: lower);
 83  53
             size = (range >= 0) ? range + 1 : 0;
 84  
         }
 85  54
     }
 86  
 
 87  
     protected Sequence<T> computeFull(int lower, int upper) {
 88  0
         return sequenceLoc.getSlice(lower, upper);
 89  
     }
 90  
                     
 91  
     private void addTriggers() {
 92  8
         sequenceLoc.addChangeListener(new SequenceChangeListener<T>() {
 93  
 
 94  
             public void onChange(int startPos, int endPos, Sequence newElements, Sequence oldValue, Sequence newValue) {
 95  24
                 computeBounds(true, true);
 96  
 
 97  24
                 Sequence<T> newSeq = newValue.getSlice(lower, upper);
 98  24
                 updateSlice(0, size == 0 ? 0 : size - 1, newSeq, newSeq);
 99  24
             }
 100  
         });
 101  11
         lowerLoc.addChangeListener(new IntChangeListener() {
 102  
 
 103  
             public void onChange(int oldValue, int newValue) {
 104  10
                 assert oldValue != newValue;
 105  10
                 int oldSize = size;
 106  10
                 computeBounds(true, false);
 107  
 
 108  10
                 if (sequenceLoc.getAsSequence().size() > 0 && size != oldSize) {
 109  9
                     if (size > oldSize) {
 110  3
                         updateSlice(
 111  
                                 0, 
 112  
                                 -1, 
 113  
                                 sequenceLoc.getSlice(newValue, (oldSize == 0) ? upper : (oldValue - 1)));
 114  
                     } else {
 115  6
                         updateSlice(
 116  
                                 0, 
 117  
                                 oldSize - size - 1, 
 118  
                                 Sequences.emptySequence(sequenceLoc.getAsSequence().getElementType()));
 119  
                     }
 120  
                 }
 121  10
             }
 122  
         });
 123  8
         if (upperLoc != null) {
 124  6
             upperLoc.addChangeListener(new IntChangeListener() {
 125  
 
 126  
                 public void onChange(int oldValue, int newValue) {
 127  12
                     assert oldValue != newValue;
 128  12
                     int oldSize = size;
 129  12
                     computeBounds(false, true);
 130  
 
 131  12
                     if (sequenceLoc.getAsSequence().size() > 0 && size != oldSize) {
 132  10
                         if (size > oldSize) {
 133  4
                             int oldUpper = adjusted(oldValue);
 134  4
                             updateSlice(
 135  
                                     oldSize, 
 136  
                                     oldSize - 1, 
 137  
                                     sequenceLoc.getSlice((oldUpper >= lower) ? oldUpper + 1 : lower, upper));
 138  4
                         } else {
 139  6
                             updateSlice(
 140  
                                     size, 
 141  
                                     oldSize - 1, 
 142  
                                     Sequences.emptySequence(sequenceLoc.getAsSequence().getElementType()));
 143  
                         }
 144  
                     }
 145  12
                 }
 146  
             });
 147  
         }
 148  8
     }
 149  
 }