Java tutorial
/* * Copyright 2012 The Decanter Project * * The Decanter Project licenses this file to you 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 com.eincs.decanter.container.simple.route; import java.util.List; import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import com.eincs.decanter.message.DecanterRequest; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; /** * @author Jung-Haeng Lee */ public class SimpleRouter implements Router { private final LoadingCache<SimpleRouteServiceId, RouteResult> resultCache; private Multimap<SimpleRouteServiceId, SimpleRouteService> services; public SimpleRouter() { resultCache = CacheBuilder.newBuilder().build(new SimpleRouterCacheLoader()); services = ArrayListMultimap.create(); } @Override public RouteResult route(DecanterRequest request) throws RouteException { SimpleRouteServiceId serviceId = SimpleRouteServiceId.create(request); try { if (services.containsKey(serviceId)) { return resultCache.get(serviceId); } else { // return empty result directly when there is no possibility of // cache hit (no negative caching) return SimpleRouteResult.EMPTY_RESULT; } } catch (ExecutionException e) { throw new RouteException(e); } } @Override public void add(Object serviceObj) throws RouteReflectException { Multimap<SimpleRouteServiceId, SimpleRouteService> newServices = SimpleRouteService .createServices(serviceObj); services.putAll(newServices); resultCache.invalidateAll(); } @Override public void remove(Object serviceObj) throws RouteReflectException { Multimap<SimpleRouteServiceId, SimpleRouteService> newServices = SimpleRouteService .createServices(serviceObj); for (Entry<SimpleRouteServiceId, SimpleRouteService> entry : newServices.entries()) { services.remove(entry.getKey(), entry.getValue()); } resultCache.invalidateAll(); } @Override public void clear() { services.clear(); } /** * @author Jung-Haeng Lee */ private class SimpleRouterCacheLoader extends CacheLoader<SimpleRouteServiceId, RouteResult> { @Override public RouteResult load(SimpleRouteServiceId key) throws Exception { List<RouteService> resultServices = Lists.newArrayList(); resultServices.addAll(services.get(key)); SimpleRouteResult result = new SimpleRouteResult(resultServices); return result; } } }