EMMA Coverage Report (generated Thu Jan 24 13:37:04 CST 2013)
[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)93%  (282/302)98%  (39/40)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class RangeArrayPropertyEditor100% (1/1)100% (6/6)93%  (259/279)97%  (38/39)
setAsText (String): void 100% (1/1)81%  (87/107)93%  (14/15)
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% (76/76)100% (10/10)
verifyRanges (Range []): void 100% (1/1)100% (54/54)100% (3/3)
     
class RangeArrayPropertyEditor$1100% (1/1)100% (2/2)100% (23/23)100% (2/2)
RangeArrayPropertyEditor$1 (RangeArrayPropertyEditor, Range []): void 100% (1/1)100% (9/9)100% (1/1)
compare (Integer, Integer): int 100% (1/1)100% (14/14)100% (1/1)

1/*
2 * Copyright 2006-2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17package org.springframework.batch.item.file.transform;
18 
19import java.beans.PropertyEditorSupport;
20import java.util.Arrays;
21import java.util.Comparator;
22 
23import org.springframework.util.Assert;
24import org.springframework.util.StringUtils;
25 
26/**
27 * Property editor implementation which parses string and creates array of
28 * ranges. Ranges can be provided in any order. </br> Input string should be
29 * provided in following format: 'range1, range2, range3,...' where range is
30 * specified as:
31 * <ul>
32 * <li>'X-Y', where X is minimum value and Y is maximum value (condition X<=Y
33 * is verified)</li>
34 * <li>or 'Z', where Z is minimum and maximum is calculated as (minimum of
35 * adjacent range - 1). Maximum of the last range is never calculated. Range
36 * stays unbound at maximum side if maximum value is not provided.</li>
37 * </ul>
38 * Minimum and maximum values can be from interval &lt;1, Integer.MAX_VALUE-1&gt;
39 * <p>
40 * Examples:</br> 
41 * '1, 15, 25, 38, 55-60' is equal to '1-14, 15-24, 25-37, 38-54, 55-60' </br> 
42 * '36, 14, 1-10, 15, 49-57' is equal to '36-48, 14-14, 1-10, 15-35, 49-57'
43 * <p>
44 * Property editor also allows to validate whether ranges are disjoint. Validation
45 * can be turned on/off by using {@link #setForceDisjointRanges(boolean)}. By default 
46 * validation is turned off.
47 * 
48 * @author peter.zozom
49 */
50public class RangeArrayPropertyEditor extends PropertyEditorSupport {
51        
52        private boolean forceDisjointRanges = false;
53        
54        /**
55         * Set force disjoint ranges. If set to TRUE, ranges are validated to be disjoint.
56         * For example: defining ranges '1-10, 5-15' will cause IllegalArgumentException in
57         * case of forceDisjointRanges=TRUE.  
58         * @param forceDisjointRanges 
59         */
60        public void setForceDisjointRanges(boolean forceDisjointRanges) {
61                this.forceDisjointRanges = forceDisjointRanges;
62        }
63 
64        public void setAsText(String text) throws IllegalArgumentException {
65                
66                //split text into ranges
67                String[] strRanges = text.split(",");
68                Range[] ranges = new Range[strRanges.length];
69                
70                //parse ranges and create array of Range objects 
71                for (int i = 0; i < strRanges.length; i++) {                        
72                        String[] range = strRanges[i].split("-");
73                
74                        int min;
75                        int max;
76                        
77                        if ((range.length == 1) && (StringUtils.hasText(range[0]))) {
78                                min = Integer.parseInt(range[0].trim());
79                                // correct max value will be assigned later
80                                ranges[i] = new Range(min);
81                        } else if ((range.length == 2) && (StringUtils.hasText(range[0]))
82                                        && (StringUtils.hasText(range[1]))) {
83                                min = Integer.parseInt(range[0].trim());
84                                max = Integer.parseInt(range[1].trim());
85                                ranges[i] = new Range(min,max);
86                        } else {
87                                throw new IllegalArgumentException("Range[" + i + "]: range (" + strRanges[i] + ") is invalid");
88                        }                        
89                        
90                }
91        
92                setMaxValues(ranges);
93                setValue(ranges);
94        }
95        
96        public String getAsText() {
97                Range[] ranges = (Range[])getValue();
98                
99                StringBuffer sb = new StringBuffer();
100 
101                for (int i = 0; i < ranges.length; i++) {
102                        if(i>0) {
103                                sb.append(", ");
104                        }
105                        sb.append(ranges[i]);
106                }
107                return sb.toString();
108        }
109        
110        private void setMaxValues(final Range[] ranges) {
111                
112                // Array of integers to track range values by index
113                Integer[] c = new Integer[ranges.length];
114                for (int i=0; i<c.length; i++) {
115                        c[i] = i;
116                }
117                
118                //sort array of Ranges
119                Arrays.sort(c, new Comparator<Integer>() {
120                                public int compare(Integer r1, Integer r2) {
121                                        return ranges[r1].getMin()-ranges[r2].getMin();
122                                }                                                                
123                        }
124                );
125                
126                //set max values for all unbound ranges (except last range)
127                for (int i = 0; i < c.length - 1; i++) {
128                        if (!ranges[c[i]].hasMaxValue()) {
129                                //set max value to (min value - 1) of the next range
130                                ranges[c[i]] = new Range(ranges[c[i]].getMin(),ranges[c[i+1]].getMin() - 1);
131                        }
132                }
133                
134                if (forceDisjointRanges) {
135                        verifyRanges(ranges);
136                }
137        }
138        
139        
140        private void verifyRanges(Range[] ranges) {
141                //verify that ranges are disjoint                
142                for(int i = 1; i < ranges.length;i++) {
143                        Assert.isTrue(ranges[i-1].getMax() < ranges[i].getMin(),
144                                        "Ranges must be disjoint. Range[" + (i-1) + "]: (" + ranges[i-1] + 
145                                        ") Range[" + i +"]: (" + ranges[i] + ")");
146                }
147        }
148}

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