001/*
002 * Copyright (c) 2007-2017 Xplenty, Inc. All Rights Reserved.
003 *
004 * Project and contact information: http://www.cascading.org/
005 *
006 * This file is part of the Cascading project.
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *     http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020
021package cascading.property;
022
023import java.util.HashMap;
024import java.util.HashSet;
025import java.util.Map;
026import java.util.Properties;
027import java.util.Set;
028
029import cascading.flow.planner.ScopedElement;
030
031import static cascading.util.Util.isEmpty;
032
033/** Class PropertyUtil is a static helper class for handling properties. */
034public class PropertyUtil
035  {
036  public static String getProperty( Map<Object, Object> properties, String property )
037    {
038    return getProperty( properties, property, (String) null );
039    }
040
041  public static boolean getBooleanProperty( Map<Object, Object> properties, String property, boolean defaultValue )
042    {
043    return getBooleanProperty( System.getProperties(), properties, property, defaultValue );
044    }
045
046  public static boolean getBooleanProperty( Properties defaultProperties, Map<Object, Object> properties, String property, boolean defaultValue )
047    {
048    String result;
049
050    if( defaultProperties == null )
051      result = getProperty( properties, property );
052    else
053      result = getProperty( properties, property, defaultProperties.getProperty( property ) );
054
055    if( isEmpty( result ) )
056      return defaultValue;
057
058    return Boolean.parseBoolean( result );
059    }
060
061  public static int getIntProperty( Map<Object, Object> properties, String property, int defaultValue )
062    {
063    return getIntProperty( System.getProperties(), properties, property, defaultValue );
064    }
065
066  public static int getIntProperty( Properties defaultProperties, Map<Object, Object> properties, String property, int defaultValue )
067    {
068    String result;
069
070    if( defaultProperties == null )
071      result = getProperty( properties, property );
072    else
073      result = getProperty( properties, property, defaultProperties.getProperty( property ) );
074
075    if( isEmpty( result ) )
076      return defaultValue;
077
078    return Integer.parseInt( result );
079    }
080
081  public static String getStringProperty( Map<Object, Object> properties, String property )
082    {
083    return getStringProperty( System.getProperties(), properties, property );
084    }
085
086  public static String getStringProperty( Properties defaultProperties, Map<Object, Object> properties, String property )
087    {
088    if( defaultProperties == null )
089      return getProperty( properties, property );
090
091    return getProperty( properties, property, defaultProperties.getProperty( property ) );
092    }
093
094  public static <A> A getProperty( Map<Object, Object> properties, String key, A defaultValue )
095    {
096    if( properties == null )
097      return defaultValue;
098
099    A value;
100
101    if( properties instanceof Properties )
102      value = (A) ( (Properties) properties ).getProperty( key );
103    else
104      value = (A) properties.get( key );
105
106    return value == null ? defaultValue : value;
107    }
108
109  public static String getProperty( final Map<Object, Object> properties, ScopedElement flowElement, String property )
110    {
111    if( flowElement != null && flowElement.hasConfigDef() )
112      return PropertyUtil.getProperty( properties, flowElement.getConfigDef(), property );
113
114    return PropertyUtil.getProperty( properties, property );
115    }
116
117  public static String getProperty( final Map<Object, Object> properties, ConfigDef configDef, String property )
118    {
119    return configDef.apply( property, new ConfigDef.Getter()
120    {
121    @Override
122    public String update( String key, String value )
123      {
124      return value;
125      }
126
127    @Override
128    public String get( String key )
129      {
130      return getProperty( properties, key );
131      }
132    } );
133    }
134
135  public static void setProperty( Map<Object, Object> properties, String key, String value )
136    {
137    if( properties == null || value == null || value.isEmpty() )
138      return;
139
140    if( properties instanceof Properties )
141      ( (Properties) properties ).setProperty( key, value );
142    else
143      properties.put( key, value );
144    }
145
146  public static Properties createProperties( Iterable<Map.Entry<String, String>> defaultProperties )
147    {
148    Properties properties = new Properties();
149
150    for( Map.Entry<String, String> property : defaultProperties )
151      properties.setProperty( property.getKey(), property.getValue() );
152
153    return properties;
154    }
155
156  public static Properties createProperties( Map<Object, Object> properties, Properties defaultProperties )
157    {
158    Properties results = defaultProperties == null ? new Properties() : new Properties( defaultProperties );
159
160    if( properties == null )
161      return results;
162
163    Set<Object> keys = new HashSet<Object>( properties.keySet() );
164
165    // keys will only be grabbed if both key/value are String, so keep orig keys
166    if( properties instanceof Properties )
167      keys.addAll( ( (Properties) properties ).stringPropertyNames() );
168
169    for( Object key : keys )
170      {
171      Object value = properties.get( key );
172
173      if( value == null && properties instanceof Properties && key instanceof String )
174        value = ( (Properties) properties ).getProperty( (String) key );
175
176      if( value == null ) // don't stuff null values
177        continue;
178
179      // don't let these objects pass, even though toString is called below.
180      if( value instanceof Class )
181        continue;
182
183      results.setProperty( key.toString(), value.toString() );
184      }
185
186    return results;
187    }
188
189  public static Map<Object, Object> asFlatMap( Map<Object, Object> properties )
190    {
191    if( !( properties instanceof Properties ) )
192      return properties;
193
194    Map<Object, Object> map = new HashMap<>();
195    Properties props = (Properties) properties;
196
197    for( String property : props.stringPropertyNames() )
198      map.put( property, props.getProperty( property ) );
199
200    return map;
201    }
202  }