1   package com.trendmicro.grid.acl.ds.jpa;
2   
3   import com.trendmicro.grid.acl.ds.Repository;
4   import com.trendmicro.grid.acl.ds.RepositorySelector;
5   import com.trendmicro.grid.acl.ds.RepositorySelectorsRepository;
6   import com.trendmicro.grid.acl.ds.SelectorAware;
7   
8   /**
9    * Is a base to classes that implement fetching inside a JPA context using another repository
10   * through the repository selector.
11   *
12   * @author juergen_kellerer, 2010-06-01
13   * @version 1.0
14   */
15  public abstract class AbstractFetcher<K, T, R extends Repository> implements SelectorAware {
16  
17  	private Class<R> repositoryClass;
18  
19  	protected String incompatibleRepositoryKey;
20  	protected RepositorySelector<R> selector;
21  
22  	protected AbstractFetcher(Class<R> repositoryClass) {
23  		this.repositoryClass = repositoryClass;
24  	}
25  
26  	protected abstract R getFallbackRepository();
27  
28  	/**
29  	 * {@inheritDoc}
30  	 */
31  	public void refreshSelectors(RepositorySelectorsRepository selectorsRepository) {
32  		selector = selectorsRepository.getSelector(repositoryClass);
33  	}
34  
35  	@SuppressWarnings("unchecked")
36  	public T fetch(K key) {
37  		if (selector != null && !selector.getSelectedKey().equals(incompatibleRepositoryKey)) {
38  			R repository = selector.getRepository();
39  			Object instance = fetch(repository, key);
40  			if (instance == null)
41  				return null;
42  			try {
43  				return (T) instance;
44  			} catch (ClassCastException e) {
45  				incompatibleRepositoryKey = selector.getSelectedKey();
46  			}
47  		}
48  
49  		return (T) fetch(getFallbackRepository(), key);
50  	}
51  
52  	protected abstract Object fetch(R repository, K key);
53  }