/** * Copyright 2011-2013 Terracotta, Inc. * Copyright 2011-2013 Oracle, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jsr107.tck.integration; import org.jsr107.tck.support.CacheClient; import org.jsr107.tck.support.Operation; import org.jsr107.tck.support.Server; import javax.cache.Cache; import javax.cache.integration.CacheLoader; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.InetAddress; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; /** * A {@link CacheLoader} that delegates requests to a {@link CacheLoaderServer}. * * @param <K> the type of keys * @param <V> the type of values * @author Brian Oliver */ public class CacheLoaderClient<K, V> extends CacheClient implements CacheLoader<K, V> { private CacheLoaderServer<K,V> directServer; /** * Constructs a {@link CacheLoaderClient}. * * @param address the {@link InetAddress} on which to connect to the {@link CacheLoaderServer} * @param port the port to which to connect to the {@link CacheLoaderServer} */ public CacheLoaderClient(InetAddress address, int port) { super(address, port); } @Override protected boolean checkDirectCallsPossible() { Server server = Server.lookupServerAtLocalMachine(port); if (server != null) { directServer = (CacheLoaderServer) server; return true; } return false; } @Override public V load(final K key) { if (isDirectCallable()) { return directServer.getCacheLoader().load(key); } return getClient().invoke(new LoadOperation<K, V>(key)); } /** * {@inheritDoc} */ @Override public Map<K, V> loadAll(Iterable<? extends K> keys) { if (isDirectCallable()) { return directServer.getCacheLoader().loadAll(keys); } return getClient().invoke(new LoadAllOperation<K, V>(keys)); } /** * The {@link LoadOperation} representing a {@link CacheLoader#load(Object)} * request. * * @param <K> the type of keys * @param <V> the type of values */ private static class LoadOperation<K, V> implements Operation<V> { /** * The key to load. */ private K key; /** * Constructs a {@link LoadOperation}. * * @param key the Key to load */ public LoadOperation(K key) { this.key = key; } /** * {@inheritDoc} */ @Override public String getType() { return "load"; } /** * {@inheritDoc} */ @Override public V onInvoke(ObjectInputStream ois, ObjectOutputStream oos) throws IOException, ClassNotFoundException { oos.writeObject(key); Object o = ois.readObject(); if (o instanceof RuntimeException) { throw (RuntimeException) o; } else { return (V) o; } } } /** * The {@link LoadAllOperation} representing a {@link Cache#loadAll(java.util.Set, boolean, javax.cache.integration.CompletionListener)} * request. * * @param <K> the type of keys * @param <V> the type of values */ private static class LoadAllOperation<K, V> implements Operation<Map<K, V>> { /** * The keys to load. */ private Iterable<? extends K> keys; /** * Constructs a {@link LoadAllOperation}. * * @param keys the keys to load */ public LoadAllOperation(Iterable<? extends K> keys) { this.keys = keys; } /** * {@inheritDoc} */ @Override public String getType() { return "loadAll"; } /** * {@inheritDoc} */ @Override public Map<K, V> onInvoke(ObjectInputStream ois, ObjectOutputStream oos) throws IOException, ClassNotFoundException, ExecutionException { //send the keys to load for(K key : keys) { oos.writeObject(key); } oos.writeObject(null); //read the resulting map HashMap<K, V> map = new HashMap<K, V>(); Object result = ois.readObject(); while (result != null && !(result instanceof Exception)) { K key = (K)result; V value = (V) ois.readObject(); map.put(key, value); result = ois.readObject(); } if (result instanceof RuntimeException) { throw (RuntimeException)result; } else { return map; } } } }