001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. 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 implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.config.store; 018 019import static org.apache.juneau.common.utils.Utils.*; 020 021import java.io.*; 022import java.lang.annotation.*; 023import java.util.concurrent.*; 024 025import org.apache.juneau.*; 026import org.apache.juneau.internal.*; 027import org.apache.juneau.utils.*; 028 029/** 030 * Filesystem-based storage location for configuration files. 031 * 032 * <p> 033 * Points to a file system directory containing configuration files. 034 * 035 * <h5 class='section'>Notes:</h5><ul> 036 * <li class='note'>This class is thread safe and reusable. 037 * </ul> 038 */ 039public class MemoryStore extends ConfigStore { 040 041 //------------------------------------------------------------------------------------------------------------------- 042 // Static 043 //------------------------------------------------------------------------------------------------------------------- 044 045 /** Default memory store, all default values.*/ 046 public static final MemoryStore DEFAULT = MemoryStore.create().build(); 047 048 /** 049 * Creates a new builder for this object. 050 * 051 * @return A new builder. 052 */ 053 public static Builder create() { 054 return new Builder(); 055 } 056 057 //------------------------------------------------------------------------------------------------------------------- 058 // Builder 059 //------------------------------------------------------------------------------------------------------------------- 060 061 /** 062 * Builder class. 063 */ 064 public static class Builder extends ConfigStore.Builder { 065 066 /** 067 * Constructor, default settings. 068 */ 069 protected Builder() { 070 } 071 072 /** 073 * Copy constructor. 074 * 075 * @param copyFrom The bean to copy from. 076 */ 077 protected Builder(MemoryStore copyFrom) { 078 super(copyFrom); 079 type(copyFrom.getClass()); 080 } 081 082 /** 083 * Copy constructor. 084 * 085 * @param copyFrom The builder to copy from. 086 */ 087 protected Builder(Builder copyFrom) { 088 super(copyFrom); 089 } 090 091 @Override /* Context.Builder */ 092 public Builder copy() { 093 return new Builder(this); 094 } 095 096 @Override /* Context.Builder */ 097 public MemoryStore build() { 098 return build(MemoryStore.class); 099 } 100 101 //----------------------------------------------------------------------------------------------------------------- 102 // Properties 103 //----------------------------------------------------------------------------------------------------------------- 104 @Override /* Overridden from Builder */ 105 public Builder annotations(Annotation...values) { 106 super.annotations(values); 107 return this; 108 } 109 110 @Override /* Overridden from Builder */ 111 public Builder apply(AnnotationWorkList work) { 112 super.apply(work); 113 return this; 114 } 115 116 @Override /* Overridden from Builder */ 117 public Builder applyAnnotations(Object...from) { 118 super.applyAnnotations(from); 119 return this; 120 } 121 122 @Override /* Overridden from Builder */ 123 public Builder applyAnnotations(Class<?>...from) { 124 super.applyAnnotations(from); 125 return this; 126 } 127 128 @Override /* Overridden from Builder */ 129 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) { 130 super.cache(value); 131 return this; 132 } 133 134 @Override /* Overridden from Builder */ 135 public Builder debug() { 136 super.debug(); 137 return this; 138 } 139 140 @Override /* Overridden from Builder */ 141 public Builder debug(boolean value) { 142 super.debug(value); 143 return this; 144 } 145 146 @Override /* Overridden from Builder */ 147 public Builder impl(Context value) { 148 super.impl(value); 149 return this; 150 } 151 152 @Override /* Overridden from Builder */ 153 public Builder type(Class<? extends org.apache.juneau.Context> value) { 154 super.type(value); 155 return this; 156 } 157 } 158 159 //------------------------------------------------------------------------------------------------------------------- 160 // Instance 161 //------------------------------------------------------------------------------------------------------------------- 162 163 @Override /* Context */ 164 public Builder copy() { 165 return new Builder(this); 166 } 167 168 private final ConcurrentHashMap<String,String> cache = new ConcurrentHashMap<>(); 169 170 /** 171 * Constructor. 172 * 173 * @param builder The builder for this object. 174 */ 175 public MemoryStore(Builder builder) { 176 super(builder); 177 } 178 179 @Override /* ConfigStore */ 180 public synchronized String read(String name) { 181 return emptyIfNull(cache.get(name)); 182 } 183 184 @Override /* ConfigStore */ 185 public synchronized String write(String name, String expectedContents, String newContents) { 186 187 // This is a no-op. 188 if (eq(expectedContents, newContents)) 189 return null; 190 191 var currentContents = read(name); 192 193 if (expectedContents != null && ! eq(currentContents, expectedContents)) 194 return currentContents; 195 196 update(name, newContents); 197 198 return null; 199 } 200 201 @Override /* ConfigStore */ 202 public synchronized boolean exists(String name) { 203 return cache.containsKey(name); 204 } 205 206 @Override /* ConfigStore */ 207 public synchronized MemoryStore update(String name, String newContents) { 208 if (newContents == null) 209 cache.remove(name); 210 else 211 cache.put(name, newContents); 212 super.update(name, newContents); // Trigger any listeners. 213 return this; 214 } 215 216 /** 217 * No-op. 218 */ 219 @Override /* Closeable */ 220 public void close() throws IOException { 221 // No-op 222 } 223}