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 } 069 070 /** 071 * Copy constructor. 072 * 073 * @param copyFrom The bean to copy from. 074 */ 075 protected Builder(MemoryStore copyFrom) { 076 super(copyFrom); 077 type(copyFrom.getClass()); 078 } 079 080 /** 081 * Copy constructor. 082 * 083 * @param copyFrom The builder to copy from. 084 */ 085 protected Builder(Builder copyFrom) { 086 super(copyFrom); 087 } 088 089 @Override /* Context.Builder */ 090 public Builder copy() { 091 return new Builder(this); 092 } 093 094 @Override /* Context.Builder */ 095 public MemoryStore build() { 096 return build(MemoryStore.class); 097 } 098 099 //----------------------------------------------------------------------------------------------------------------- 100 // Properties 101 //----------------------------------------------------------------------------------------------------------------- 102 103 // <FluentSetters> 104 105 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 106 public Builder annotations(Annotation...values) { 107 super.annotations(values); 108 return this; 109 } 110 111 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 112 public Builder apply(AnnotationWorkList work) { 113 super.apply(work); 114 return this; 115 } 116 117 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 118 public Builder applyAnnotations(java.lang.Class<?>...fromClasses) { 119 super.applyAnnotations(fromClasses); 120 return this; 121 } 122 123 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 124 public Builder applyAnnotations(Method...fromMethods) { 125 super.applyAnnotations(fromMethods); 126 return this; 127 } 128 129 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 130 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) { 131 super.cache(value); 132 return this; 133 } 134 135 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 136 public Builder debug() { 137 super.debug(); 138 return this; 139 } 140 141 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 142 public Builder debug(boolean value) { 143 super.debug(value); 144 return this; 145 } 146 147 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 148 public Builder impl(Context value) { 149 super.impl(value); 150 return this; 151 } 152 153 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 154 public Builder type(Class<? extends org.apache.juneau.Context> value) { 155 super.type(value); 156 return this; 157 } 158 159 // </FluentSetters> 160 } 161 162 //------------------------------------------------------------------------------------------------------------------- 163 // Instance 164 //------------------------------------------------------------------------------------------------------------------- 165 166 @Override /* Context */ 167 public Builder copy() { 168 return new Builder(this); 169 } 170 171 private final ConcurrentHashMap<String,String> cache = new ConcurrentHashMap<>(); 172 173 /** 174 * Constructor. 175 * 176 * @param builder The builder for this object. 177 */ 178 public MemoryStore(Builder builder) { 179 super(builder); 180 } 181 182 @Override /* ConfigStore */ 183 public synchronized String read(String name) { 184 return emptyIfNull(cache.get(name)); 185 } 186 187 @Override /* ConfigStore */ 188 public synchronized String write(String name, String expectedContents, String newContents) { 189 190 // This is a no-op. 191 if (eq(expectedContents, newContents)) 192 return null; 193 194 String currentContents = read(name); 195 196 if (expectedContents != null && ! eq(currentContents, expectedContents)) 197 return currentContents; 198 199 update(name, newContents); 200 201 return null; 202 } 203 204 @Override /* ConfigStore */ 205 public synchronized boolean exists(String name) { 206 return cache.containsKey(name); 207 } 208 209 @Override /* ConfigStore */ 210 public synchronized MemoryStore update(String name, String newContents) { 211 if (newContents == null) 212 cache.remove(name); 213 else 214 cache.put(name, newContents); 215 super.update(name, newContents); // Trigger any listeners. 216 return this; 217 } 218 219 /** 220 * No-op. 221 */ 222 @Override /* Closeable */ 223 public void close() throws IOException { 224 // No-op 225 } 226}