Posts | Codice

07/07/09

An ordered properties file

Mi è capitato di dover salvare un file di properties “ordinato” ovvero nel quale le chiavi fossero ordinate rispetto ad un certo criterio. Poichè la classe java.util.Properties estende java.util.Hashtable<Object, Object> normalmente le properties sono memorizzate senza alcun ordinamento specifico.
In qualche caso invece, se il file ottenuto è di grandi dimensioni, può essere utile disporre di un qualche tipo di ordinamento. La soluzione è abbastanza “tricky”, pertanto la pubblico.
La seguente classe rappresenta la chiave:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * A key in the form Sn, where n is an integer number.
 *
 */
public class MessageKey implements Comparable {
 
    private Integer key;
 
    public MessageKey(final String pKey) {
        final String vKey = pKey.substring(1);
        try {
            key = Integer.valueOf(vKey);
        } catch (NumberFormatException vExc) {
            Logger.error(vExc);
        }
    }
 
    public Integer getId() {
        return key;
    }
 
    public int compareTo(final MessageKey pKey) {
        return key.compareTo(pKey.getId());
    }
 
    @Override
    public String toString() {
        return "S" + key;
    }
 
}

A questo punto occorre creare il nuovo oggetto Properties, facendo l’override del metodo keys() per ottenere, all’atto del salvataggio, il file ordinato. Il tutto senza ridefinire classi di sistema. Sono necessari alcuni passaggi per costruire una Enumeration ordinata (utilizzata nell’implementazione base della classe Properties), transitanto attraverso un Vector ed una List, riordinabile con il metodo standard Collections.sort(…). La soluzione risulta compatibile con Java5 e Java6.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
final Properties vProps = new Properties() {
    private static final long serialVersionUID = 1127046528812232390L;
 
    @Override
    public Enumeration<Object> keys() {
	// this is for key reordering...
	final Vector<MessageKey> vKeysEnum = new Vector<MessageKey>();
	for (Enumeration<Object> vEn = super.keys(); vEn.hasMoreElements();) {
	    vKeysEnum.add(new MessageKey((String) vEn.nextElement()));
	}
	final List<MessageKey> vKeysList = Collections.list(vKeysEnum.elements());
	Collections.sort(vKeysList);
 
	final Vector<Object> vOrderedKeys = new Vector<Object>();
	for (final MessageKey vKey : vKeysList) {
	    vOrderedKeys.add(vKey.toString());
	}
	return vOrderedKeys.elements();
    }
 
};
//...
vProps.setProperty("S" + vMsgKey.getId(), "something");
//...
vProps.store(...);