1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.util;
20
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Enumeration;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.concurrent.ConcurrentHashMap;
28 import java.util.concurrent.ConcurrentMap;
29 import java.util.concurrent.atomic.AtomicReference;
30
31 public class AttributesMap implements Attributes
32 {
33 private final AtomicReference<ConcurrentMap<String, Object>> _map = new AtomicReference<>();
34
35 public AttributesMap()
36 {
37 }
38
39 public AttributesMap(AttributesMap attributes)
40 {
41 ConcurrentMap<String, Object> map = attributes.map();
42 if (map != null)
43 _map.set(new ConcurrentHashMap<>(map));
44 }
45
46 private ConcurrentMap<String, Object> map()
47 {
48 return _map.get();
49 }
50
51 private ConcurrentMap<String, Object> ensureMap()
52 {
53 while (true)
54 {
55 ConcurrentMap<String, Object> map = map();
56 if (map != null)
57 return map;
58 map = new ConcurrentHashMap<>();
59 if (_map.compareAndSet(null, map))
60 return map;
61 }
62 }
63
64 @Override
65 public void removeAttribute(String name)
66 {
67 Map<String, Object> map = map();
68 if (map != null)
69 map.remove(name);
70 }
71
72 @Override
73 public void setAttribute(String name, Object attribute)
74 {
75 if (attribute == null)
76 removeAttribute(name);
77 else
78 ensureMap().put(name, attribute);
79 }
80
81 @Override
82 public Object getAttribute(String name)
83 {
84 Map<String, Object> map = map();
85 return map == null ? null : map.get(name);
86 }
87
88 @Override
89 public Enumeration<String> getAttributeNames()
90 {
91 return Collections.enumeration(getAttributeNameSet());
92 }
93
94 public Set<String> getAttributeNameSet()
95 {
96 return keySet();
97 }
98
99 public Set<Map.Entry<String, Object>> getAttributeEntrySet()
100 {
101 Map<String, Object> map = map();
102 return map == null ? Collections.<Map.Entry<String, Object>>emptySet() : map.entrySet();
103 }
104
105 public static Enumeration<String> getAttributeNamesCopy(Attributes attrs)
106 {
107 if (attrs instanceof AttributesMap)
108 return Collections.enumeration(((AttributesMap)attrs).keySet());
109
110 List<String> names = new ArrayList<>();
111 names.addAll(Collections.list(attrs.getAttributeNames()));
112 return Collections.enumeration(names);
113 }
114
115 @Override
116 public void clearAttributes()
117 {
118 Map<String, Object> map = map();
119 if (map != null)
120 map.clear();
121 }
122
123 public int size()
124 {
125 Map<String, Object> map = map();
126 return map == null ? 0 : map.size();
127 }
128
129 @Override
130 public String toString()
131 {
132 Map<String, Object> map = map();
133 return map == null ? "{}" : map.toString();
134 }
135
136 private Set<String> keySet()
137 {
138 Map<String, Object> map = map();
139 return map == null ? Collections.<String>emptySet() : map.keySet();
140 }
141
142 public void addAll(Attributes attributes)
143 {
144 Enumeration<String> e = attributes.getAttributeNames();
145 while (e.hasMoreElements())
146 {
147 String name = e.nextElement();
148 setAttribute(name, attributes.getAttribute(name));
149 }
150 }
151 }