/* * Copyright (c) 2013. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 or * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. */ package uk.me.parabola.mkgmap.osmstyle.actions; import java.util.regex.Pattern; import uk.me.parabola.mkgmap.reader.osm.Element; import uk.me.parabola.mkgmap.scan.SyntaxException; /** * Split a value in parts and returns one or more part(s) of a value. * value is split at a separator that defaults to semicolon ';' * by default the first part is returned * * if the optional second parameter 'partnumber' is out of * range then null is returned * * if the optional second parameter is negative * the part returned is counted from the end of the split * * if the the split operator is a > or < and the * the correspondent number of parts are returned * * Example: if the value is "Aa#Bb#Cc#Dd#Ee" * part:#:1 returns Aa * part:#:-1 returns Ee * part:#:2 returns Bb * part:#:-2 returns Dd * part:#>1 returns Bb#Cc#Dd#Ee# * part:#<5 returns Aa#Bb#Cc#Dd# * part:#<-1 returns Aa#Bb#Cc#Dd# * * @author Franco Bez * @author Enrico Liboni */ public class PartFilter extends ValueFilter { private String separator; private int partnumber; private boolean isLt=false; // less than < private boolean isGt=false; // great than > public PartFilter(String arg) { String[] temp; // detect which operator is used if (arg.contains(":")) { temp = arg.split(":"); } else if (arg.contains(">")) { temp = arg.split(">"); isGt = true; } else if (arg.contains("<")) { temp = arg.split("<"); isLt = true; } else { // no operators default to arg temp = new String[] { arg }; } partnumber = 1; try { // set the part number (default is 1) if( temp.length > 1 ) { partnumber = Integer.parseInt(temp[1]); } // set the separator (default to ;) if(temp[0].length() > 0 ){ separator = temp[0]; } else{ separator = ";"; } } catch (NumberFormatException e) { throw new SyntaxException("Not valid numbers in style part command: " + arg); } if (partnumber == 0) throw new SyntaxException("Not valid numbers in style part command: " + arg); } public String doFilter(String value, Element el) { if (value == null || partnumber == 0) return null; // split uses a regex we need to replace special characters String[] temp = value.split(Pattern.quote(separator)); // check if partnumber is in range, if not return null if (temp.length < Math.abs(partnumber) ) return null; // get the index of the partnumber // if the partnumber is negative the part is counted from the end of the split int idx=(partnumber > 0)?(partnumber-1):(temp.length+partnumber); // default operator ":": return the part if ( !isLt && !isGt ) { return temp[idx].trim(); } else { StringBuffer returnValue= new StringBuffer(); // operator "<": collate all the parts before the partnumber if ( isLt ) { for (int i=0;i<idx;i++) { returnValue.append(temp[i]).append(separator); } } // operator ">": collate all the parts after the partnumber if ( isGt ) { for (int i=idx+1;i<temp.length;i++) { returnValue.append(temp[i]).append(separator); } } // return the result return returnValue.toString(); } } }