001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2019 microBean™.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
014 * implied.  See the License for the specific language governing
015 * permissions and limitations under the License.
016 */
017package org.microbean.jersey.netty;
018
019import java.util.Collection;
020import java.util.Collections;
021import java.util.HashMap;
022import java.util.Map;
023
024import org.glassfish.jersey.internal.PropertiesDelegate;
025
026/**
027 * A simple {@link PropertiesDelegate} built around a {@link Map}.
028 *
029 * <h2>Thread Safety</h2>
030 *
031 * <p>Instances of this class are <strong>not</strong> safe for
032 * concurrent use by multiple threads.</p>
033 *
034 * @author <a href="https://about.me/lairdnelson"
035 * target="_parent">Laird Nelson</a>
036 *
037 * @see PropertiesDelegate
038 */
039public class MapBackedPropertiesDelegate implements PropertiesDelegate {
040
041
042  /*
043   * Static fields.
044   */
045
046  
047  private static final Collection<String> EMPTY_STRING_SET = Collections.emptySet();
048  
049
050  /*
051   * Instance fields.
052   */
053
054  
055  private Map<String, Object> map;
056
057
058  /*
059   * Constructors.
060   */
061  
062
063  /**
064   * Creates a new {@link MapBackedPropertiesDelegate}.
065   *
066   * @see #MapBackedPropertiesDelegate(Map)
067   */
068  public MapBackedPropertiesDelegate() {
069    this(null);
070  }
071
072  /**
073   * Creates a new {@link MapBackedPropertiesDelegate}.
074   *
075   * @param map the {@link Map} implementing this {@link
076   * MapBackedPropertiesDelegate}; may be {@code null} in which case a
077   * {@linkplain HashMap#HashMap() new} {@link HashMap} will be used
078   * instead; accessed by reference
079   */
080  public MapBackedPropertiesDelegate(final Map<String, Object> map) {
081    super();
082    this.map = map;
083  }
084
085  /**
086   * Returns the property value indexed under the supplied {@code
087   * name}, or {@code null} if the property value is itself {@code
088   * null} or if no such property exists.
089   *
090   * <p>This method may return {@code null}.</p>
091   *
092   * @param name the name of the property; may be {@code null}
093   *
094   * @return the property value, or {@code null}
095   */
096  @Override
097  public final Object getProperty(final String name) {
098    final Map<String, Object> map = this.map;
099    final Object returnValue;
100    if (map == null) {
101      returnValue = null;
102    } else {
103      returnValue = map.get(name);
104    }
105    return returnValue;
106  }
107
108  /**
109   * Returns a {@link Collection} of the names of properties that this
110   * {@link MapBackedPropertiesDelegate} stores.
111   *
112   * <p>This method never returns {@code null}.</p>
113   *
114   * <p>The order of the elements of the returned {@link Collection}
115   * is deliberately unspecified, is subject to change, and must not
116   * be relied upon.</p>
117   *
118   * @return a non-{@code null} {@link Collection} of property names
119   */
120  @Override
121  public final Collection<String> getPropertyNames() {
122    final Map<String, Object> map = this.map;
123    final Collection<String> returnValue;
124    if (map == null || map.isEmpty()) {
125      returnValue = EMPTY_STRING_SET;
126    } else {
127      returnValue = map.keySet();
128    }
129    return returnValue;
130  }
131
132  /**
133   * Sets the supplied {@code value} as the property value to be
134   * indexed under the supplied {@code name}.
135   *
136   * @param name the name of the property to set; may be {@code null}
137   *
138   * @param value the value of the property to set; may be {@code
139   * null}
140   */
141  @Override
142  public final void setProperty(final String name, final Object value) {
143    Map<String, Object> map = this.map;
144    if (map == null) {
145      map = new HashMap<>();
146      this.map = map;
147    }
148    map.put(name, value);
149  }
150
151  /**
152   * Removes any property value indexed under the supplied property
153   * name.
154   *
155   * @param name the name of the property to remove; may be {@code
156   * null}
157   */
158  @Override
159  public final void removeProperty(final String name) {
160    final Map<String, Object> map = this.map;
161    if (map != null) {
162      map.remove(name);
163    }
164  }
165  
166}