├── .gitignore ├── README.md ├── src └── test │ └── java │ └── javax │ └── cache │ ├── core │ ├── package-info.java │ ├── TypeSafety.java │ ├── stepbystep │ │ ├── AbstractEntryProcessor.java │ │ ├── Step1.java │ │ ├── MyCacheEntryListener.java │ │ ├── Step2.java │ │ ├── Step3.java │ │ ├── Step4.java │ │ └── SimpleExample.java │ ├── CompletionListenerExamples.java │ ├── EntryProcessorExamples.java │ ├── StatisticsExample.java │ └── CacheDemos.java │ └── optional │ ├── package-info.java │ └── CacheDemos.java ├── LICENSE.txt ├── checkstyle ├── ClassHeader.txt ├── suppressions.xml └── checkstyle.xml └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | *.iml 8 | *.idea 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Demo 2 | ==== 3 | 4 | Examples of the usage of the javax.cache API. 5 | 6 | These examples are used in the specification document. For that reason 7 | they all compile. 8 | 9 | Examples whose Class names end in Demos will in addition be executable and 10 | can be used for demos. -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2011-2013 Terracotta, Inc. 3 | * Copyright (c) 2011-2013 Oracle and/or its affiliates. 4 | * 5 | * All rights reserved. Use is subject to license terms. 6 | */ 7 | 8 | /** 9 | *

10 | * This package contains sample code for javax.cache set up as JUnit tests. 11 | *

12 | * It only uses required features of the specification. 13 | * 14 | * @author Greg Luck 15 | * @since 1.0 16 | */ 17 | package javax.cache.core; 18 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/optional/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2011-2013 Terracotta, Inc. 3 | * Copyright (c) 2011-2013 Oracle and/or its affiliates. 4 | * 5 | * All rights reserved. Use is subject to license terms. 6 | */ 7 | 8 | /** 9 | *

10 | * This package contains sample code for javax.cache set up as JUnit tests. 11 | *

12 | * It uses required and optional features of the specification. 13 | * 14 | * @author Greg Luck 15 | * @since 1.0 16 | */ 17 | package javax.cache.optional; 18 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2011-2013 Terracotta, Inc. 3 | * Copyright 2011-2013 Oracle, Inc. 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ -------------------------------------------------------------------------------- /checkstyle/ClassHeader.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2011-2013 Terracotta, Inc. 3 | * Copyright 2011-2013 Oracle America Incorporated 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/TypeSafety.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core; 2 | 3 | import org.junit.Test; 4 | 5 | import javax.cache.Cache; 6 | import javax.cache.CacheManager; 7 | import javax.cache.Caching; 8 | import javax.cache.configuration.MutableConfiguration; 9 | import javax.cache.spi.CachingProvider; 10 | 11 | /** 12 | * @author Greg Luck 13 | */ 14 | public class TypeSafety { 15 | 16 | @Test 17 | public void runtimeTypeEnforcement() { 18 | CachingProvider cachingProvider = Caching.getCachingProvider(); 19 | CacheManager cacheManager = cachingProvider.getCacheManager(); 20 | 21 | MutableConfiguration config = new 22 | MutableConfiguration<>(); 23 | config.setTypes(String.class, Integer.class); 24 | 25 | Cache simpleCache = cacheManager.createCache("simpleCache5", config); 26 | 27 | simpleCache.put("key1", 3); 28 | Integer value2 = simpleCache.get("key1"); 29 | 30 | //Shows how you might try to get around runtime+generics safety 31 | Cache secondReferenceToCache = simpleCache; 32 | 33 | try { 34 | secondReferenceToCache.put(123, "String"); 35 | } catch (ClassCastException e) { 36 | //But the RI is an implementation that performs runtime enforcement and throws 37 | //a ClassCastException. Implementations may perform runtime enforcement. 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/stepbystep/AbstractEntryProcessor.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core.stepbystep;/* 2 | * File: AbstractEntryProcessor.java 3 | * 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5 | * 6 | * The contents of this file are subject to the terms and conditions of 7 | * the Common Development and Distribution License 1.0 (the "License"). 8 | * 9 | * You may not use this file except in compliance with the License. 10 | * 11 | * You can obtain a copy of the License by consulting the LICENSE.txt file 12 | * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL 13 | * 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * 17 | * When distributing the software, include this License Header Notice in each 18 | * file and include the License file LICENSE.txt. 19 | * 20 | * MODIFICATIONS: 21 | * If applicable, add the following below the License Header, with the fields 22 | * enclosed by brackets [] replaced by your own identifying information: 23 | * "Portions Copyright [year] [name of copyright owner]" 24 | */ 25 | 26 | import javax.cache.processor.EntryProcessor; 27 | import java.io.Serializable; 28 | 29 | /** 30 | * An abstract serializable {@link javax.cache.processor.EntryProcessor}. 31 | * 32 | * @author Brian Oliver (Oracle Corporation) 33 | */ 34 | public abstract class AbstractEntryProcessor implements EntryProcessor, Serializable { 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/stepbystep/Step1.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core.stepbystep;/* 2 | * File: Step1.java 3 | * 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5 | * 6 | * The contents of this file are subject to the terms and conditions of 7 | * the Common Development and Distribution License 1.0 (the "License"). 8 | * 9 | * You may not use this file except in compliance with the License. 10 | * 11 | * You can obtain a copy of the License by consulting the LICENSE.txt file 12 | * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL 13 | * 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * 17 | * When distributing the software, include this License Header Notice in each 18 | * file and include the License file LICENSE.txt. 19 | * 20 | * MODIFICATIONS: 21 | * If applicable, add the following below the License Header, with the fields 22 | * enclosed by brackets [] replaced by your own identifying information: 23 | * "Portions Copyright [year] [name of copyright owner]" 24 | */ 25 | 26 | import javax.cache.CacheManager; 27 | import javax.cache.Caching; 28 | import javax.cache.spi.CachingProvider; 29 | 30 | /** 31 | * JCache Step 1: Acquiring a CachingProvider 32 | * 33 | * @author Brian Oliver (Oracle Corporation) 34 | */ 35 | public class Step1 { 36 | 37 | public static void main(String[] args) { 38 | // acquire the default caching provider 39 | CachingProvider provider = Caching.getCachingProvider(); 40 | 41 | // acquire the default cache manager 42 | CacheManager manager = provider.getCacheManager(); 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/optional/CacheDemos.java: -------------------------------------------------------------------------------- 1 | package javax.cache.optional; 2 | 3 | import org.junit.Test; 4 | 5 | import javax.cache.Cache; 6 | import javax.cache.CacheManager; 7 | import javax.cache.Caching; 8 | import javax.cache.configuration.MutableConfiguration; 9 | import javax.cache.expiry.AccessedExpiryPolicy; 10 | import javax.cache.spi.CachingProvider; 11 | 12 | import static javax.cache.expiry.Duration.ONE_HOUR; 13 | import static junit.framework.Assert.assertNull; 14 | import static org.junit.Assert.assertEquals; 15 | 16 | 17 | /** 18 | * 19 | * @author Greg Luck 20 | */ 21 | public class CacheDemos { 22 | 23 | 24 | @Test 25 | public void simpleAPITypeEnforcement() { 26 | 27 | //resolve a cache manager 28 | CachingProvider cachingProvider = Caching.getCachingProvider(); 29 | CacheManager cacheManager = cachingProvider.getCacheManager(); 30 | 31 | //configure the cache 32 | MutableConfiguration config = new MutableConfiguration<>(); 33 | //uses store by reference 34 | config.setStoreByValue(false) 35 | .setTypes(String.class, Integer.class) 36 | .setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(ONE_HOUR)) 37 | .setStatisticsEnabled(true); 38 | 39 | //create the cache 40 | cacheManager.createCache("simpleOptionalCache", config); 41 | 42 | //... and then later to get the cache 43 | Cache cache = Caching.getCache("simpleOptionalCache", 44 | String.class, Integer.class); 45 | 46 | //use the cache 47 | String key = "key"; 48 | Integer value1 = 1; 49 | cache.put("key", value1); 50 | Integer value2 = cache.get(key); 51 | assertEquals(value1, value2); 52 | 53 | cache.remove("key"); 54 | assertNull(cache.get("key")); 55 | } 56 | 57 | 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /checkstyle/suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/CompletionListenerExamples.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core; 2 | 3 | import javax.cache.Cache; 4 | import javax.cache.CacheManager; 5 | import javax.cache.Caching; 6 | import javax.cache.configuration.MutableConfiguration; 7 | import javax.cache.expiry.AccessedExpiryPolicy; 8 | import javax.cache.integration.CompletionListenerFuture; 9 | import javax.cache.spi.CachingProvider; 10 | import java.util.HashSet; 11 | import java.util.concurrent.ExecutionException; 12 | 13 | import static javax.cache.expiry.Duration.ONE_HOUR; 14 | 15 | /** 16 | * Examples for completino listeners 17 | * @author Greg Luck 18 | */ 19 | public class CompletionListenerExamples { 20 | 21 | 22 | public void completionListenerExample() { 23 | 24 | CachingProvider cachingProvider = Caching.getCachingProvider(); 25 | CacheManager cacheManager = cachingProvider.getCacheManager(); 26 | 27 | MutableConfiguration config = new MutableConfiguration<>(); 28 | config.setTypes(String.class, Integer.class) 29 | .setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(ONE_HOUR)) 30 | .setStatisticsEnabled(true); 31 | 32 | Cache cache = cacheManager.createCache("simpleCache", config); 33 | 34 | HashSet keys = new HashSet<>(); 35 | keys.add("23432lkj"); 36 | keys.add("4fsdldkj"); 37 | 38 | 39 | //create a completion future to use to wait for loadAll 40 | CompletionListenerFuture future = new CompletionListenerFuture(); 41 | 42 | //load the values for the set of keys, replacing those that may already 43 | //exist in the cache 44 | cache.loadAll(keys, true, future); 45 | 46 | //wait for the cache to load the keys 47 | try { 48 | future.get(); 49 | } catch (InterruptedException e) { 50 | //future interrupted 51 | e.printStackTrace(); 52 | } catch (ExecutionException e) { 53 | //throwable was what was sent to onException(Exception e) 54 | Throwable throwable = e.getCause(); 55 | } 56 | 57 | 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/EntryProcessorExamples.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core; 2 | 3 | import org.junit.Test; 4 | 5 | import javax.cache.Cache; 6 | import javax.cache.CacheManager; 7 | import javax.cache.Caching; 8 | import javax.cache.configuration.MutableConfiguration; 9 | import javax.cache.processor.EntryProcessor; 10 | import javax.cache.processor.MutableEntry; 11 | import javax.cache.spi.CachingProvider; 12 | import java.io.Serializable; 13 | 14 | /** 15 | * {@link EntryProcessor} examples. 16 | * 17 | * @author Brian Oliver 18 | */ 19 | public class EntryProcessorExamples { 20 | 21 | /** 22 | * Demonstrates incrementing a value in a {@link javax.cache.Cache} using 23 | * an {@link EntryProcessor}. 24 | */ 25 | @Test 26 | public void incrementValue() { 27 | 28 | CachingProvider provider = Caching.getCachingProvider(); 29 | CacheManager manager = provider.getCacheManager(); 30 | 31 | MutableConfiguration configuration = 32 | new MutableConfiguration() 33 | .setTypes(String.class, Integer.class); 34 | 35 | Cache cache = manager.createCache("example", configuration); 36 | 37 | String key = "counter"; 38 | cache.put(key, 1); 39 | 40 | int previous = cache.invoke(key, new IncrementProcessor()); 41 | 42 | assert previous == 1; 43 | assert cache.get(key) == 2; 44 | } 45 | 46 | /** 47 | * An {@link EntryProcessor} that increments an {@link Integer}. 48 | * 49 | * @param the type of keys 50 | */ 51 | public static class IncrementProcessor implements EntryProcessor, Serializable { 53 | 54 | /** 55 | * The serialVersionUID required for {@link java.io.Serializable}. 56 | */ 57 | public static final long serialVersionUID = 201306211238L; 58 | 59 | /** 60 | * {@inheritDoc} 61 | */ 62 | @Override 63 | public Integer process(MutableEntry entry, Object... arguments) { 64 | if (entry.exists()) { 65 | Integer current = entry.getValue(); 66 | entry.setValue(current + 1); 67 | return current; 68 | } else { 69 | entry.setValue(0); 70 | return -1; 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/stepbystep/MyCacheEntryListener.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core.stepbystep;/* 2 | * File: MyCacheEntryListener.java 3 | * 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5 | * 6 | * The contents of this file are subject to the terms and conditions of 7 | * the Common Development and Distribution License 1.0 (the "License"). 8 | * 9 | * You may not use this file except in compliance with the License. 10 | * 11 | * You can obtain a copy of the License by consulting the LICENSE.txt file 12 | * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL 13 | * 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * 17 | * When distributing the software, include this License Header Notice in each 18 | * file and include the License file LICENSE.txt. 19 | * 20 | * MODIFICATIONS: 21 | * If applicable, add the following below the License Header, with the fields 22 | * enclosed by brackets [] replaced by your own identifying information: 23 | * "Portions Copyright [year] [name of copyright owner]" 24 | */ 25 | 26 | import javax.cache.event.CacheEntryCreatedListener; 27 | import javax.cache.event.CacheEntryEvent; 28 | import javax.cache.event.CacheEntryListenerException; 29 | import javax.cache.event.CacheEntryUpdatedListener; 30 | 31 | /** 32 | * A custom cache entry listener. 33 | * 34 | * @author Brian Oliver (Oracle Corporation) 35 | */ 36 | public class MyCacheEntryListener implements CacheEntryCreatedListener, 37 | CacheEntryUpdatedListener { 38 | @Override 39 | public void onCreated(Iterable> cacheEntryEvents) 40 | throws CacheEntryListenerException { 41 | for (CacheEntryEvent entryEvent : cacheEntryEvents) { 42 | System.out.println("Created: " + entryEvent.getKey() + " with value: " + entryEvent.getValue()); 43 | } 44 | } 45 | 46 | 47 | @Override 48 | public void onUpdated(Iterable> cacheEntryEvents) 49 | throws CacheEntryListenerException { 50 | for (CacheEntryEvent entryEvent : cacheEntryEvents) { 51 | System.out.println("Updated: " + entryEvent.getKey() + " with value: " + entryEvent.getValue()); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/stepbystep/Step2.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core.stepbystep;/* 2 | * File: Step2.java 3 | * 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5 | * 6 | * The contents of this file are subject to the terms and conditions of 7 | * the Common Development and Distribution License 1.0 (the "License"). 8 | * 9 | * You may not use this file except in compliance with the License. 10 | * 11 | * You can obtain a copy of the License by consulting the LICENSE.txt file 12 | * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL 13 | * 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * 17 | * When distributing the software, include this License Header Notice in each 18 | * file and include the License file LICENSE.txt. 19 | * 20 | * MODIFICATIONS: 21 | * If applicable, add the following below the License Header, with the fields 22 | * enclosed by brackets [] replaced by your own identifying information: 23 | * "Portions Copyright [year] [name of copyright owner]" 24 | */ 25 | 26 | import javax.cache.Cache; 27 | import javax.cache.CacheManager; 28 | import javax.cache.Caching; 29 | import javax.cache.configuration.MutableConfiguration; 30 | import javax.cache.spi.CachingProvider; 31 | 32 | /** 33 | * JCache Step 2: Accessing a Cache 34 | * 35 | * @author Brian Oliver (Oracle Corporation) 36 | */ 37 | public class Step2 { 38 | public static void main(String[] args) { 39 | // acquire the default caching provider 40 | CachingProvider provider = Caching.getCachingProvider(); 41 | 42 | // acquire the default cache manager 43 | CacheManager manager = provider.getCacheManager(); 44 | 45 | // define a configuration for a cache from String to String 46 | MutableConfiguration configuration = 47 | new MutableConfiguration().setStoreByValue(true).setTypes(String.class, 48 | String.class); 49 | 50 | // create a cache 51 | Cache cache = manager.createCache("greetings2", configuration); 52 | // Cache cache = manager.getCache("greetings"); 53 | 54 | // put some values 55 | cache.put("AU", "gudday mate"); 56 | cache.put("US", "hello"); 57 | cache.put("FR", "bonjour"); 58 | 59 | // get a value 60 | System.out.println("Greeting for today: " + cache.get("AU")); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/stepbystep/Step3.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core.stepbystep;/* 2 | * File: Step3.java 3 | * 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5 | * 6 | * The contents of this file are subject to the terms and conditions of 7 | * the Common Development and Distribution License 1.0 (the "License"). 8 | * 9 | * You may not use this file except in compliance with the License. 10 | * 11 | * You can obtain a copy of the License by consulting the LICENSE.txt file 12 | * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL 13 | * 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * 17 | * When distributing the software, include this License Header Notice in each 18 | * file and include the License file LICENSE.txt. 19 | * 20 | * MODIFICATIONS: 21 | * If applicable, add the following below the License Header, with the fields 22 | * enclosed by brackets [] replaced by your own identifying information: 23 | * "Portions Copyright [year] [name of copyright owner]" 24 | */ 25 | 26 | import javax.cache.Cache; 27 | import javax.cache.CacheManager; 28 | import javax.cache.Caching; 29 | import javax.cache.configuration.MutableConfiguration; 30 | import javax.cache.processor.EntryProcessor; 31 | import javax.cache.processor.EntryProcessorException; 32 | import javax.cache.processor.MutableEntry; 33 | import javax.cache.spi.CachingProvider; 34 | 35 | /** 36 | * JCache Step 3: Mutating Entries 37 | * 38 | * @author Brian Oliver (Oracle Corporation) 39 | */ 40 | public class Step3 { 41 | public static void main(String[] args) { 42 | // acquire the default caching provider 43 | CachingProvider provider = Caching.getCachingProvider(); 44 | 45 | // acquire the default cache manager 46 | CacheManager manager = provider.getCacheManager(); 47 | 48 | // define a configuration for a cache from String to String 49 | MutableConfiguration configuration = 50 | new MutableConfiguration().setStoreByValue(true).setTypes(String.class, 51 | String.class); 52 | 53 | // create a cache 54 | Cache cache = manager.createCache("greetings", configuration); 55 | 56 | // put some values 57 | cache.put("AU", "gudday mate"); 58 | cache.put("US", "hello"); 59 | cache.put("FR", "bonjour"); 60 | 61 | // convert the entries to upper case 62 | cache.invoke("AU", new EntryProcessor() { 63 | @Override 64 | public String process(MutableEntry entry, 65 | Object... arguments) throws EntryProcessorException { 66 | if (entry.exists()) { 67 | String currentValue = entry.getValue(); 68 | 69 | entry.setValue(currentValue.toUpperCase()); 70 | 71 | return currentValue; 72 | } else { 73 | return null; 74 | } 75 | } 76 | }); 77 | 78 | // get a value 79 | System.out.println("Greeting for today: " + cache.get("AU")); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/stepbystep/Step4.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core.stepbystep;/* 2 | * File: Step4.java 3 | * 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5 | * 6 | * The contents of this file are subject to the terms and conditions of 7 | * the Common Development and Distribution License 1.0 (the "License"). 8 | * 9 | * You may not use this file except in compliance with the License. 10 | * 11 | * You can obtain a copy of the License by consulting the LICENSE.txt file 12 | * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL 13 | * 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * 17 | * When distributing the software, include this License Header Notice in each 18 | * file and include the License file LICENSE.txt. 19 | * 20 | * MODIFICATIONS: 21 | * If applicable, add the following below the License Header, with the fields 22 | * enclosed by brackets [] replaced by your own identifying information: 23 | * "Portions Copyright [year] [name of copyright owner]" 24 | */ 25 | 26 | import javax.cache.Cache; 27 | import javax.cache.CacheManager; 28 | import javax.cache.Caching; 29 | import javax.cache.configuration.CacheEntryListenerConfiguration; 30 | import javax.cache.configuration.FactoryBuilder; 31 | import javax.cache.configuration.MutableCacheEntryListenerConfiguration; 32 | import javax.cache.configuration.MutableConfiguration; 33 | import javax.cache.processor.EntryProcessor; 34 | import javax.cache.processor.EntryProcessorException; 35 | import javax.cache.processor.MutableEntry; 36 | import javax.cache.spi.CachingProvider; 37 | 38 | /** 39 | * JCache Step 4: Observing Cache Entry Events 40 | * 41 | * @author Brian Oliver (Oracle Corporation) 42 | */ 43 | public class Step4 { 44 | public static void main(String[] args) { 45 | // acquire the default caching provider 46 | CachingProvider provider = Caching.getCachingProvider(); 47 | 48 | // acquire the default cache manager 49 | CacheManager manager = provider.getCacheManager(); 50 | 51 | // define a configuration for a cache from String to String 52 | MutableConfiguration configuration = 53 | new MutableConfiguration().setStoreByValue(true).setTypes(String.class, 54 | String.class); 55 | 56 | // create a cache 57 | Cache cache = manager.createCache("greetings", configuration); 58 | 59 | // define a cache entry listener configuration 60 | CacheEntryListenerConfiguration listenerConfiguration = 61 | new MutableCacheEntryListenerConfiguration(FactoryBuilder.factoryOf(MyCacheEntryListener.class), 63 | null, 64 | false, 65 | true); 66 | 67 | cache.registerCacheEntryListener(listenerConfiguration); 68 | 69 | // put some values 70 | cache.put("AU", "gudday mate"); 71 | cache.put("US", "hello"); 72 | cache.put("FR", "bonjour"); 73 | 74 | // convert the entries to upper case 75 | cache.invoke("AU", new EntryProcessor() { 76 | @Override 77 | public String process(MutableEntry entry, 78 | Object... arguments) throws EntryProcessorException { 79 | if (entry.exists()) { 80 | entry.setValue(entry.getValue().toUpperCase()); 81 | } 82 | 83 | return null; 84 | } 85 | }); 86 | 87 | // get a value 88 | System.out.println("Greeting for today: " + cache.get("AU")); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/stepbystep/SimpleExample.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core.stepbystep;/* 2 | * File: SimpleExample.java 3 | * 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5 | * 6 | * The contents of this file are subject to the terms and conditions of 7 | * the Common Development and Distribution License 1.0 (the "License"). 8 | * 9 | * You may not use this file except in compliance with the License. 10 | * 11 | * You can obtain a copy of the License by consulting the LICENSE.txt file 12 | * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL 13 | * 14 | * See the License for the specific language governing permissions 15 | * and limitations under the License. 16 | * 17 | * When distributing the software, include this License Header Notice in each 18 | * file and include the License file LICENSE.txt. 19 | * 20 | * MODIFICATIONS: 21 | * If applicable, add the following below the License Header, with the fields 22 | * enclosed by brackets [] replaced by your own identifying information: 23 | * "Portions Copyright [year] [name of copyright owner]" 24 | */ 25 | 26 | import javax.cache.Cache; 27 | import javax.cache.CacheManager; 28 | import javax.cache.Caching; 29 | import javax.cache.configuration.CacheEntryListenerConfiguration; 30 | import javax.cache.configuration.FactoryBuilder; 31 | import javax.cache.configuration.MutableCacheEntryListenerConfiguration; 32 | import javax.cache.configuration.MutableConfiguration; 33 | import javax.cache.event.CacheEntryCreatedListener; 34 | import javax.cache.event.CacheEntryEvent; 35 | import javax.cache.event.CacheEntryListenerException; 36 | import javax.cache.event.CacheEntryUpdatedListener; 37 | import javax.cache.processor.EntryProcessorException; 38 | import javax.cache.processor.MutableEntry; 39 | import javax.cache.spi.CachingProvider; 40 | 41 | /** 42 | * A simple JCache example 43 | */ 44 | public class SimpleExample { 45 | 46 | public static void main(String[] args) { 47 | CachingProvider provider = Caching.getCachingProvider(); 48 | 49 | CacheManager manager = provider.getCacheManager(); 50 | 51 | MutableConfiguration configuration = 52 | new MutableConfiguration().setStoreByValue(false).setTypes(String.class, 53 | String.class); 54 | 55 | Cache cache = manager.createCache("my-cache", configuration); 56 | 57 | CacheEntryListenerConfiguration listenerConfiguration = 58 | new MutableCacheEntryListenerConfiguration(FactoryBuilder.factoryOf(MyCacheEntryListener.class), 60 | null, 61 | false, 62 | true); 63 | 64 | cache.registerCacheEntryListener(listenerConfiguration); 65 | 66 | cache.put("message", "hello"); 67 | cache.put("message", "g'day"); 68 | cache.put("message", "bonjour"); 69 | 70 | String result = cache.invoke("message", new AbstractEntryProcessor() { 71 | @Override 72 | public String process(MutableEntry entry, 73 | Object... arguments) throws EntryProcessorException { 74 | return entry.exists() ? entry.getValue().toUpperCase() : null; 75 | } 76 | }); 77 | 78 | System.out.println("EntryProcessor result:" + result); 79 | 80 | // cache.clear(); 81 | 82 | System.out.println(cache.get("message")); 83 | } 84 | 85 | 86 | /** 87 | * A simple cache listener example 88 | */ 89 | public static class MyCacheEntryListener implements CacheEntryCreatedListener, 90 | CacheEntryUpdatedListener { 91 | @Override 92 | public void onCreated(Iterable> cacheEntryEvents) 93 | throws CacheEntryListenerException { 94 | for (CacheEntryEvent entryEvent : cacheEntryEvents) { 95 | System.out.println("Created: " + entryEvent.getKey() + " with value: " + entryEvent.getValue()); 96 | } 97 | } 98 | 99 | 100 | @Override 101 | public void onUpdated(Iterable> cacheEntryEvents) 102 | throws CacheEntryListenerException { 103 | for (CacheEntryEvent entryEvent : cacheEntryEvents) { 104 | System.out.println("Updated: " + entryEvent.getKey() + " with value: " + entryEvent.getValue()); 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/StatisticsExample.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core; 2 | 3 | import static javax.cache.expiry.Duration.ONE_HOUR; 4 | import static org.junit.Assert.assertEquals; 5 | import static org.junit.Assert.assertTrue; 6 | 7 | import java.util.ArrayList; 8 | 9 | import javax.cache.Cache; 10 | import javax.cache.CacheManager; 11 | import javax.cache.Caching; 12 | import javax.cache.configuration.MutableConfiguration; 13 | import javax.cache.expiry.AccessedExpiryPolicy; 14 | import javax.cache.spi.CachingProvider; 15 | import javax.management.AttributeNotFoundException; 16 | import javax.management.InstanceNotFoundException; 17 | import javax.management.MBeanException; 18 | import javax.management.MBeanServer; 19 | import javax.management.MBeanServerFactory; 20 | import javax.management.MalformedObjectNameException; 21 | import javax.management.ObjectName; 22 | import javax.management.ReflectionException; 23 | 24 | import org.junit.Test; 25 | 26 | /** 27 | * Examples on retrieving cache statistics utilizing MXBeans. 28 | * @author Greg Luck 29 | * @author Dhrubajyoti Gogoi 30 | */ 31 | public class StatisticsExample { 32 | 33 | /** 34 | * Defining cache statistics parameters as constants. 35 | */ 36 | private enum CacheStatistics { 37 | CacheHits, CacheHitPercentage, 38 | CacheMisses, CacheMissPercentage, 39 | CacheGets, CachePuts, CacheRemovals, CacheEvictions, 40 | AverageGetTime, AveragePutTime, AverageRemoveTime 41 | } 42 | 43 | @Test 44 | public void accessStatistics() throws MalformedObjectNameException, 45 | AttributeNotFoundException, MBeanException, ReflectionException, 46 | InstanceNotFoundException { 47 | 48 | // resolving cache manager. 49 | CachingProvider cachingProvider = Caching.getCachingProvider(); 50 | CacheManager cacheManager = cachingProvider.getCacheManager(); 51 | 52 | // configuring cache. 53 | MutableConfiguration config = 54 | new MutableConfiguration(); 55 | config.setTypes(String.class, Integer.class) 56 | .setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(ONE_HOUR)) 57 | .setStatisticsEnabled(true); 58 | 59 | Cache cache = cacheManager.createCache("simpleCacheWithStatistics", config); 60 | 61 | // defining constants. 62 | long cacheHits = 5; 63 | long cacheMisses = 3; 64 | long cacheGets = cacheHits + cacheMisses; 65 | long cacheRemovals = 3; 66 | long cachePuts = cacheRemovals + 1; 67 | // TODO: add eviction logic. 68 | long cacheEvictions = 0; 69 | float cacheHitPercentage = (float) cacheHits / cacheGets * 100.0f; 70 | float cacheMissPercentage = (float) cacheMisses / cacheGets * 100.0f; 71 | 72 | // use the cache 73 | cache.put("valid-key", 1); 74 | for (int i = 0; i < cacheHits; i++) { cache.get("valid-key"); } 75 | for (int i = 0; i < cacheMisses; i++) { cache.get("invalid-key"); } 76 | for (int i = 0; i < cacheRemovals; i++) { cache.put("key" + i, i); } 77 | for (int i = 0; i < cacheRemovals; i++) { cache.remove("key" + i); } 78 | 79 | ArrayList mBeanServers = MBeanServerFactory.findMBeanServer(null); 80 | ObjectName objectName = new ObjectName("javax.cache:type=CacheStatistics" 81 | + ",CacheManager=" + (cache.getCacheManager().getURI().toString()) 82 | + ",Cache=" + cache.getName()); 83 | 84 | // assertions 85 | assertEquals(cacheHits, mBeanServers.get(0).getAttribute(objectName, CacheStatistics.CacheHits.toString())); 86 | assertEquals(cacheHitPercentage, mBeanServers.get(0).getAttribute(objectName, CacheStatistics.CacheHitPercentage.toString())); 87 | assertEquals(cacheMisses, mBeanServers.get(0).getAttribute(objectName, CacheStatistics.CacheMisses.toString())); 88 | assertEquals(cacheMissPercentage, mBeanServers.get(0).getAttribute(objectName, CacheStatistics.CacheMissPercentage.toString())); 89 | assertEquals(cacheGets, mBeanServers.get(0).getAttribute(objectName, CacheStatistics.CacheGets.toString())); 90 | assertEquals(cachePuts, mBeanServers.get(0).getAttribute(objectName, CacheStatistics.CachePuts.toString())); 91 | assertEquals(cacheRemovals, mBeanServers.get(0).getAttribute(objectName, CacheStatistics.CacheRemovals.toString())); 92 | assertEquals(cacheEvictions, mBeanServers.get(0).getAttribute(objectName, CacheStatistics.CacheEvictions.toString())); 93 | assertTrue((float) mBeanServers.get(0).getAttribute(objectName, CacheStatistics.AverageGetTime.toString()) > 0.0f); 94 | assertTrue((float) mBeanServers.get(0).getAttribute(objectName, CacheStatistics.AveragePutTime.toString()) > 0.0f); 95 | assertTrue((float) mBeanServers.get(0).getAttribute(objectName, CacheStatistics.AverageRemoveTime.toString()) > 0.0f); 96 | 97 | // printing retrieved cache statistics to console. 98 | for (CacheStatistics cacheStatistic : CacheStatistics.values()) { 99 | System.out.println(cacheStatistic + ": " + mBeanServers.get(0) 100 | .getAttribute(objectName, cacheStatistic.toString())); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 4.0.0 6 | javax.cache 7 | jsr107demo 8 | 1.1.2-SNAPSHOT 9 | jar 10 | 11 | jsr107demo 12 | http://maven.apache.org 13 | A simple demo of javax.cache 14 | 15 | 16 | UTF-8 17 | 18 | 19 | 20 | 21 | junit 22 | junit 23 | 4.11 24 | 25 | 26 | 27 | javax.cache 28 | cache-api 29 | ${project.version} 30 | 31 | 32 | 33 | org.jsr107.ri 34 | cache-ri-impl 35 | 1.1.2-SNAPSHOT 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-surefire-plugin 46 | 2.9 47 | 48 | 49 | **/**.java 50 | 51 | 52 | 53 | 54 | 55 | 56 | maven-compiler-plugin 57 | 2.5.1 58 | 59 | 1.7 60 | 1.7 61 | 62 | 63 | 64 | 65 | 66 | maven-install-plugin 67 | 2.4 68 | 69 | true 70 | 71 | 72 | 73 | 74 | 75 | maven-jar-plugin 76 | 2.4 77 | 78 | 79 | default-jar 80 | never 81 | 82 | unwanted 83 | unwanted 84 | 85 | 86 | 87 | 88 | 89 | 90 | com.atlassian.maven.plugins 91 | maven-clover2-plugin 92 | 3.2.0 93 | 94 | ${java.io.tmpdir}/clover/clover.db 95 | 96 | true 97 | 98 | 99 | 100 | 101 | org.apache.maven.plugins 102 | maven-checkstyle-plugin 103 | 2.10 104 | 105 | 106 | 107 | install 108 | 109 | checkstyle 110 | 111 | 112 | 113 | 114 | ${basedir}/checkstyle/checkstyle.xml 115 | 116 | ${basedir}/checkstyle/suppressions.xml 117 | 118 | ${basedir}/checkstyle/ClassHeader.txt 119 | 120 | false 121 | true 122 | true 123 | true 124 | true 125 | false 126 | true 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | The Apache Software License, Version 2.0 136 | http://www.apache.org/licenses/LICENSE-2.0.txt 137 | repo 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /src/test/java/javax/cache/core/CacheDemos.java: -------------------------------------------------------------------------------- 1 | package javax.cache.core; 2 | 3 | import org.junit.Test; 4 | 5 | import javax.cache.Cache; 6 | import javax.cache.CacheManager; 7 | import javax.cache.Caching; 8 | import javax.cache.configuration.Configuration; 9 | import javax.cache.configuration.MutableConfiguration; 10 | import javax.cache.expiry.AccessedExpiryPolicy; 11 | import javax.cache.spi.CachingProvider; 12 | 13 | import static javax.cache.expiry.Duration.ONE_HOUR; 14 | import static junit.framework.Assert.assertNull; 15 | import static org.junit.Assert.assertEquals; 16 | 17 | 18 | /** 19 | * @author Greg Luck 20 | */ 21 | public class CacheDemos { 22 | 23 | 24 | @Test 25 | public void simpleCache() { 26 | 27 | CacheManager manager = Caching.getCachingProvider().getCacheManager(); 28 | Configuration configuration = new MutableConfiguration().setTypes(Integer.class, String.class); 29 | Cache simpleCache = manager.getCache("simpleCache22"); 30 | simpleCache = manager.createCache("simpleCache22", configuration); 31 | simpleCache.put(2, "value"); 32 | String value = simpleCache.get(2); 33 | System.out.println("Value: " + value); 34 | } 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | @Test 54 | public void simpleAPITypeEnforcement() { 55 | 56 | //resolve a cache manager 57 | CachingProvider cachingProvider = Caching.getCachingProvider(); 58 | CacheManager cacheManager = cachingProvider.getCacheManager(); 59 | 60 | //configure the cache 61 | MutableConfiguration config = new MutableConfiguration<>(); 62 | config.setStoreByValue(true) 63 | .setTypes(String.class, Integer.class) 64 | .setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(ONE_HOUR)) 65 | .setStatisticsEnabled(true); 66 | 67 | //create the cache 68 | cacheManager.createCache("simpleCache", config); 69 | 70 | //... and then later to get the cache 71 | Cache cache = Caching.getCache("simpleCache", String.class, Integer.class); 72 | 73 | //use the cache 74 | String key = "key"; 75 | Integer value1 = 1; 76 | cache.put("key", value1); 77 | Integer value2 = cache.get(key); 78 | assertEquals(value1, value2); 79 | 80 | cache.remove("key"); 81 | assertNull(cache.get("key")); 82 | } 83 | 84 | 85 | @Test 86 | public void simpleAPITypeEnforcementUsingCaching() { 87 | 88 | //resolve a cache manager 89 | CachingProvider cachingProvider = Caching.getCachingProvider(); 90 | CacheManager cacheManager = cachingProvider.getCacheManager(); 91 | 92 | Number one = new Integer(1); 93 | 94 | //configure the cache 95 | MutableConfiguration config = new MutableConfiguration<>(); 96 | config.setTypes(String.class, Integer.class) 97 | .setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(ONE_HOUR)) 98 | .setStatisticsEnabled(true); 99 | 100 | //create the cache 101 | cacheManager.createCache("simpleCache2", config); 102 | 103 | //... and then later to get the cache 104 | Cache cache = Caching.getCache("simpleCache2", 105 | String.class, Integer.class); 106 | 107 | //use the cache 108 | String key = "key"; 109 | Integer value1 = 1; 110 | cache.put("key", value1); 111 | Integer value2 = cache.get(key); 112 | assertEquals(value1, value2); 113 | cache.remove("key"); 114 | assertNull(cache.get("key")); 115 | } 116 | 117 | @Test 118 | public void simpleAPIWithGenericsAndNoTypeEnforcement() { 119 | 120 | //resolve a cache manager 121 | CachingProvider cachingProvider = Caching.getCachingProvider(); 122 | CacheManager cacheManager = cachingProvider.getCacheManager(); 123 | 124 | //configure the cache 125 | String cacheName = "sampleCache3"; 126 | MutableConfiguration config = new MutableConfiguration(); 127 | config.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(ONE_HOUR)) 128 | .setStatisticsEnabled(true); 129 | 130 | //create the cache 131 | cacheManager.createCache(cacheName, config); 132 | 133 | //... and then later to get the cache 134 | Cache cache = cacheManager.getCache(cacheName); 135 | 136 | //use the cache 137 | String key = "key"; 138 | Integer value1 = 1; 139 | cache.put("key", value1); 140 | 141 | //The following line gives a compile error 142 | //cache.put(value1, "key1"); 143 | Integer value2 = (Integer) cache.get(key); 144 | 145 | cache.remove(key); 146 | assertNull(cache.get(key)); 147 | } 148 | 149 | 150 | @Test 151 | public void simpleAPINoGenericsAndNoTypeEnforcement() { 152 | 153 | //resolve a cache manager 154 | CachingProvider cachingProvider = Caching.getCachingProvider(); 155 | CacheManager cacheManager = cachingProvider.getCacheManager(); 156 | 157 | //configure the cache 158 | String cacheName = "sampleCache"; 159 | MutableConfiguration config = new MutableConfiguration(); 160 | config.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(ONE_HOUR)) 161 | .setStatisticsEnabled(true); 162 | 163 | //create the cache 164 | cacheManager.createCache(cacheName, config); 165 | 166 | //... and then later to get the cache 167 | Cache cache = cacheManager.getCache(cacheName); 168 | 169 | //use the cache 170 | String key = "key"; 171 | Integer value1 = 1; 172 | cache.put(key, value1); 173 | //wrong 174 | cache.put(value1, key); 175 | Integer value2 = (Integer) cache.get(key); 176 | assertEquals(value1, value2); 177 | 178 | cache.remove(key); 179 | assertNull(cache.get(key)); 180 | } 181 | 182 | 183 | /** 184 | * Shows the consequences of using Object, Object where you want no enforcement 185 | */ 186 | @Test 187 | public void simpleAPITypeEnforcementObject() { 188 | 189 | //resolve a cache manager 190 | CachingProvider cachingProvider = Caching.getCachingProvider(); 191 | CacheManager cacheManager = cachingProvider.getCacheManager(); 192 | 193 | //configure the cache 194 | MutableConfiguration config = new MutableConfiguration<>(); 195 | config.setTypes(Object.class, Object.class) 196 | .setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(ONE_HOUR)) 197 | .setStatisticsEnabled(true); 198 | 199 | //create the cache 200 | cacheManager.createCache("simpleCache4", config); 201 | 202 | //... and then later to get the cache 203 | Cache cache = Caching.getCache("simpleCache4", 204 | Object.class, Object.class); 205 | 206 | //use the cache 207 | String key = "key"; 208 | Integer value1 = 1; 209 | cache.put("key", value1); 210 | Object value2 = cache.get(key); 211 | assertEquals(value1, value2); 212 | 213 | cache.remove("key"); 214 | assertNull(cache.get("key")); 215 | } 216 | 217 | 218 | } 219 | -------------------------------------------------------------------------------- /checkstyle/checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 152 | 153 | 154 | 155 | 156 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | --------------------------------------------------------------------------------