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}