View Javadoc
1   package fr.ifremer.adagio.synchro.meta;
2   
3   /*
4    * #%L
5    * SIH-Adagio :: Synchronization
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2012 - 2014 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 java.sql.ResultSet;
27  import java.sql.SQLException;
28  
29  import org.hibernate.internal.CoreMessageLogger;
30  import org.jboss.logging.Logger;
31  
32  import fr.ifremer.adagio.synchro.service.SynchroServiceUtils;
33  import fr.ifremer.adagio.synchro.service.data.DataSynchroService;
34  
35  /**
36   * Store metadata on a link between two tables.
37   * <ul>
38   * <li>Obtains owner table name {@link #getTableName()};</li>
39   * <li>Obtains linked column (for FK only) {@link #getParentJoin()} as a join metadata: used to synchronize data in
40   * {@link DataSynchroService};</li>
41   * <li>Obtains if a column is protected for data import {@link #isProtected()}: used by {@link SynchroServiceUtils} for
42   * schemas check.</li>
43   * </ul>
44   * 
45   * @author Benoit Lavenier <benoit.lavenier@e-is.pro>
46   * @since 3.5.2
47   * 
48   */
49  public class SynchroJoinMetadata {
50  
51  	private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SynchroJoinMetadata.class.getName());
52  
53  	protected SynchroTableMetadata sourceTable;
54  
55  	protected SynchroColumnMetadata sourceColumn;
56  
57  	protected SynchroColumnMetadata targetColumn;
58  
59  	protected SynchroTableMetadata targetTable;
60  
61  	protected boolean isValid = false;
62  
63  	protected boolean isChild = false;
64  
65  	protected boolean isSourceFk = false;
66  
67  	public SynchroJoinMetadata(
68  			ResultSet rs,
69  			SynchroTableMetadata table,
70  			SynchroDatabaseMetadata meta) throws SQLException {
71  
72  		// String pkCatalog = rs.getString("PKTABLE_CAT");
73  		// String pkSchema = rs.getString("PKTABLE_SCHEM");
74  		String pkTableName = rs.getString("PKTABLE_NAME").toLowerCase();
75  		String pkColumnName = rs.getString("PKCOLUMN_NAME").toLowerCase();
76  		String fkTableName = rs.getString("FKTABLE_NAME").toLowerCase();
77  		String fkColumnName = rs.getString("FKCOLUMN_NAME").toLowerCase();
78  
79  		// Load PK metadata
80  		SynchroTableMetadata pkTable = meta.getLoadedTable(pkTableName);
81  		SynchroColumnMetadata pkColumn = null;
82  		if (pkTable == null) {
83  			LOG.trace(String.format("Ignoring reference to table '%s', because it could not been found in tables.",
84  					pkTableName));
85  			return;
86  		}
87  		pkColumn = pkTable.getColumn(pkColumnName);
88  		if (pkColumn == null) {
89  			LOG.trace(String.format("Ignoring reference to column '%s.%s', because it could not been found.",
90  					pkTableName, pkColumnName));
91  			return;
92  		}
93  
94  		// Load FK metadata
95  		SynchroTableMetadata fkTable = meta.getLoadedTable(fkTableName);
96  		SynchroColumnMetadata fkColumn = null;
97  		if (fkTable != null) {
98  			fkColumn = fkTable.getColumn(fkColumnName);
99  		}
100 		if (fkTable == null || fkColumn == null) {
101 			// Ignoring the join, because referenced table not bound
102 			LOG.trace(String.format("Ignoring reference to table '%s' from foreign key '%s.%s', because table '%s' could not been found in tables.",
103 					pkTableName, fkTableName, fkColumnName, fkTableName));
104 			return;
105 		}
106 
107 		if (pkTable == table) {
108 			this.sourceTable = pkTable;
109 			this.sourceColumn = pkColumn;
110 
111 			this.targetTable = fkTable;
112 			this.targetColumn = fkColumn;
113 
114 			this.isChild = true;
115 			this.isSourceFk = false;
116 		}
117 		else {
118 			this.sourceTable = fkTable;
119 			this.sourceColumn = fkColumn;
120 
121 			this.targetTable = pkTable;
122 			this.targetColumn = pkColumn;
123 
124 			this.isChild = false;
125 			this.isSourceFk = true;
126 		}
127 		isValid = true;
128 	}
129 
130 	public boolean isChild() {
131 		return isChild;
132 	}
133 
134 	public int hashCode() {
135 		return sourceColumn.hashCode() + targetColumn.hashCode();
136 	}
137 
138 	public boolean equals(Object obj) {
139 		if (obj instanceof SynchroJoinMetadata) {
140 			SynchroJoinMetadata otherJoin = (SynchroJoinMetadata) obj;
141 			return sourceColumn.equals(otherJoin.sourceColumn) && targetColumn.equals(otherJoin.targetColumn);
142 		}
143 		return this.equals(obj);
144 	}
145 
146 	public SynchroTableMetadata getTargetTable() {
147 		return targetTable;
148 	}
149 
150 	public SynchroColumnMetadata getTargetColumn() {
151 		return targetColumn;
152 	}
153 
154 	public SynchroTableMetadata getSourceTable() {
155 		return sourceTable;
156 	}
157 
158 	public SynchroColumnMetadata getSourceColumn() {
159 		return sourceColumn;
160 	}
161 
162 	public boolean isValid() {
163 		return isValid;
164 	}
165 
166 	public void setIsValid(boolean isValid) {
167 		this.isValid = isValid;
168 	}
169 
170 	public String toString() {
171 		return String.format("JoinMetadata(%s.%s = %s.%s)",
172 				sourceTable.getName(), sourceColumn.getName(),
173 				targetTable.getName(), targetColumn.getName());
174 	}
175 
176 	public boolean needRemoteIdInterceptor() {
177 		return isSourceFk && targetTable.isWithRemoteIdColumn();
178 	}
179 
180 }