001/*
002 * Copyright (c) 2007-2016 Concurrent, 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 int getIntProperty( Map<Object, Object> properties, String property, int defaultValue )
042    {
043    return getIntProperty( System.getProperties(), properties, property, defaultValue );
044    }
045
046  public static int getIntProperty( Properties defaultProperties, Map<Object, Object> properties, String property, int 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 Integer.parseInt( result );
059    }
060
061  public static String getStringProperty( Map<Object, Object> properties, String property )
062    {
063    return getStringProperty( System.getProperties(), properties, property );
064    }
065
066  public static String getStringProperty( Properties defaultProperties, Map<Object, Object> properties, String property )
067    {
068    if( defaultProperties == null )
069      return getProperty( properties, property );
070
071    return getProperty( properties, property, defaultProperties.getProperty( property ) );
072    }
073
074  public static <A> A getProperty( Map<Object, Object> properties, String key, A defaultValue )
075    {
076    if( properties == null )
077      return defaultValue;
078
079    A value;
080
081    if( properties instanceof Properties )
082      value = (A) ( (Properties) properties ).getProperty( key );
083    else
084      value = (A) properties.get( key );
085
086    return value == null ? defaultValue : value;
087    }
088
089  public static String getProperty( final Map<Object, Object> properties, ScopedElement flowElement, String property )
090    {
091    if( flowElement.hasConfigDef() )
092      return PropertyUtil.getProperty( properties, flowElement.getConfigDef(), property );
093
094    return PropertyUtil.getProperty( properties, property );
095    }
096
097  public static String getProperty( final Map<Object, Object> properties, ConfigDef configDef, String property )
098    {
099    return configDef.apply( property, new ConfigDef.Getter()
100    {
101    @Override
102    public String update( String key, String value )
103      {
104      return value;
105      }
106
107    @Override
108    public String get( String key )
109      {
110      return getProperty( properties, key );
111      }
112    } );
113    }
114
115  public static void setProperty( Map<Object, Object> properties, String key, String value )
116    {
117    if( properties == null || value == null || value.isEmpty() )
118      return;
119
120    if( properties instanceof Properties )
121      ( (Properties) properties ).setProperty( key, value );
122    else
123      properties.put( key, value );
124    }
125
126  public static Properties createProperties( Iterable<Map.Entry<String, String>> defaultProperties )
127    {
128    Properties properties = new Properties();
129
130    for( Map.Entry<String, String> property : defaultProperties )
131      properties.setProperty( property.getKey(), property.getValue() );
132
133    return properties;
134    }
135
136  public static Properties createProperties( Map<Object, Object> properties, Properties defaultProperties )
137    {
138    Properties results = defaultProperties == null ? new Properties() : new Properties( defaultProperties );
139
140    if( properties == null )
141      return results;
142
143    Set<Object> keys = new HashSet<Object>( properties.keySet() );
144
145    // keys will only be grabbed if both key/value are String, so keep orig keys
146    if( properties instanceof Properties )
147      keys.addAll( ( (Properties) properties ).stringPropertyNames() );
148
149    for( Object key : keys )
150      {
151      Object value = properties.get( key );
152
153      if( value == null && properties instanceof Properties && key instanceof String )
154        value = ( (Properties) properties ).getProperty( (String) key );
155
156      if( value == null ) // don't stuff null values
157        continue;
158
159      // don't let these objects pass, even though toString is called below.
160      if( value instanceof Class )
161        continue;
162
163      results.setProperty( key.toString(), value.toString() );
164      }
165
166    return results;
167    }
168
169  public static Map<Object, Object> asFlatMap( Map<Object, Object> properties )
170    {
171    if( !( properties instanceof Properties ) )
172      return properties;
173
174    Map<Object, Object> map = new HashMap<>();
175    Properties props = (Properties) properties;
176
177    for( String property : props.stringPropertyNames() )
178      map.put( property, props.getProperty( property ) );
179
180    return map;
181    }
182  }