View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
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 }