001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/io/datastore/sql/transaction/delete/TableNode.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2008 by:
006 Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/deegree/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 This library is free software; you can redistribute it and/or
012 modify it under the terms of the GNU Lesser General Public
013 License as published by the Free Software Foundation; either
014 version 2.1 of the License, or (at your option) any later version.
015
016 This library 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 GNU
019 Lesser General Public License for more details.
020
021 You should have received a copy of the GNU Lesser General Public
022 License along with this library; if not, write to the Free Software
023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024
025 Contact:
026
027 Andreas Poth
028 lat/lon GmbH
029 Aennchenstraße 19
030 53177 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Prof. Dr. Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: greve@giub.uni-bonn.de
041
042 ---------------------------------------------------------------------------*/
043 package org.deegree.io.datastore.sql.transaction.delete;
044
045 import java.util.Collection;
046 import java.util.HashMap;
047 import java.util.HashSet;
048 import java.util.Map;
049 import java.util.Set;
050
051 import org.deegree.io.datastore.FeatureId;
052 import org.deegree.io.datastore.schema.content.MappingField;
053 import org.deegree.ogcwebservices.wfs.operation.transaction.Delete;
054
055 /**
056 * Represents a table row that has to be deleted as part of a {@link Delete} operation.
057 * <p>
058 * Connected table entries (rows that refer to this row or that are referenced by this row) are also
059 * stored.
060 *
061 * @see TableGraph
062 *
063 * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider</a>
064 * @author last edited by: $Author: apoth $
065 *
066 * @version $Revision: 9342 $, $Date: 2007-12-27 13:32:57 +0100 (Do, 27 Dez 2007) $
067 */
068 public class TableNode {
069
070 private String table;
071
072 private Map<String, KeyColumn> namesToColumns = new HashMap<String, KeyColumn>();
073
074 private Set<TableNode> preNodes = new HashSet<TableNode>();
075
076 private Set<TableNode> postNodes = new HashSet<TableNode>();
077
078 private boolean deleteVetoPossible;
079
080 /**
081 * Creates a new <code>DeleteNode</code> instance.
082 *
083 * @param table
084 * @param keyColumns
085 */
086 TableNode( String table, Collection<KeyColumn> keyColumns ) {
087 this.table = table;
088 for ( KeyColumn column : keyColumns ) {
089 this.namesToColumns.put( column.getName(), column );
090 }
091 }
092
093 /**
094 * Creates a new <code>DeleteNode</code> instance for a feature instance.
095 *
096 * @param fid
097 */
098 TableNode( FeatureId fid ) {
099 MappingField[] fidFields = fid.getFidDefinition().getIdFields();
100 for ( int i = 0; i < fidFields.length; i++ ) {
101 KeyColumn column = new KeyColumn( fidFields[i].getField(), fidFields[i].getType(), fid.getValue( i ) );
102 this.namesToColumns.put( column.getName(), column );
103 }
104 this.table = fid.getFeatureType().getTable();
105 }
106
107 boolean isDeleteVetoPossible() {
108 return this.deleteVetoPossible;
109 }
110
111 void setDeleteVetoPossible() {
112 this.deleteVetoPossible = true;
113 }
114
115 /**
116 * Returns the table name.
117 *
118 * @return the table name
119 */
120 String getTable() {
121 return this.table;
122 }
123
124 /**
125 * Returns the key columns that identify the table row.
126 *
127 * @return the key columns that identify the table row
128 */
129 Collection<KeyColumn> getKeyColumns() {
130 return this.namesToColumns.values();
131 }
132
133 /**
134 * Returns the value for the given key column name.
135 *
136 * @param columnName
137 * @return the value for the given key column name
138 */
139 KeyColumn getKeyColumnValue( String columnName ) {
140 return this.namesToColumns.get( columnName );
141 }
142
143 /**
144 * Returns the set of post nodes, i.e. table rows that <i>are referenced</i> by this row.
145 *
146 * @return the set of post nodes
147 */
148 Collection<TableNode> getPostNodes() {
149 return this.postNodes;
150 }
151
152 /**
153 * Returns the set of pre nodes, i.e. table rows that <i>refer</i> to this row.
154 *
155 * @return the set of pre nodes
156 */
157 Collection<TableNode> getPreNodes() {
158 return this.preNodes;
159 }
160
161 /**
162 * Connects this node to the given target node.
163 * <p>
164 * NOTE: The target node is the one that stores the primary key.
165 *
166 * @param targetNode
167 */
168 void connect( TableNode targetNode ) {
169 if ( !this.postNodes.contains( targetNode ) ) {
170 this.postNodes.add( targetNode );
171 targetNode.preNodes.add( this );
172 }
173 }
174
175 @Override
176 public int hashCode() {
177 return this.table.hashCode();
178 }
179
180 @Override
181 public boolean equals( Object obj ) {
182 if ( obj == null || !( obj instanceof TableNode ) ) {
183 return false;
184 }
185 TableNode that = (TableNode) obj;
186 if ( !this.table.equals( that.table ) ) {
187 return false;
188 }
189 if ( this.namesToColumns.size() != that.namesToColumns.size() ) {
190 return false;
191 }
192 for ( String columnName : this.namesToColumns.keySet() ) {
193 KeyColumn thisKeyValue = this.namesToColumns.get( columnName );
194 KeyColumn thatKeyValue = that.namesToColumns.get( columnName );
195 if ( !thisKeyValue.equals( thatKeyValue ) ) {
196 return false;
197 }
198 }
199 return true;
200 }
201
202 @Override
203 public String toString() {
204 StringBuffer sb = new StringBuffer();
205 sb.append( this.table );
206 for ( KeyColumn column : this.namesToColumns.values() ) {
207 sb.append( "," );
208 sb.append( column );
209 }
210 return sb.toString();
211 }
212
213 String toString( String indent, Set<TableNode> printedNodes ) {
214 StringBuffer sb = new StringBuffer();
215 sb.append( indent );
216 sb.append( "- table: " );
217 sb.append( this.table );
218 for ( KeyColumn column : this.namesToColumns.values() ) {
219 sb.append( ", " );
220 sb.append( column );
221 }
222 sb.append( '\n' );
223
224 for ( TableNode postNode : this.postNodes ) {
225 sb.append( indent );
226 if ( printedNodes.contains( postNode ) ) {
227 sb.append( indent + " " );
228 sb.append( "- table: " );
229 sb.append( postNode.getTable() );
230 sb.append( " (DUP)\n" );
231 } else {
232 printedNodes.add( postNode );
233 sb.append( postNode.toString( indent + " ", printedNodes ) );
234 }
235 }
236 return sb.toString();
237 }
238
239 }
240
241 /**
242 * Encapsulates a column name, it's type code and a value.
243 */
244 class KeyColumn {
245
246 private String name;
247
248 private int typeCode;
249
250 private Object value;
251
252 KeyColumn( String name, int typeCode, Object value ) {
253 this.name = name;
254 this.typeCode = typeCode;
255 this.value = value;
256 }
257
258 String getName() {
259 return this.name;
260 }
261
262 int getTypeCode() {
263 return this.typeCode;
264 }
265
266 Object getValue() {
267 return this.value;
268 }
269
270 @Override
271 public boolean equals( Object obj ) {
272 if ( obj == null || !( obj instanceof KeyColumn ) ) {
273 return false;
274 }
275 KeyColumn that = (KeyColumn) obj;
276 if ( !this.name.equals( that.name ) ) {
277 return false;
278 }
279 return this.value.equals( that.value );
280 }
281
282 @Override
283 public String toString() {
284 StringBuffer sb = new StringBuffer();
285 sb.append( this.name );
286 sb.append( '=' );
287 sb.append( this.value );
288 return sb.toString();
289 }
290 }