Rev 3383 |
View as "text/plain" |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* 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 {
StringBuilder returnValue=
new StringBuilder();
// 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();
}
}
}