/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.util; import java.io.File; import java.io.FileReader; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import xxl.core.functions.AbstractFunction; import xxl.core.functions.Function; import xxl.core.predicates.AbstractPredicate; import xxl.core.predicates.Predicate; /** * This class provides some useful methods for dealing with Strings and parsing Strings. */ public class Strings{ /** * The default constructor has private access in order to ensure * non-instantiability. */ private Strings(){} /** * Returns a Predicate which returns true iff the object matches the * String which is given. * @param matcher Regular expression. * @see java.lang.String#matches(String) * @return The Predicate. */ public static Predicate<String> getStringMatchingPredicate(final String matcher) { return new AbstractPredicate<String>() { @Override public boolean invoke(String o) { return o.matches(matcher); } }; } /** * Returns a Predicate which returns true iff the object is inside * the array. The internal implementation puts the array into a * HashSet for better performance. * @param array The Objects. * @return The Predicate. */ public static Predicate<Object> getIsInArrayPredicate(Object[] array) { final Set<Object> set = new HashSet<Object>(); for (int i=0; i<array.length; i++) set.add(array[i]); return new AbstractPredicate<Object>() { @Override public boolean invoke(Object o) { return set.contains(o); } }; } /** * Returns a Function which expects a String parameter s and returns * prefix+s+suffix as a String. * @param prefix Prefix String. * @param suffix Suffix String. * @return The Function. */ public static Function<String, String> getPrefixSuffixMapStringFunction(final String prefix, final String suffix) { return new AbstractFunction<String, String>() { @Override public String invoke(String o) { return prefix+o+suffix; } }; } /** * Function which gets an object and returns the String * representation of the object (uses toString() inside). */ public static final Function<Object, String> TO_STRING_FUNCTION = new AbstractFunction<Object, String>() { @Override public String invoke(Object o) { return o.toString(); } }; /** This method is parsing a String using given delimeters and is * returning the parsed String as <tt>String[]</tt> * separated by the delimeters. The delimeters are not returned. * @param s String to parse * @param delims <tt>String[]</tt> used as delimeters * @return <tt>String[]</tt> containing the parsed String */ public static String[] parse( String s, String[] delims){ List<String> l = new ArrayList<String>(); if ( s.equals ("") ) return new String[]{""}; if ( delims.length == 0) return new String[]{s}; String t = s.trim(); while ( t.length() > 0){ int delim = 0; int index = t.length() + 1; for ( int i= 0; i < delims.length ; i++){ if ( ( index > t.indexOf(delims[i])) && (t.indexOf(delims[i]) != -1) ){ index = t.indexOf(delims[i]) ; delim = i; // welcher trenner war es? } } try{ String n = t.substring (0, index); l.add ( n); t = t.substring (index - 1 + delims[delim].length() , t.length()).trim(); } catch (Exception e){ l.add ( t); t = ""; } } String[] r = new String[l.size()]; for ( int i= 0; i < r.length; i++){ r[i] = l.get(i); } return r; } /** This method is parsing a String using the given delimeter and is * returning the parsed String as String[] * separated by the delimeter. The delimeter is not returned. * @param s String to parse * @param delim String used as delimeter * @return String[] containing the parsed String */ public static String [] parse( String s, String delim){ if ( s.trim().equals ("") && !delim.equals(" ")) return new String[]{""}; if ( s.equals ("") ) return new String[]{""}; StringTokenizer st = new StringTokenizer( s, delim); String[] r = new String[ st.countTokens() ]; int i=0; while( st.hasMoreElements() ) { r[i] = (String) st.nextElement(); i++; } return r; } /** This method is converting a <tt>String []</tt> to a <tt>double []</tt> of same length. * @param s <tt>String []</tt> to convert * @return <tt>double []</tt> containing a double representation of each String from the * input array. */ public static double [] toDoubleArray ( String [] s){ double [] r = new double[ s.length]; for ( int i = 0; i < r.length ; i++) r[i] = (new Double( s[i])).doubleValue(); return r; } /** This method is converting a <tt>String []</tt> to a <tt>float []</tt> of same length. * @param s <tt>String []</tt> to convert * @return <tt>float []</tt> containing a float representation of each String from the * input array. */ public static float[] toFloatArray ( String[] s){ float [] r = new float[ s.length]; for ( int i = 0; i < r.length ; i++) r[i] = (new Float( s[i])).floatValue(); return r; } /** This method is converting a <tt>String []</tt> to a <tt>int []</tt> of same length. * @param s <tt>String []</tt> to convert * @return <tt>int []</tt> containing a float representation of each String from the * input array. */ public static int [] toIntArray ( String[] s){ int [] r = new int[ s.length]; for ( int i = 0; i < r.length ; i++) r[i] = (new Integer( s[i])).intValue(); return r; } /** This method is converting a <tt>String []</tt> to a <tt>long []</tt> of same length. * @param s <tt>String []</tt> to convert * @return <tt>long []</tt> containing a float representation of each String from the * input array. */ public static long [] toLongArray ( String[] s){ long [] r = new long[ s.length]; for ( int i = 0; i < r.length ; i++) r[i] = (new Long( s[i])).longValue(); return r; } /** Returns a character reader based reader upon the source given by the name. * Different sources such as web-servers or files will be choosen automatically * determind by the given name, i.e., a source starting with <tt>http</tt> will be treated as * a web-based text-file. At this time only <tt>http</tt> and files are supported. * * @param source name of the data source provided as {@link java.io.Reader reader} * @return the given source as {@link java.io.Reader reader} * @throws WrappingRuntimeException if an error of any type occures */ public static Reader getReader( String source) throws WrappingRuntimeException{ Reader r = null; boolean init = false; try{ // -- url --- if ( source.trim().toLowerCase().startsWith("http")){ URL url = new URL (source); r = new InputStreamReader ( url.openStream()); init = true; } // -- default file --- if ( ! init){ r = new FileReader ( new File ( source)); } } catch ( Exception e){ throw new WrappingRuntimeException (e); } return r; } /** Assumes that the given String indicates a file and replaces the * suffix by a new one. The suffix if given by "*.suffix" meaning the last found * '.' and all following character will be replaced. If there's no '.' in the given String * the given suffix will be concatenated. * @param filename String treated as file name * @param newSuffix new suffix for the file name * @return a String representing a file name */ public static String changeSuffix( String filename, String newSuffix){ int k = filename.lastIndexOf("."); return (k == -1) ? filename : filename.substring(0,k) + newSuffix; } /** Assumes that the given String represents a fully qualified * file name (i.e., with path information) and returns the file name without any * folder information by pruning all parts before the last * separator character * return the file name itself * @param filename fully qualified file name * @return file name withiout path information * @see File#separator */ public static String prunePath( String filename){ String r = filename; int i1 = r.lastIndexOf( File.separator); if ( i1 != -1) r = r.substring( i1+1, r.length()); return r; } }