001package fr.ifremer.adagio.synchro.intercept; 002 003/* 004 * #%L 005 * SIH-Adagio :: Synchronization 006 * $Id:$ 007 * $HeadURL:$ 008 * %% 009 * Copyright (C) 2012 - 2014 Ifremer 010 * %% 011 * This program is free software: you can redistribute it and/or modify 012 * it under the terms of the GNU Affero General Public License as published by 013 * the Free Software Foundation, either version 3 of the License, or 014 * (at your option) any later version. 015 * 016 * This program is distributed in the hope that it will be useful, 017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 019 * GNU General Public License for more details. 020 * 021 * You should have received a copy of the GNU Affero General Public License 022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 023 * #L% 024 */ 025 026import java.util.Collection; 027import java.util.List; 028import java.util.ServiceLoader; 029 030import org.hibernate.dialect.Dialect; 031import org.hibernate.tool.hbm2ddl.TableMetadata; 032 033import com.google.common.base.Predicate; 034import com.google.common.collect.Collections2; 035import com.google.common.collect.Lists; 036 037import fr.ifremer.adagio.synchro.SynchroTechnicalException; 038import fr.ifremer.adagio.synchro.meta.SynchroDatabaseMetadata; 039import fr.ifremer.adagio.synchro.service.SynchroContext; 040 041public class SynchroInterceptorUtils { 042 043 private SynchroInterceptorUtils() { 044 // helper class 045 } 046 047 public static <T, U extends SynchroInterceptor> List<U> load(Class<U> clazz, SynchroContext context) { 048 List<U> result = Lists.newArrayList(); 049 050 ServiceLoader<U> loader = ServiceLoader.load(clazz); 051 for (U interceptor : loader) { 052 // Set the current context 053 interceptor.setContext(context); 054 055 result.add(interceptor); 056 } 057 return result; 058 } 059 060 public static <T, U extends SynchroInterceptor> Collection<U> filter(List<U> interceptors, final SynchroDatabaseMetadata meta, 061 final TableMetadata table) { 062 // Retrieve overrides to apply on this table 063 Collection<U> result = Collections2.filter( 064 interceptors, 065 new Predicate<SynchroInterceptor>() { 066 public boolean apply(SynchroInterceptor interceptor) { 067 return interceptor.apply(meta, table); 068 } 069 }); 070 return result; 071 } 072 073 public static <T, U extends SynchroInterceptor> U chain(List<U> interceptors, 074 final SynchroDatabaseMetadata meta, 075 final TableMetadata table, 076 Class<? extends SynchroInterceptorChain> chainClazz) { 077 Collection<U> filteredInterceptors = filter(interceptors, meta, table); 078 079 try { 080 return (U) createChain(filteredInterceptors, chainClazz); 081 } catch (InstantiationException e) { 082 throw new SynchroTechnicalException("Could not instantiate interceptor : " + e.getMessage(), e); 083 } catch (IllegalAccessException e) { 084 throw new SynchroTechnicalException("Could not instantiate interceptor : " + e.getMessage(), e); 085 } 086 } 087 088 public static <T, U extends SynchroInterceptor, V extends SynchroInterceptorChain> U chain(Collection<U> interceptors, 089 Class<V> chainClazz) { 090 try { 091 return (U) createChain(interceptors, chainClazz); 092 } catch (InstantiationException e) { 093 throw new SynchroTechnicalException("Could not instantiate interceptor : " + e.getMessage(), e); 094 } catch (IllegalAccessException e) { 095 throw new SynchroTechnicalException("Could not instantiate interceptor : " + e.getMessage(), e); 096 } 097 } 098 099 protected static <T, U extends SynchroInterceptor> SynchroInterceptorChain createChain(Collection<U> interceptors, 100 Class<? extends SynchroInterceptorChain> chainClazz) throws InstantiationException, IllegalAccessException { 101 SynchroInterceptorChain result = null; 102 SynchroInterceptorChain previous = null; 103 for (U interceptor : interceptors) { 104 SynchroInterceptorChain newChain = null; 105 if (interceptor instanceof SynchroInterceptorChain) { 106 newChain = (SynchroInterceptorChain) interceptor; 107 } 108 else { 109 newChain = encapsulate(interceptor, chainClazz); 110 } 111 if (result == null) { 112 result = newChain; 113 } 114 else if (previous != null) { 115 previous.setNext((U) newChain); 116 } 117 previous = newChain; 118 } 119 return result; 120 } 121 122 protected static <T, U extends SynchroInterceptor> SynchroInterceptorChain encapsulate(U delegate, 123 Class<? extends SynchroInterceptorChain> chainClass) throws InstantiationException, IllegalAccessException { 124 SynchroInterceptorChain chain = (SynchroInterceptorChain) chainClass.newInstance(); 125 chain.setNext(delegate); 126 return chain; 127 } 128}