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 }