1 package org.apache.torque.engine.database.model;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Hashtable;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.commons.collections.map.ListOrderedMap;
29 import org.xml.sax.Attributes;
30
31 /***
32 * A class for information about foreign keys of a table.
33 *
34 * @author <a href="mailto:fedor.karpelevitch@home.com">Fedor</a>
35 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
36 * @author <a href="mailto:monroe@dukece.com>Greg Monroe</a>
37 * @version $Id: ForeignKey.java 473814 2006-11-11 22:30:30Z tv $
38 */
39 public class ForeignKey
40 {
41 private String foreignTableName;
42 private String name;
43 private String onUpdate;
44 private String onDelete;
45 private Table parentTable;
46 private List localColumns = new ArrayList(3);
47 private List foreignColumns = new ArrayList(3);
48 private Map options = Collections.synchronizedMap(new ListOrderedMap());
49
50
51
52 private static final String NONE = "NONE";
53 private static final String SETNULL = "SETNULL";
54
55 /***
56 * Imports foreign key from an XML specification
57 *
58 * @param attrib the xml attributes
59 */
60 public void loadFromXML(Attributes attrib)
61 {
62 foreignTableName = attrib.getValue("foreignTable");
63 name = attrib.getValue("name");
64 onUpdate = attrib.getValue("onUpdate");
65 onDelete = attrib.getValue("onDelete");
66 onUpdate = normalizeFKey(onUpdate);
67 onDelete = normalizeFKey(onDelete);
68 }
69
70 /***
71 * Normalizes the input of onDelete, onUpdate attributes
72 *
73 * @param attrib the attribute to normalize
74 * @return nomalized form
75 */
76 private String normalizeFKey(String attrib)
77 {
78 if (attrib == null)
79 {
80 attrib = NONE;
81 }
82
83 attrib = attrib.toUpperCase();
84 if (attrib.equals(SETNULL))
85 {
86 attrib = "SET NULL";
87 }
88 return attrib;
89 }
90
91 /***
92 * Returns whether or not the onUpdate attribute is set
93 *
94 * @return true if the onUpdate attribute is set
95 */
96 public boolean hasOnUpdate()
97 {
98 return !onUpdate.equals(NONE);
99 }
100
101 /***
102 * Returns whether or not the onDelete attribute is set
103 *
104 * @return true if the onDelete attribute is set
105 */
106 public boolean hasOnDelete()
107 {
108 return !onDelete.equals(NONE);
109 }
110
111 /***
112 * Returns the onUpdate attribute
113 *
114 * @return the onUpdate attribute
115 */
116 public String getOnUpdate()
117 {
118 return onUpdate;
119 }
120
121 /***
122 * Returns the onDelete attribute
123 *
124 * @return the onDelete attribute
125 */
126 public String getOnDelete()
127 {
128 return onDelete;
129 }
130
131 /***
132 * Sets the onDelete attribute
133 *
134 * @param value the onDelete attribute
135 */
136 public void setOnDelete(String value)
137 {
138 onDelete = normalizeFKey(value);
139 }
140
141 /***
142 * Sets the onUpdate attribute
143 *
144 * @param value the onUpdate attribute
145 */
146 public void setOnUpdate(String value)
147 {
148 onUpdate = normalizeFKey(value);
149 }
150
151 /***
152 * Returns the name attribute.
153 *
154 * @return the name
155 */
156 public String getName()
157 {
158 return name;
159 }
160
161 /***
162 * Sets the name attribute.
163 *
164 * @param name the name
165 */
166 public void setName(String name)
167 {
168 this.name = name;
169 }
170
171 /***
172 * Get the foreignTableName of the FK
173 *
174 * @return the name of the foreign table
175 */
176 public String getForeignTableName()
177 {
178 return foreignTableName;
179 }
180
181 /***
182 * Set the foreignTableName of the FK
183 *
184 * @param tableName the name of the foreign table
185 */
186 public void setForeignTableName(String tableName)
187 {
188 foreignTableName = tableName;
189 }
190
191 /***
192 * Set the parent Table of the foreign key
193 *
194 * @param parent the table
195 */
196 public void setTable(Table parent)
197 {
198 parentTable = parent;
199 }
200
201 /***
202 * Get the parent Table of the foreign key
203 *
204 * @return the parent table
205 */
206 public Table getTable()
207 {
208 return parentTable;
209 }
210
211 /***
212 * Returns the name of the table the foreign key is in
213 *
214 * @return the name of the table
215 */
216 public String getTableName()
217 {
218 return parentTable.getName();
219 }
220
221 /***
222 * Adds a new reference entry to the foreign key
223 *
224 * @param attrib the xml attributes
225 */
226 public void addReference(Attributes attrib)
227 {
228 addReference(attrib.getValue("local"), attrib.getValue("foreign"));
229 }
230
231 /***
232 * Adds a new reference entry to the foreign key
233 *
234 * @param local name of the local column
235 * @param foreign name of the foreign column
236 */
237 public void addReference(String local, String foreign)
238 {
239 localColumns.add(local);
240 foreignColumns.add(foreign);
241 }
242
243 /***
244 * Returns a comma delimited string of local column names
245 *
246 * @return the local column names
247 */
248 public String getLocalColumnNames()
249 {
250 return Column.makeList(getLocalColumns());
251 }
252
253 /***
254 * Returns a comma delimited string of foreign column names
255 *
256 * @return the foreign column names
257 */
258 public String getForeignColumnNames()
259 {
260 return Column.makeList(getForeignColumns());
261 }
262
263 /***
264 * Returns the list of local column names. You should not edit this List.
265 *
266 * @return the local columns
267 */
268 public List getLocalColumns()
269 {
270 return localColumns;
271 }
272
273 /***
274 * Utility method to get local column names to foreign column names
275 * mapping for this foreign key.
276 *
277 * @return table mapping foreign names to local names
278 */
279 public Hashtable getLocalForeignMapping()
280 {
281 Hashtable h = new Hashtable();
282
283 for (int i = 0; i < localColumns.size(); i++)
284 {
285 h.put(localColumns.get(i), foreignColumns.get(i));
286 }
287
288 return h;
289 }
290
291 /***
292 * Returns the list of foreign column names. You should not edit this List.
293 *
294 * @return the foreign columns
295 */
296 public List getForeignColumns()
297 {
298 return foreignColumns;
299 }
300
301 /***
302 * Utility method to get foreign column names to local column names
303 * mapping for this foreign key.
304 *
305 * @return table mapping local names to foreign names
306 */
307 public Hashtable getForeignLocalMapping()
308 {
309 Hashtable h = new Hashtable();
310
311 for (int i = 0; i < localColumns.size(); i++)
312 {
313 h.put(foreignColumns.get(i), localColumns.get(i));
314 }
315
316 return h;
317 }
318
319 /***
320 * String representation of the foreign key. This is an xml representation.
321 *
322 * @return string representation in xml
323 */
324 public String toString()
325 {
326 StringBuffer result = new StringBuffer();
327 result.append(" <foreign-key foreignTable=\"")
328 .append(getForeignTableName())
329 .append("\" name=\"")
330 .append(getName())
331 .append("\">\n");
332
333 for (int i = 0; i < localColumns.size(); i++)
334 {
335 result.append(" <reference local=\"")
336 .append(localColumns.get(i))
337 .append("\" foreign=\"")
338 .append(foreignColumns.get(i))
339 .append("\"/>\n");
340 }
341 result.append(" </foreign-key>\n");
342 return result.toString();
343 }
344
345 /***
346 * Add an XML Specified option key/value pair to this element's option set.
347 *
348 * @param key the key of the option.
349 * @param value the value of the option.
350 */
351 public void addOption(String key, String value)
352 {
353 options.put(key, value);
354 }
355
356 /***
357 * Get the value that was associated with this key in an XML option
358 * element.
359 *
360 * @param key the key of the option.
361 * @return The value for the key or a null.
362 */
363 public String getOption(String key)
364 {
365 return (String) options.get(key);
366 }
367
368 /***
369 * Gets the full ordered hashtable array of items specified by XML option
370 * statements under this element.<p>
371 *
372 * Note, this is not thread save but since it's only used for
373 * generation which is single threaded, there should be minimum
374 * danger using this in Velocity.
375 *
376 * @return An Map of all options. Will not be null but may be empty.
377 */
378 public Map getOptions()
379 {
380 return options;
381 }
382 }