View Javadoc
1   package fr.ifremer.quadrige3.synchro.intercept;
2   
3   /*-
4    * #%L
5    * Quadrige3 Core :: Quadrige3 Synchro Core
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import com.google.common.collect.ImmutableSet;
27  import fr.ifremer.common.synchro.intercept.SynchroInterceptorBase;
28  import fr.ifremer.common.synchro.meta.SynchroDatabaseMetadata;
29  import fr.ifremer.common.synchro.service.SynchroDatabaseConfiguration;
30  import fr.ifremer.quadrige3.core.dao.technical.Assert;
31  import fr.ifremer.quadrige3.synchro.service.AbstractSynchroDatabaseConfiguration;
32  import fr.ifremer.quadrige3.synchro.service.SynchroDirection;
33  import org.hibernate.tool.hbm2ddl.TableMetadata;
34  
35  import java.util.Arrays;
36  import java.util.Set;
37  import java.util.stream.Collectors;
38  
39  /**
40   * <p>
41   * Abstract AbstractSynchroInterceptor class.
42   * </p>
43   * 
44   */
45  public abstract class AbstractSynchroInterceptor<T extends AbstractSynchroDatabaseConfiguration> extends SynchroInterceptorBase {
46  
47  	private SynchroDatabaseMetadata meta;
48  	private Integer userId;
49  	private Set<SynchroDirection> allowDirections;
50  	private Set<String> allowTables;
51  
52  	/**
53  	 * <p>
54  	 * Constructor for AbstractSynchroInterceptor.
55  	 * </p>
56  	 */
57  	public AbstractSynchroInterceptor() {
58  		// All direction are allowed
59  		this.allowDirections = null;
60  		// All table are allowed
61  		this.allowTables = null;
62  	}
63  
64  	/**
65  	 * <p>
66  	 * Constructor for AbstractSynchroInterceptor.
67  	 * </p>
68  	 * 
69  	 * @param directions
70  	 *            a {@link fr.ifremer.quadrige3.synchro.service.SynchroDirection} object.
71  	 */
72  	public AbstractSynchroInterceptor(SynchroDirection... directions) {
73  		Assert.notEmpty(directions);
74  
75  		// Fill allowed directions
76  		this.allowDirections = ImmutableSet.copyOf(directions);
77  		// All table are allowed
78  		this.allowTables = null;
79  	}
80  
81  	/**
82  	 * <p>
83  	 * Constructor for AbstractSynchroInterceptor.
84  	 * </p>
85  	 * 
86  	 * @param tableIncludes
87  	 *            a {@link java.util.Set} object.
88  	 * @param directions
89  	 *            a {@link fr.ifremer.quadrige3.synchro.service.SynchroDirection} object.
90  	 */
91  	public AbstractSynchroInterceptor(Set<String> tableIncludes, SynchroDirection... directions) {
92  		Assert.notEmpty(tableIncludes);
93  		Assert.notEmpty(directions);
94  
95  		this.allowTables = ImmutableSet.copyOf(tableIncludes.stream().map(String::toUpperCase).collect(Collectors.toSet()));
96  
97  		// Fill allowed directions
98  		this.allowDirections = ImmutableSet.copyOf(directions);
99  	}
100 
101 	/**
102 	 * <p>
103 	 * Constructor for AbstractSynchroInterceptor.
104 	 * </p>
105 	 * 
106 	 * @param tableIncludes
107 	 *            a {@link java.util.Set} object.
108 	 */
109 	public AbstractSynchroInterceptor(Set<String> tableIncludes) {
110 		Assert.notEmpty(tableIncludes);
111 
112 		this.allowTables = ImmutableSet.copyOf(tableIncludes.stream().map(String::toUpperCase).collect(Collectors.toSet()));
113 
114 		// All direction are allowed
115 		this.allowDirections = null;
116 	}
117 
118 	/** {@inheritDoc} */
119 	@Override
120 	public SynchroInterceptorBase clone() {
121 		AbstractSynchroInterceptor result = (AbstractSynchroInterceptor) super.clone();
122 		result.meta = this.meta;
123 		result.userId = this.userId;
124 		result.allowDirections = allowDirections;
125 		result.allowTables = allowTables;
126 		return result;
127 	}
128 
129 	/** {@inheritDoc} */
130 	@SuppressWarnings("unchecked")
131 	@Override
132 	public final boolean apply(SynchroDatabaseConfiguration config) {
133 		boolean result = getConfigClass().isInstance(config)
134 				/* super is need to store the config into a field */
135 				&& super.apply(config);
136 
137 		if (result) {
138 			// Init the interceptor
139 			init((T) config);
140 		}
141 		return result;
142 	}
143 
144 	/**
145 	 * <p>
146 	 * getConfigClass.
147 	 * </p>
148 	 * 
149 	 * @return a {@link java.lang.Class} object.
150 	 */
151 	protected abstract Class<T> getConfigClass();
152 
153 	/** {@inheritDoc} */
154 	@Override
155 	public final boolean apply(SynchroDatabaseMetadata meta, TableMetadata table) {
156 		Assert.notNull(meta);
157 		if (this.meta != null) {
158 			Assert.state(this.meta == meta, "this metadata should be the same as previous");
159 		}
160 
161 		// Store meta and configuration
162 		else {
163 			this.meta = meta;
164 
165 			// Retrieve the user id
166 			userId = getConfig().getUserId();
167 		}
168 
169 		return (allowDirections == null || allowDirections.contains(getConfig().getDirection()))
170 				&& (allowTables == null || allowTables.contains(table.getName().toUpperCase()))
171 				&& doApply(meta, table);
172 	}
173 
174 	/**
175 	 * <p>
176 	 * doApply.
177 	 * </p>
178 	 * 
179 	 * @param meta
180 	 *            a {@link fr.ifremer.common.synchro.meta.SynchroDatabaseMetadata} object.
181 	 * @param table
182 	 *            a {@link org.hibernate.tool.hbm2ddl.TableMetadata} object.
183 	 * @return a boolean.
184 	 */
185 	public abstract boolean doApply(SynchroDatabaseMetadata meta, TableMetadata table);
186 
187 	/**
188 	 * <p>
189 	 * checkAndGetUserId.
190 	 * </p>
191 	 * 
192 	 * @return a int.
193 	 */
194 	public int checkAndGetUserId() {
195 		Assert.notNull(
196 						userId,
197 						String.format(
198 								"Could not retrieve user id (in database configuration). %s need a not null userId.",
199 								getClass().getSimpleName()
200 								));
201 		return userId;
202 	}
203 
204 	/* -- delegate methods -- */
205 
206 	/**
207 	 * <p>
208 	 * getConfig.
209 	 * </p>
210 	 * 
211 	 * @return a T object.
212 	 */
213 	@SuppressWarnings("unchecked")
214 	public T getConfig() {
215 		return (T) getDefaultDatabaseConfiguration();
216 	}
217 
218 	/* -- internal methods -- */
219 
220 	/**
221 	 * <p>
222 	 * init.
223 	 * </p>
224 	 * 
225 	 * @param config
226 	 *            a T object.
227 	 */
228 	protected void init(T config) {
229 		// could be override
230 	}
231 
232 	/**
233 	 * <p>
234 	 * isInDirections.
235 	 * </p>
236 	 * 
237 	 * @param allowDirections
238 	 *            a {@link fr.ifremer.quadrige3.synchro.service.SynchroDirection} object.
239 	 * @return a boolean.
240 	 */
241 	protected boolean isInDirections(SynchroDirection... allowDirections) {
242 		return Arrays.asList(allowDirections).contains(getConfig().getDirection());
243 	}
244 }