View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.shade.resource.properties;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.Comparator;
24  import java.util.Enumeration;
25  import java.util.Iterator;
26  import java.util.LinkedHashSet;
27  import java.util.LinkedList;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Properties;
31  import java.util.Set;
32  
33  /**
34   * Internal Properties instance sorting its keys on iterations for store() usages.
35   * It ensures properties persistence is deterministic.
36   *
37   * IMPORTANT: this only overrides methods used across JVM in store() so ordering is not guaranteed for other cases.
38   */
39  public class SortedProperties extends Properties {
40      @Override
41      public Set<Map.Entry<Object, Object>> entrySet() {
42          final List<Map.Entry<Object, Object>> entries = new ArrayList<>(super.entrySet());
43          Collections.sort(entries, new Comparator<Map.Entry<Object, Object>>() {
44              @Override
45              public int compare(Map.Entry<Object, Object> o1, Map.Entry<Object, Object> o2) {
46                  return String.valueOf(o1.getKey()).compareTo(String.valueOf(o2.getKey()));
47              }
48          });
49          return new LinkedHashSet<>(entries);
50      }
51  
52      @Override
53      public synchronized Enumeration<Object> keys() // ensure it is sorted to be deterministic
54              {
55          final List<String> keys = new LinkedList<>();
56          for (Object k : super.keySet()) {
57              keys.add((String) k);
58          }
59          Collections.sort(keys);
60          final Iterator<String> it = keys.iterator();
61          return new Enumeration<Object>() {
62              @Override
63              public boolean hasMoreElements() {
64                  return it.hasNext();
65              }
66  
67              @Override
68              public Object nextElement() {
69                  return it.next();
70              }
71          };
72      }
73  }