views:

208

answers:

6

I need to read a properties file and generate a Properties class in Java. I do so by using:

Properties props = new Properties();
props.load(new FileInputStream(args[0]));
for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
}

However, the properties returned by props.propertyName is not in the order of the original properties file. I understand that Properties are just old fashioned, non-generified Hashtables. I'm looking for a work around. Any idea? Thank you!

+1  A: 

The fact they are represented as a Hashtable under the hood means that their order is not kept in any fashion.

I'd suggest you "roll your own" properties reader if you're absolutely desperate for this functionality.

Noel M
There is nothing "under the hood" about the use of `Hashtable` - `Properties extends Hashtable<Object,Object>`.
Tom Hawtin - tackline
A: 

Subclass Properties to memorize reading order and create an Enumeration that uses the ordered keys list ?

Riduidel
+3  A: 

You may want to implement your own Properties class with similar functionalities. It will not be possible for you to obtain the order since, as you already pointed out, it uses Hashtable.

Having said that, there are some interesting suggestions here.

pavanlimo
+1  A: 

You can extend Properties and delegate all map methods to a LinkedHashMap to retain the order. Here is an example (you may need to override some more methods):

public class LinkedProperties extends Properties{


    private static final long serialVersionUID = 1L;

    private Map<Object, Object> linkMap = new LinkedHashMap<Object,Object>();

    @Override
    public synchronized Object put(Object key, Object value){
        return linkMap.put(key, value);
    }

    @Override
    public synchronized boolean contains(Object value){
        return linkMap.containsValue(value);
    }

    @Override
    public boolean containsValue(Object value){
        return linkMap.containsValue(value);
    }

    @Override
    public synchronized Enumeration<Object> elements(){
        throw new UnsupportedOperationException(
          "Enumerations are so old-school, don't use them, "
        + "use keySet() or entrySet() instead");
    }

    @Override
    public Set<Entry<Object, Object>> entrySet(){
        return linkMap.entrySet();
    }

    @Override
    public synchronized void clear(){
        linkMap.clear();
    }

    @Override
    public synchronized boolean containsKey(Object key){
        return linkMap.containsKey(key);
    }

}
seanizer
A: 

Example from www.java2s.com should solve your problem.

import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;

/**
 * <a href="OrderedProperties.java.html"><b><i>View Source</i></b></a>
 *
 * @author Brian Wing Shun Chan
 *
 */
public class OrderedProperties extends Properties {

    public OrderedProperties() {
        super ();

        _names = new Vector();
    }

    public Enumeration propertyNames() {
        return _names.elements();
    }

    public Object put(Object key, Object value) {
        if (_names.contains(key)) {
            _names.remove(key);
        }

        _names.add(key);

        return super .put(key, value);
    }

    public Object remove(Object key) {
        _names.remove(key);

        return super .remove(key);
    }

    private Vector _names;

}

And your code will change to:

Properties props = new OrderedProperties();
props.load(new FileInputStream(args[0]));
for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
}
YoK
A: 

To solve the problem: "to execute classes based on the order in the properties file." I normally used one of 2 possibilities:

1 - use one property as a comma-separated list with the class-names or with the keys to the class definition

loadClasses = class-definition-A, class-definition-B, class-definition-C

or (useful if the "definition" consists of more than one property)

loadClasses = keyA, keyB, keyC
keyA = class-definition-A
keyB = class-definition-B
keyC = class-definition-C


2 - use a key followed by an index (counter). Read the keys in a loop until no value is found.

class1 = class-definition-A
class2 = class-definition-B
class3 = class-definition-C

Carlos Heuberger