EMMA Coverage Report (generated Tue May 06 07:28:24 PDT 2008)
[all classes][org.springframework.batch.item.file.transform]

COVERAGE SUMMARY FOR SOURCE FILE [RangeArrayPropertyEditor.java]

nameclass, %method, %block, %line, %
RangeArrayPropertyEditor.java100% (2/2)100% (8/8)92%  (246/266)98%  (41/42)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class RangeArrayPropertyEditor100% (1/1)100% (6/6)92%  (228/248)97%  (37/38)
setAsText (String): void 100% (1/1)81%  (87/107)94%  (15/16)
RangeArrayPropertyEditor (): void 100% (1/1)100% (6/6)100% (2/2)
getAsText (): String 100% (1/1)100% (32/32)100% (7/7)
setForceDisjointRanges (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setMaxValues (Range []): void 100% (1/1)100% (45/45)100% (8/8)
verifyRanges (Range []): void 100% (1/1)100% (54/54)100% (3/3)
     
class RangeArrayPropertyEditor$1100% (1/1)100% (2/2)100% (18/18)100% (4/4)
RangeArrayPropertyEditor$1 (RangeArrayPropertyEditor): void 100% (1/1)100% (6/6)100% (1/1)
compare (Object, Object): int 100% (1/1)100% (12/12)100% (3/3)

1package org.springframework.batch.item.file.transform;
2 
3import java.beans.PropertyEditorSupport;
4import java.util.Arrays;
5import java.util.Comparator;
6 
7import org.springframework.util.Assert;
8import org.springframework.util.StringUtils;
9 
10/**
11 * Property editor implementation which parses string and creates array of
12 * ranges. Ranges can be provided in any order. </br> Input string should be
13 * provided in following format: 'range1, range2, range3,...' where range is
14 * specified as:
15 * <ul>
16 * <li>'X-Y', where X is minimum value and Y is maximum value (condition X<=Y
17 * is verified)</li>
18 * <li>or 'Z', where Z is minimum and maximum is calculated as (minimum of
19 * adjacent range - 1). Maximum of the last range is never calculated. Range
20 * stays unbound at maximum side if maximum value is not provided.</li>
21 * </ul>
22 * Minimum and maximum values can be from interval &lt;1, Integer.MAX_VALUE-1&gt;
23 * <p>
24 * Examples:</br> 
25 * '1, 15, 25, 38, 55-60' is equal to '1-14, 15-24, 25-37, 38-54, 55-60' </br> 
26 * '36, 14, 1-10, 15, 49-57' is equal to '36-48, 14-14, 1-10, 15-35, 49-57'
27 * <p>
28 * Property editor also allows to validate whether ranges are disjoint. Validation
29 * can be turned on/off by using {@link #setForceDisjointRanges(boolean)}. By default 
30 * validation is turned off.
31 * 
32 * @author peter.zozom
33 */
34public class RangeArrayPropertyEditor extends PropertyEditorSupport {
35        
36        private boolean forceDisjointRanges = false;
37        
38        /**
39         * Set force disjoint ranges. If set to TRUE, ranges are validated to be disjoint.
40         * For example: defining ranges '1-10, 5-15' will cause IllegalArgumentException in
41         * case of forceDisjointRanges=TRUE.  
42         * @param forceDisjointRanges 
43         */
44        public void setForceDisjointRanges(boolean forceDisjointRanges) {
45                this.forceDisjointRanges = forceDisjointRanges;
46        }
47 
48        public void setAsText(String text) throws IllegalArgumentException {
49                
50                //split text into ranges
51                String[] strRanges = text.split(",");
52                Range[] ranges = new Range[strRanges.length];
53                
54                //parse ranges and create array of Range objects 
55                for (int i = 0; i < strRanges.length; i++) {                        
56                        String[] range = strRanges[i].split("-");
57                
58                        int min;
59                        int max;
60                        
61                        if ((range.length == 1) && (StringUtils.hasText(range[0]))) {
62                                min = Integer.parseInt(range[0].trim());
63                                // correct max value will be assigned later
64                                ranges[i] = new Range(min);
65                        } else if ((range.length == 2) && (StringUtils.hasText(range[0]))
66                                        && (StringUtils.hasText(range[1]))) {
67                                min = Integer.parseInt(range[0].trim());
68                                max = Integer.parseInt(range[1].trim());
69                                ranges[i] = new Range(min,max);
70                        } else {
71                                throw new IllegalArgumentException("Range[" + i + "]: range (" + strRanges[i] + ") is invalid");
72                        }                        
73                        
74                }
75        
76                setMaxValues(ranges);
77                setValue(ranges);
78        }
79        
80        public String getAsText() {
81                Range[] ranges = (Range[])getValue();
82                
83                StringBuffer sb = new StringBuffer();
84 
85                for (int i = 0; i < ranges.length; i++) {
86                        if(i>0) {
87                                sb.append(", ");
88                        }
89                        sb.append(ranges[i]);
90                }
91                return sb.toString();
92        }
93        
94        private void setMaxValues(Range[] ranges) {
95                
96                //clone array, original array should stay same
97                Range[] c = (Range[])ranges.clone();
98                
99                //sort array of Ranges
100                Arrays.sort(c, new Comparator() {
101                                public int compare(Object o1, Object o2) {
102                                        Range c1 = (Range)o1;
103                                        Range c2 = (Range)o2;
104                                        return c1.getMin()-c2.getMin();
105                                }                                                                
106                        }
107                );
108 
109                //set max values for all unbound ranges (except last range)
110                for (int i = 0; i < c.length - 1; i++) {
111                        if (!c[i].hasMaxValue()) {
112                                //set max value to (min value - 1) of the next range
113                                c[i].setMax(c[i+1].getMin() - 1);
114                        }
115                }
116                
117                if (forceDisjointRanges) {
118                        verifyRanges(c);
119                }
120        }
121        
122        
123        private void verifyRanges(Range[] ranges) {
124                //verify that ranges are disjoint                
125                for(int i = 1; i < ranges.length;i++) {
126                        Assert.isTrue(ranges[i-1].getMax() < ranges[i].getMin(),
127                                        "Ranges must be disjoint. Range[" + (i-1) + "]: (" + ranges[i-1] + 
128                                        ") Range[" + i +"]: (" + ranges[i] + ")");
129                }
130        }
131}

[all classes][org.springframework.batch.item.file.transform]
EMMA 2.0.5312 (C) Vladimir Roubtsov