001package org.unix4j.convert; 002 003import org.unix4j.util.Range; 004 005import java.util.ArrayList; 006import java.util.List; 007 008public class RangeConverters { 009 public static final ValueConverter<Range> STRING = new ValueConverter<Range>() { 010 @Override 011 public Range convert(Object value) throws IllegalArgumentException { 012 if (value != null) { 013 final String[] values = value.toString().split("\\s*,\\s*"); 014 final List<Integer> indices = new ArrayList<Integer>(); 015 for (final String s : values) { 016 final int dashIndex = s.indexOf('-'); 017 try { 018 if (dashIndex < 0) { 019 indices.add(Integer.parseInt(s)); 020 } else { 021 if (dashIndex == 0) { 022 //e.g.: -4 023 indices.add(Integer.parseInt(s)); 024 } else if (dashIndex == s.length() - 1) { 025 //e.g.: 4- 026 indices.add(Integer.parseInt(s.substring(0, dashIndex))); 027 indices.add(-Integer.MAX_VALUE);//FIXME not very nice, but works 028 } else { 029 //e.g. 4-8 030 indices.add(Integer.parseInt(s.substring(0, dashIndex))); 031 indices.add(Integer.parseInt(s.substring(dashIndex)));//include minus 032 } 033 } 034 } catch (Exception e) { 035 //we cannot parse range value, return null 036 return null; 037 } 038 } 039 if (!indices.isEmpty()) { 040 return toRange(value, indices); 041 } 042 } 043 return null; 044 } 045 private Range toRange(final Object value, final List<Integer> indices) { 046 int lastIndex = 0; 047 Range range = null; 048 for (final int index : indices) { 049 if (index == 0) { 050 throw new IllegalArgumentException("invalid index 0 in range expression: " + value); 051 } 052 if (index > 0) { 053 if (lastIndex > 0) { 054 range = range == null ? Range.of(lastIndex) : range.andOf(lastIndex); 055 } 056 lastIndex = index; 057 } else { 058 final int start = lastIndex == 0 ? 1 : lastIndex; 059 range = range == null ? Range.between(start, -index) : range.andBetween(start, -index); 060 lastIndex = -1; 061 } 062 } 063 if (lastIndex > 0) { 064 return range == null ? Range.of(lastIndex) : range.andOf(lastIndex); 065 } 066 return range; 067 } 068 069 }; 070 public static final ValueConverter<Range> DEFAULT = STRING; 071}