View Javadoc
1   package fr.ifremer.quadrige3.synchro.intercept.referential;
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.meta.SynchroDatabaseMetadata;
28  import fr.ifremer.common.synchro.meta.SynchroMetadataUtils;
29  import fr.ifremer.common.synchro.meta.SynchroTableMetadata;
30  import fr.ifremer.quadrige3.synchro.intercept.AbstractSynchroInterceptor;
31  import fr.ifremer.quadrige3.synchro.service.SynchroDirection;
32  import fr.ifremer.quadrige3.synchro.service.referential.ReferentialSynchroDatabaseConfiguration;
33  import org.apache.commons.collections4.CollectionUtils;
34  import org.hibernate.tool.hbm2ddl.TableMetadata;
35  
36  import java.util.Collection;
37  import java.util.Set;
38  
39  /**
40   * Abstract interceptor, for synchronization on referential tables
41   * 
42   * @author Benoit Lavenier <benoit.lavenier@e-is.pro>
43   * @since 1.0
44   */
45  public abstract class AbstractReferentialInterceptor extends AbstractSynchroInterceptor<ReferentialSynchroDatabaseConfiguration> {
46  
47  	/**
48  	 * <p>
49  	 * Constructor for AbstractReferentialInterceptor.
50  	 * </p>
51  	 */
52  	public AbstractReferentialInterceptor() {
53  		super();
54  	}
55  
56  	/**
57  	 * <p>
58  	 * Constructor for AbstractReferentialInterceptor.
59  	 * </p>
60  	 * 
61  	 * @param directions
62  	 *            a {@link fr.ifremer.quadrige3.synchro.service.SynchroDirection} object.
63  	 */
64  	public AbstractReferentialInterceptor(SynchroDirection... directions) {
65  		super(directions);
66  	}
67  
68  	/**
69  	 * <p>
70  	 * Constructor for AbstractReferentialInterceptor.
71  	 * </p>
72  	 * 
73  	 * @param tables
74  	 *            a {@link java.util.Set} object.
75  	 * @param directions
76  	 *            a {@link fr.ifremer.quadrige3.synchro.service.SynchroDirection} object.
77  	 */
78  	public AbstractReferentialInterceptor(Set<String> tables, SynchroDirection... directions) {
79  		super(tables, directions);
80  	}
81  
82  	/**
83  	 * <p>
84  	 * Constructor for AbstractReferentialInterceptor.
85  	 * </p>
86  	 * 
87  	 * @param tables
88  	 *            a {@link java.util.Set} object.
89  	 */
90  	public AbstractReferentialInterceptor(Set<String> tables) {
91  		super(tables);
92  	}
93  
94  	/**
95  	 * <p>
96  	 * Constructor for AbstractReferentialInterceptor.
97  	 * </p>
98  	 * 
99  	 * @param tableName
100 	 *            a {@link java.lang.String} object.
101 	 * @param directions
102 	 *            a {@link fr.ifremer.quadrige3.synchro.service.SynchroDirection} object.
103 	 */
104 	public AbstractReferentialInterceptor(String tableName, SynchroDirection... directions) {
105 		this(ImmutableSet.of(tableName), directions);
106 	}
107 
108 	/**
109 	 * <p>
110 	 * Constructor for AbstractReferentialInterceptor.
111 	 * </p>
112 	 * 
113 	 * @param tableName
114 	 *            a {@link java.lang.String} object.
115 	 */
116 	public AbstractReferentialInterceptor(String tableName) {
117 		this(ImmutableSet.of(tableName));
118 	}
119 
120 	/** {@inheritDoc} */
121 	@Override
122 	protected Class<ReferentialSynchroDatabaseConfiguration> getConfigClass() {
123 		return ReferentialSynchroDatabaseConfiguration.class;
124 	}
125 
126 	/** {@inheritDoc} */
127 	@Override
128 	public boolean doApply(SynchroDatabaseMetadata meta, TableMetadata table) {
129 		return true;
130 	}
131 
132 	/* -- internal methods -- */
133 
134 	/**
135 	 * <p>
136 	 * hasStatusCodesIncludes.
137 	 * </p>
138 	 * 
139 	 * @return a boolean.
140 	 */
141 	protected boolean hasStatusCodesIncludes() {
142 		return CollectionUtils.isNotEmpty(getConfig().getStatusCodeIncludes());
143 	}
144 
145 	/**
146 	 * <p>
147 	 * createPkFilter.
148 	 * </p>
149 	 * 
150 	 * @param table
151 	 *            a {@link fr.ifremer.common.synchro.meta.SynchroTableMetadata} object.
152 	 * @return a {@link java.lang.String} object.
153 	 */
154 	protected String createPkFilter(SynchroTableMetadata table) {
155 		if (getConfig().getPkIncludes() == null
156 				|| getConfig().getPkIncludes().isEmpty()) {
157 			return null;
158 		}
159 
160 		// If more than ONE pk : exit
161 		if (table.getPkNames().size() != 1) {
162 			return null;
163 		}
164 
165 		String pkName = table.getPkNames().iterator().next();
166 
167 		Collection<String> pkStrs = getConfig()
168 				.getPkIncludes()
169 				.get(table.getName().toUpperCase());
170 
171 		if (org.apache.commons.collections.CollectionUtils.isEmpty(pkStrs)) {
172 			// There is filter by PK, but not on this table
173 			// so exclude this table
174 			return "1=2";
175 		}
176 
177 		boolean isNumericPk = SynchroMetadataUtils.isNumericType(table.getColumnMetadata(pkName));
178 
179 		StringBuilder inBuilder = new StringBuilder();
180 		if (isNumericPk) {
181 			for (String pkStr : pkStrs) {
182 				inBuilder.append(',').append(pkStr);
183 			}
184 			return String.format("t.%s IN (%s)",
185 					pkName,
186 					inBuilder.substring(1)
187 					);
188 		}
189 
190 		// Alphanumerical : protect characters
191 		else {
192 			for (String pkStr : pkStrs) {
193 				inBuilder.append("','").append(pkStr);
194 			}
195 			inBuilder.append("'");// close last string value
196 
197 			return String.format("t.%s IN (%s)",
198 					pkName,
199 					inBuilder.substring(2)
200 					);
201 		}
202 	}
203 }