001/* 002 * Copyright (c) 2016-2017 Chris K Wensel <chris@wensel.net>. All Rights Reserved. 003 * Copyright (c) 2007-2017 Xplenty, Inc. All Rights Reserved. 004 * 005 * Project and contact information: http://www.cascading.org/ 006 * 007 * This file is part of the Cascading project. 008 * 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 */ 021 022package cascading.property; 023 024import java.util.HashMap; 025import java.util.HashSet; 026import java.util.Map; 027import java.util.Objects; 028import java.util.Properties; 029import java.util.Set; 030 031import cascading.flow.planner.ScopedElement; 032 033import static cascading.util.Util.isEmpty; 034 035/** Class PropertyUtil is a static helper class for handling properties. */ 036public class PropertyUtil 037 { 038 public static String getProperty( Map<Object, Object> properties, String property ) 039 { 040 return getProperty( properties, property, (String) null ); 041 } 042 043 public static boolean getBooleanProperty( Map<Object, Object> properties, String property, boolean defaultValue ) 044 { 045 return getBooleanProperty( System.getProperties(), properties, property, defaultValue ); 046 } 047 048 public static boolean getBooleanProperty( Properties defaultProperties, Map<Object, Object> properties, String property, boolean defaultValue ) 049 { 050 String result; 051 052 if( defaultProperties == null ) 053 result = getProperty( properties, property ); 054 else 055 result = getProperty( properties, property, defaultProperties.getProperty( property ) ); 056 057 if( isEmpty( result ) ) 058 return defaultValue; 059 060 return Boolean.parseBoolean( result ); 061 } 062 063 public static int getIntProperty( Map<Object, Object> properties, String property, int defaultValue ) 064 { 065 return getIntProperty( System.getProperties(), properties, property, defaultValue ); 066 } 067 068 public static int getIntProperty( Properties defaultProperties, Map<Object, Object> properties, String property, int defaultValue ) 069 { 070 String result; 071 072 if( defaultProperties == null ) 073 result = getProperty( properties, property ); 074 else 075 result = getProperty( properties, property, defaultProperties.getProperty( property ) ); 076 077 if( isEmpty( result ) ) 078 return defaultValue; 079 080 return Integer.parseInt( result ); 081 } 082 083 public static String getStringProperty( Map<Object, Object> properties, String property ) 084 { 085 return getStringProperty( System.getProperties(), properties, property ); 086 } 087 088 public static String getStringProperty( Properties defaultProperties, Map<Object, Object> properties, String property ) 089 { 090 if( defaultProperties == null ) 091 return getProperty( properties, property ); 092 093 return getProperty( properties, property, defaultProperties.getProperty( property ) ); 094 } 095 096 public static <A> A getProperty( Map<Object, Object> properties, String key, A defaultValue ) 097 { 098 if( properties == null ) 099 return defaultValue; 100 101 A value; 102 103 if( properties instanceof Properties ) 104 value = (A) ( (Properties) properties ).getProperty( key ); 105 else 106 value = (A) properties.get( key ); 107 108 return value == null ? defaultValue : value; 109 } 110 111 public static String getProperty( final Map<Object, Object> properties, ScopedElement flowElement, String property ) 112 { 113 if( flowElement != null && flowElement.hasConfigDef() ) 114 return PropertyUtil.getProperty( properties, flowElement.getConfigDef(), property ); 115 116 return PropertyUtil.getProperty( properties, property ); 117 } 118 119 public static String getProperty( final Map<Object, Object> properties, ConfigDef configDef, String property ) 120 { 121 return configDef.apply( property, new ConfigDef.Getter() 122 { 123 @Override 124 public String update( String key, String value ) 125 { 126 return value; 127 } 128 129 @Override 130 public String get( String key ) 131 { 132 return getProperty( properties, key ); 133 } 134 } ); 135 } 136 137 public static void setProperty( Map<Object, Object> properties, String key, String value ) 138 { 139 if( properties == null || value == null || value.isEmpty() ) 140 return; 141 142 if( properties instanceof Properties ) 143 ( (Properties) properties ).setProperty( key, value ); 144 else 145 properties.put( key, value ); 146 } 147 148 public static Properties createProperties( Iterable<Map.Entry<String, String>> defaultProperties ) 149 { 150 Properties properties = new Properties(); 151 152 for( Map.Entry<String, String> property : defaultProperties ) 153 properties.setProperty( property.getKey(), property.getValue() ); 154 155 return properties; 156 } 157 158 public static Properties createProperties( Map<Object, Object> properties, Properties defaultProperties ) 159 { 160 Properties results = defaultProperties == null ? new Properties() : new Properties( defaultProperties ); 161 162 if( properties == null ) 163 return results; 164 165 Set<Object> keys = new HashSet<Object>( properties.keySet() ); 166 167 // keys will only be grabbed if both key/value are String, so keep orig keys 168 if( properties instanceof Properties ) 169 keys.addAll( ( (Properties) properties ).stringPropertyNames() ); 170 171 for( Object key : keys ) 172 { 173 Object value = properties.get( key ); 174 175 if( value == null && properties instanceof Properties && key instanceof String ) 176 value = ( (Properties) properties ).getProperty( (String) key ); 177 178 if( value == null ) // don't stuff null values 179 continue; 180 181 // don't let these objects pass, even though toString is called below. 182 if( value instanceof Class ) 183 continue; 184 185 results.setProperty( key.toString(), value.toString() ); 186 } 187 188 return results; 189 } 190 191 public static Map<Object, Object> asFlatMap( Map<Object, Object> properties ) 192 { 193 if( !( properties instanceof Properties ) ) 194 return properties; 195 196 Map<Object, Object> map = new HashMap<>(); 197 Properties props = (Properties) properties; 198 199 for( String property : props.stringPropertyNames() ) 200 map.put( property, props.getProperty( property ) ); 201 202 return map; 203 } 204 205 /** 206 * Merge all properties instances into one. 207 * <p> 208 * Always returns a new Properties instance. 209 * <p> 210 * Subsequent values to not overwrite earlier values, that is, the left most instances 211 * have more precedence, that is, won't be replaced. 212 * 213 * @param properties 214 * @return a new Properties instance. 215 */ 216 public static Properties merge( Properties... properties ) 217 { 218 Properties results = new Properties(); 219 220 for( int i = properties.length - 1; i >= 0; i-- ) 221 { 222 Properties current = properties[ i ]; 223 224 if( current == null ) 225 continue; 226 227 Set<String> currentNames = current.stringPropertyNames(); 228 229 for( String currentName : currentNames ) 230 results.setProperty( currentName, current.getProperty( currentName ) ); 231 } 232 233 return results; 234 } 235 236 public static Properties remove( Properties properties, Properties... remove ) 237 { 238 Objects.requireNonNull( properties, "properties may not be null" ); 239 240 Set<String> keys = new HashSet<>(); 241 242 for( Properties current : remove ) 243 keys.addAll( current.stringPropertyNames() ); 244 245 return remove( properties, keys ); 246 } 247 248 public static Properties remove( Properties properties, Set<String> keys ) 249 { 250 Objects.requireNonNull( properties, "properties may not be null" ); 251 252 Properties results = new Properties(); 253 254 for( String name : properties.stringPropertyNames() ) 255 { 256 if( keys.contains( name ) ) 257 continue; 258 259 results.setProperty( name, properties.getProperty( name ) ); 260 } 261 262 return results; 263 } 264 265 public static Properties retain( Properties properties, Properties... retain ) 266 { 267 Objects.requireNonNull( properties, "properties may not be null" ); 268 269 Set<String> keys = new HashSet<>(); 270 271 for( Properties current : retain ) 272 { 273 if( current != null ) 274 keys.addAll( current.stringPropertyNames() ); 275 } 276 277 return remove( properties, keys ); 278 } 279 280 public static Properties retain( Properties properties, Set<String> keys ) 281 { 282 Objects.requireNonNull( properties, "properties may not be null" ); 283 284 Properties results = new Properties(); 285 286 for( String name : properties.stringPropertyNames() ) 287 { 288 if( !keys.contains( name ) ) 289 continue; 290 291 results.setProperty( name, properties.getProperty( name ) ); 292 } 293 294 return results; 295 } 296 }