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