uk.org.retep.util.collections.MapUtils Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2007, Peter T Mount
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the retep.org.uk nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.org.retep.util.collections;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import uk.org.retep.util.io.BufferedCharReader;
import uk.org.retep.util.io.FileUtils;
import uk.org.retep.util.string.StringUtils;
/** A collection of utility methods for java.util.Map
* @author peter
*/
public final class MapUtils
{
/** Creates a new instance of MapUtils */
private MapUtils()
{
}
/** Loads a Map from a URL
* @param map Map to load into
* @param url URL of resource containing map
* @throws IOException On error
* @return map with the contents of the resource loaded
*/
public static Map loadMap( Map map, URL url )
throws IOException
{
return loadMap( map, url.openStream() );
}
/** Loads a Map from a URL
* @return map with the contents of the resource loaded
* @param is InputStream
* @param map Map to load into
* @throws IOException On error
*/
public static Map loadMap( Map map,
InputStream is )
throws IOException
{
return loadMap( map, new InputStreamReader( is ) );
}
/** Loads a Map from a URL
* @return map with the contents of the resource loaded
* @param reader Reader
* @param map Map to load into
* @throws IOException On error
*/
public static Map loadMap( Map map,
Reader reader )
throws IOException
{
BufferedReader rdr = new BufferedReader( reader );
boolean run = true;
while( run )
{
String line = rdr.readLine();
if( line == null )
{
run = false;
}
else
{
if( !(line.equals( "" ) || line.startsWith( "#" )) )
{
int start = StringUtils.findNonWhitespace( line );
int sep = StringUtils.findKeySeparator( line, start );
String key = line.substring( start, sep );
String val = line.substring( StringUtils.findKeyValue( line,
sep ) );
map.put( key, val );
}
}
}
return map;
}
public static Map loadMap( final InputStream is,
final Map map )
throws IOException
{
return loadMap( FileUtils.readLines( is ), map );
}
public static Map loadMap( final InputStream is )
throws IOException
{
return loadMap( FileUtils.readLines( is ) );
}
public static Map loadMap( final Reader r,
final Map map )
throws IOException
{
return loadMap( FileUtils.readLines( r ), map );
}
public static Map loadMap( final Reader r )
throws IOException
{
return loadMap( FileUtils.readLines( r ) );
}
public static Map loadMap( final File file,
final Map map )
throws IOException
{
return loadMap( FileUtils.readLines( file ), map );
}
public static Map loadMap( final File file )
throws IOException
{
return loadMap( FileUtils.readLines( file ) );
}
public static Map loadMap( final BufferedCharReader r,
final Map map )
throws IOException
{
return loadMap( FileUtils.readLines( r ), map );
}
public static Map loadMap( final BufferedCharReader r )
throws IOException
{
return loadMap( FileUtils.readLines( r ) );
}
public static Map loadMap( final List lines )
{
return loadMap( lines, new HashMap() );
}
public static Map loadMap( final List lines,
final Map map )
{
final StringBuilder sb = new StringBuilder();
for( String line : lines )
{
final int l = line.length() - 1;
// blank line
if( l < 0 )
{
continue;
}
// find an unescaped comment
int c = -1;
if( line.length() > 0 )
{
int h = line.indexOf( '#' );
while( h > 0 && h < l && line.charAt( h - 1 ) == '\\' )
{
h = line.indexOf( '#', h + 1 );
}
int p = line.indexOf( '!' );
while( p > 0 && p < l && line.charAt( p - 1 ) == '\\' )
{
p = line.indexOf( '!', p + 1 );
}
if( h > -1 )
{
c = h;
}
if( p > -1 && p < h )
{
c = p;
}
}
// entire line is a comment
if( c == 0 )
{
continue;
}
else if( c > 0 )
{
// remove the comment
line = line.substring( 0, c );
}
if( line.charAt( line.length() - 1 ) == '\'' )
{
// line continues to next line, so strip the tailing \
// and use the buffer
sb.append( line );
sb.setLength( sb.length() - 1 );
}
else
{
// Read the line
if( sb.length() == 0 )
{
// not in buffer
loadLine( line, map );
}
else
{
// append to buffer then use
sb.append( line );
loadLine( sb.toString(), map );
// erase buffer for reuse
sb.setLength( 0 );
}
}
}
// Catch any remaining buffer content
if( sb.length() > 0 )
{
loadLine( sb.toString(), map );
}
return map;
}
public static Map loadLine( final String line,
final Map map )
{
if( line == null )
{
return map;
}
final char b[] = line.trim().toCharArray();
// blank line, or a comment
if( b.length == 0 || b[0] == '#' || b[0] == '!' )
{
return map;
}
final StringBuffer key = new StringBuffer();
int pos = 0;
char c = 0;
while( pos < line.length() && !Character.isWhitespace( c = b[pos++] ) && c != '=' && c != ':' )
{
if( c == '\'' )
{
c = line.charAt( pos++ );
switch( c )
{
case 'n':
key.append( '\n' );
break;
case 't':
key.append( '\t' );
break;
case 'r':
key.append( '\r' );
break;
case 'u':
if( pos + 4 <= line.length() )
{
final char uni = (char) Integer.parseInt(
line.substring( pos, pos + 4 ), 16 );
key.append( uni );
pos += 4;
}
break;
default:
key.append( c );
break;
}
}
else
{
key.append( c );
}
}
boolean isDelim = (c == ':' || c == '=');
while( pos < line.length() &&
Character.isWhitespace( c = line.charAt( pos ) ) )
{
pos++;
}
if( !isDelim && (c == ':' || c == '=') )
{
pos++;
while( pos < line.length() &&
Character.isWhitespace( c = line.charAt( pos ) ) )
{
pos++;
}
}
final StringBuilder value = new StringBuilder( line.length() - pos );
while( pos < line.length() )
{
c = line.charAt( pos++ );
if( c == '\\' )
{
c = line.charAt( pos++ );
switch( c )
{
case 'n':
value.append( '\n' );
break;
case 't':
value.append( '\t' );
break;
case 'r':
value.append( '\r' );
break;
case 'u':
if( pos + 4 <= line.length() )
{
char uni = (char) Integer.parseInt( line.substring(
pos, pos + 4 ),
16 );
value.append( uni );
pos += 4;
} // else throw exception?
break;
default:
value.append( c );
break;
}
}
else
{
value.append( c );
}
}
map.put( key.toString(), value.toString() );
return map;
}
}