/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.core.image.filter.parser; import java.util.ArrayList; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; public final class FilterExprParserContext { private final static Pattern QUOTE_PATTERN = Pattern.compile( "'([^']*)'" ); private final static Pattern DQUOTE_PATTERN = Pattern.compile( "\"([^\"]*)\"" ); private final String value; private final HashMap<String, String> stringMap; public FilterExprParserContext( String value ) { this.stringMap = new HashMap<String, String>(); this.value = replaceStrings( this.stringMap, value ); } public FilterSetExpr parseFilterSet() { FilterSetExpr set = new FilterSetExpr(); for ( String part : this.value.split( ";" ) ) { FilterExpr expr = parseFilter( part ); if ( expr != null ) { set.add( expr ); } } return set; } private FilterExpr parseFilter( String str ) { String name = parseName( str ); Object[] args = parseArguments( str ); if ( name != null ) { return new FilterExpr( name, args ); } else { return null; } } private String parseName( String str ) { if ( str == null ) { return null; } int pos = str.indexOf( '(' ); if ( pos >= 0 ) { str = str.substring( 0, pos ); } str = str.trim(); if ( str.length() > 0 ) { return str; } else { return null; } } private Object[] parseArguments( String str ) { if ( str == null ) { return null; } int beginPos = str.indexOf( '(' ); int endPos = str.indexOf( ')' ); if ( ( beginPos < 0 ) || ( endPos < 0 ) ) { return null; } str = str.substring( beginPos + 1, endPos ).trim(); if ( str.length() == 0 ) { return null; } ArrayList<Object> list = new ArrayList<Object>(); for ( String part : str.split( "," ) ) { list.add( parseValue( part ) ); } return list.toArray( new Object[list.size()] ); } private Object parseValue( String str ) { if ( str == null ) { return null; } str = str.trim(); if ( str.length() == 0 ) { return null; } Object value = parseStringValue( str ); if ( value == null ) { value = parseHexValue( str ); } if ( value == null ) { value = parseBooleanValue( str ); } if ( value == null ) { value = parseIntegerValue( str ); } if ( value == null ) { value = parseDoubleValue( str ); } return value; } private String parseStringValue( String str ) { if ( str.startsWith( "%" ) ) { return this.stringMap.get( str ); } else { return null; } } private Integer parseHexValue( String str ) { if ( !str.startsWith( "0x" ) ) { return null; } str = str.substring( 2 ); try { return Integer.parseInt( str, 16 ); } catch ( Exception e ) { return null; } } private Boolean parseBooleanValue( String str ) { if ( str.equals( "true" ) ) { return Boolean.TRUE; } else if ( str.equals( "false" ) ) { return Boolean.FALSE; } else { return null; } } private Double parseDoubleValue( String str ) { try { return new Double( str ); } catch ( Exception e ) { return null; } } private Integer parseIntegerValue( String str ) { try { return new Integer( str ); } catch ( Exception e ) { return null; } } private static String replaceStrings( HashMap<String, String> map, String value ) { return replaceStrings( map, replaceStrings( map, value, QUOTE_PATTERN ), DQUOTE_PATTERN ); } private static String replaceStrings( HashMap<String, String> map, String value, Pattern pattern ) { StringBuffer str = new StringBuffer(); Matcher matcher = pattern.matcher( value ); while ( matcher.find() ) { matcher.appendReplacement( str, addReplacementValue( map, matcher.group( 1 ) ) ); } matcher.appendTail( str ); return str.toString(); } private static String addReplacementValue( HashMap<String, String> map, String value ) { String key = "%" + map.size(); map.put( key, value ); return key; } }