All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.scurrilous.circe.impl.AbstractHashProvider Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright 2014 Trevor Robinson
 * 
 * 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 com.scurrilous.circe.impl;

import java.util.EnumSet;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import com.scurrilous.circe.Hash;
import com.scurrilous.circe.HashParameters;
import com.scurrilous.circe.HashProvider;
import com.scurrilous.circe.HashSupport;
import com.scurrilous.circe.IncrementalIntHash;
import com.scurrilous.circe.IncrementalLongHash;
import com.scurrilous.circe.StatefulHash;
import com.scurrilous.circe.StatefulIntHash;
import com.scurrilous.circe.StatefulLongHash;
import com.scurrilous.circe.StatelessHash;
import com.scurrilous.circe.StatelessIntHash;
import com.scurrilous.circe.StatelessLongHash;

/**
 * Base implementation for hash function providers.
 * 
 * @param 

base supported hash parameters type */ public abstract class AbstractHashProvider

implements HashProvider { private final Class

parametersClass; /** * Constructs a new {@link AbstractHashProvider} with the given base * parameters class. * * @param parametersClass the base hash parameters class supported */ protected AbstractHashProvider(Class

parametersClass) { this.parametersClass = parametersClass; } @Override public final EnumSet querySupport(HashParameters params) { if (!parametersClass.isAssignableFrom(params.getClass())) return EnumSet.noneOf(HashSupport.class); return querySupportTyped(parametersClass.cast(params)); } /** * Implemented by subclasses to provide information about the available * implementations corresponding to the given hash algorithm parameters. * Called by {@link #querySupport} if the hash parameters match the base * type supported by this provider. * * @param params the hash algorithm parameters * @return a set of flags indicating the level of support */ protected abstract EnumSet querySupportTyped(P params); /** * Requests a hash function using the given parameters and support flags. * This method is only responsible for checking support flags returned by * {@link #querySupportTyped}. *

* To support caching of stateless hash functions, call * {@link #getCacheable} from this method and implement * {@link #createCacheable}. * * @param params the hash algorithm parameters * @param required the required hash support flags * @return a hash function * @throws UnsupportedOperationException if this provider cannot support the * given parameters */ protected abstract Hash get(P params, EnumSet required); /** * Called by implementations that support caching of stateless hash * functions when a cached instance is desired. If a cached instance is not * available, this method calls {@link #createCacheable} to create one, * which is then cached (if caching is available). * * @param params the hash algorithm parameters * @param required the required hash support flags * @return a hash function * @throws UnsupportedOperationException if this provider cannot support the * given parameters */ protected final Hash getCacheable(final P params, final EnumSet required) { if (HashCacheLoader.hasCache()) { final HashCache cache = HashCacheLoader.getCache(); try { return cache.get(params, required, new Callable() { @Override public Hash call() throws Exception { return createCacheable(params, required); } }); } catch (ExecutionException e) { final Throwable cause = e.getCause(); if (cause instanceof RuntimeException) throw (RuntimeException) cause; throw new UnsupportedOperationException(e); } } return createCacheable(params, required); } /** * Called by {@link #getCacheable} to create new cacheable stateless hash * functions. The default implementation simply throws * {@link UnsupportedOperationException}. * * @param params the hash algorithm parameters * @param required the required hash support flags * @return a stateless hash function * @throws UnsupportedOperationException if this provider cannot support the * given parameters */ protected StatelessHash createCacheable(P params, EnumSet required) { throw new UnsupportedOperationException(); } private Hash castAndGet(HashParameters params, EnumSet required) { if (!parametersClass.isAssignableFrom(params.getClass())) throw new UnsupportedOperationException(); return get(parametersClass.cast(params), required); } @Override public StatefulHash createStateful(HashParameters params) { final Hash hash = castAndGet(params, EnumSet.of(HashSupport.STATEFUL)); if (hash instanceof StatefulHash) return (StatefulHash) hash; if (hash instanceof StatelessHash) return ((StatelessHash) hash).createStateful(); throw new UnsupportedOperationException(); } @Override public StatelessIntHash getStatelessInt(HashParameters params) { final Hash hash = castAndGet(params, EnumSet.of(HashSupport.INT_SIZED)); if (hash instanceof StatelessIntHash) return (StatelessIntHash) hash; if (hash instanceof StatefulIntHash) return ((StatefulIntHash) hash).asStateless(); throw new UnsupportedOperationException(); } @Override public StatelessLongHash getStatelessLong(HashParameters params) { final Hash hash = castAndGet(params, EnumSet.of(HashSupport.LONG_SIZED)); if (hash instanceof StatelessLongHash) return (StatelessLongHash) hash; if (hash instanceof StatefulLongHash) return ((StatefulLongHash) hash).asStateless(); if (hash instanceof StatelessIntHash) return new IntStatelessLongHash((StatelessIntHash) hash); if (hash instanceof StatefulIntHash) return new IntStatelessLongHash(((StatefulIntHash) hash).asStateless()); throw new UnsupportedOperationException(); } @Override public IncrementalIntHash getIncrementalInt(HashParameters params) { final Hash hash = castAndGet(params, EnumSet.of(HashSupport.INT_SIZED, HashSupport.STATELESS_INCREMENTAL)); if (hash instanceof IncrementalIntHash) return (IncrementalIntHash) hash; throw new UnsupportedOperationException(); } @Override public IncrementalLongHash getIncrementalLong(HashParameters params) { final Hash hash = castAndGet(params, EnumSet.of(HashSupport.LONG_SIZED, HashSupport.STATELESS_INCREMENTAL)); if (hash instanceof IncrementalLongHash) return (IncrementalLongHash) hash; throw new UnsupportedOperationException(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy