001    /*
002     * Copyright (c) 2007-2015 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    
021    package cascading.property;
022    
023    import java.util.HashMap;
024    import java.util.HashSet;
025    import java.util.Map;
026    import java.util.Properties;
027    import java.util.Set;
028    
029    import cascading.flow.FlowElement;
030    
031    /** Class PropertyUtil is a static helper class for handling properties. */
032    public class PropertyUtil
033      {
034      public static String getProperty( Map<Object, Object> properties, String property )
035        {
036        return getProperty( properties, property, (String) null );
037        }
038    
039      public static String getStringProperty( Properties defaultProperties, Map<Object, Object> properties, String property )
040        {
041        if( defaultProperties == null )
042          return getProperty( properties, property );
043    
044        return getProperty( properties, property, defaultProperties.getProperty( property ) );
045        }
046    
047      public static <A> A getProperty( Map<Object, Object> properties, String key, A defaultValue )
048        {
049        if( properties == null )
050          return defaultValue;
051    
052        A value;
053    
054        if( properties instanceof Properties )
055          value = (A) ( (Properties) properties ).getProperty( key );
056        else
057          value = (A) properties.get( key );
058    
059        return value == null ? defaultValue : value;
060        }
061    
062      public static String getProperty( final Map<Object, Object> properties, FlowElement flowElement, String property )
063        {
064        if( flowElement.hasConfigDef() )
065          return PropertyUtil.getProperty( properties, flowElement.getConfigDef(), property );
066    
067        return PropertyUtil.getProperty( properties, property );
068        }
069    
070      public static String getProperty( final Map<Object, Object> properties, ConfigDef configDef, String property )
071        {
072        return configDef.apply( property, new ConfigDef.Getter()
073        {
074        @Override
075        public String update( String key, String value )
076          {
077          return value;
078          }
079    
080        @Override
081        public String get( String key )
082          {
083          return getProperty( properties, key );
084          }
085        } );
086        }
087    
088      public static void setProperty( Map<Object, Object> properties, String key, String value )
089        {
090        if( properties == null || value == null || value.isEmpty() )
091          return;
092    
093        if( properties instanceof Properties )
094          ( (Properties) properties ).setProperty( key, value );
095        else
096          properties.put( key, value );
097        }
098    
099      public static Properties createProperties( Iterable<Map.Entry<String, String>> defaultProperties )
100        {
101        Properties properties = new Properties();
102    
103        for( Map.Entry<String, String> property : defaultProperties )
104          properties.setProperty( property.getKey(), property.getValue() );
105    
106        return properties;
107        }
108    
109      public static Properties createProperties( Map<Object, Object> properties, Properties defaultProperties )
110        {
111        Properties results = defaultProperties == null ? new Properties() : new Properties( defaultProperties );
112    
113        if( properties == null )
114          return results;
115    
116        Set<Object> keys = new HashSet<Object>( properties.keySet() );
117    
118        // keys will only be grabbed if both key/value are String, so keep orig keys
119        if( properties instanceof Properties )
120          keys.addAll( ( (Properties) properties ).stringPropertyNames() );
121    
122        for( Object key : keys )
123          {
124          Object value = properties.get( key );
125    
126          if( value == null && properties instanceof Properties && key instanceof String )
127            value = ( (Properties) properties ).getProperty( (String) key );
128    
129          if( value == null ) // don't stuff null values
130            continue;
131    
132          // don't let these objects pass, even though toString is called below.
133          if( value instanceof Class )
134            continue;
135    
136          results.setProperty( key.toString(), value.toString() );
137          }
138    
139        return results;
140        }
141    
142      public static Map<Object, Object> asFlatMap( Map<Object, Object> properties )
143        {
144        if( !( properties instanceof Properties ) )
145          return properties;
146    
147        Map<Object, Object> map = new HashMap<Object, Object>();
148        Properties props = (Properties) properties;
149    
150        for( String property : props.stringPropertyNames() )
151          map.put( property, props.getProperty( property ) );
152    
153        return map;
154        }
155      }