1 /* 2 * $Source$ 3 * $Revision$ 4 * 5 * Copyright (C) 2000 William Chesters 6 * 7 * Part of Melati (http://melati.org), a framework for the rapid 8 * development of clean, maintainable web applications. 9 * 10 * Melati is free software; Permission is granted to copy, distribute 11 * and/or modify this software under the terms either: 12 * 13 * a) the GNU General Public License as published by the Free Software 14 * Foundation; either version 2 of the License, or (at your option) 15 * any later version, 16 * 17 * or 18 * 19 * b) any version of the Melati Software License, as published 20 * at http://melati.org 21 * 22 * You should have received a copy of the GNU General Public License and 23 * the Melati Software License along with this program; 24 * if not, write to the Free Software Foundation, Inc., 25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the 26 * GNU General Public License and visit http://melati.org to obtain the 27 * Melati Software License. 28 * 29 * Feel free to contact the Developers of Melati (http://melati.org), 30 * if you would like to work out a different arrangement than the options 31 * outlined here. It is our intention to allow Melati to be used by as 32 * wide an audience as possible. 33 * 34 * This program is distributed in the hope that it will be useful, 35 * but WITHOUT ANY WARRANTY; without even the implied warranty of 36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 * GNU General Public License for more details. 38 * 39 * Contact details for copyright holder: 40 * 41 * William Chesters <williamc At paneris.org> 42 * http://paneris.org/~williamc 43 * Obrechtstraat 114, 2517VX Den Haag, The Netherlands 44 */ 45 46 package org.melati.poem; 47 48 import java.util.Enumeration; 49 import java.util.Map; 50 import java.util.Hashtable; 51 import org.melati.poem.util.EmptyEnumeration; 52 53 /** 54 * A class which defines the three standard integrity fixes of 55 * <tt>delete</tt>, <tt>clear</tt> and <tt>prevent</tt>. 56 * <p> 57 * These correspond to the SQL ON DELETE CASCADE, ON DELETE SET NULL 58 * and ON DELETE NO ACTION. 59 * </p> 60 */ 61 public abstract class StandardIntegrityFix implements IntegrityFix { 62 63 /** The id for a fix. */ 64 private final Integer index; 65 /** The name for a fix. */ 66 private final String name; 67 68 /** 69 * @return the name 70 */ 71 public String getName() { 72 return name; 73 } 74 75 /** 76 * @return the index. 77 */ 78 public Integer getIndex() { 79 return index; 80 } 81 82 83 /* private -- makes Sun compiler barf ... 84 An abstract class must be extended so cannot have a private constructor. 85 */ 86 StandardIntegrityFix(int index, String name) { 87 this.index = new Integer(index); 88 this.name = name; 89 } 90 91 /* The fixes. */ 92 /** Delete referred objects. */ 93 public static final StandardIntegrityFix delete; 94 /** Clear (make null) field in referring object. */ 95 public static final StandardIntegrityFix clear; 96 /** Disallow the deletion. */ 97 public static final StandardIntegrityFix prevent; 98 99 /** 100 * Each {@link StandardIntegrityFix} differs from another by the 101 * way they implement {#referencesTo}. 102 * 103 * <b>delete</b> deletes all references to this {@link Persistent}. <br> 104 * <b>clear</b> sets the references to null. <br> 105 * <b>prevent</b> returns the references, which prevokes an exception 106 * 107 * @see Persistent#delete(Map) 108 * @param referee the {@link Persistent} we are deleting 109 * @param column the {@link Column} of the reference to {@link Persistent} 110 * we are deleting, used in <b>clear</b> 111 * @param refs an {@link Enumeration} of the objects which contain 112 * a reference to the {@link Persistent} we are deleting, 113 * each is deleted, cleared or returned respectively 114 * @param referenceFixOfColumn a {@link Map} keyed on {@link Column} 115 * giving the associated {@link IntegrityFix}, passed in to 116 * the {@link Persistent} referer to delete itself 117 *@return an {@link Enumeration} of the remaining referers, which if 118 * not empty will prevent deletion 119 */ 120 @SuppressWarnings("rawtypes") 121 public abstract Enumeration<Persistent> referencesTo(Persistent referee, 122 Column column, 123 Enumeration refs, 124 Map referenceFixOfColumn); 125 126 /** 127 * Create the fixes. 128 */ 129 @SuppressWarnings({"rawtypes","unchecked"}) 130 private static final StandardIntegrityFix[] fixes = { 131 delete = new StandardIntegrityFix(0, "delete") { 132 public Enumeration<Persistent> referencesTo(Persistent referee, Column column, 133 Enumeration refs, 134 Map referenceFixOfColumn) { 135 while (refs.hasMoreElements()) { 136 Persistent p = (Persistent)refs.nextElement(); 137 p.delete(referenceFixOfColumn); 138 } 139 return new EmptyEnumeration<Persistent>(); 140 } 141 }, 142 clear = new StandardIntegrityFix(1, "clear") { 143 public Enumeration<Persistent> referencesTo(Persistent referrer, Column column, 144 Enumeration refs, 145 Map referenceFixOfColumn) { 146 while (refs.hasMoreElements()) 147 column.setRaw((Persistent)refs.nextElement(), null); 148 return new EmptyEnumeration<Persistent>(); 149 } 150 }, 151 prevent = new StandardIntegrityFix(2, "prevent") { 152 public Enumeration<Persistent> referencesTo(Persistent referrer, Column column, 153 Enumeration refs, 154 Map referenceFixOfColumn) { 155 return refs; 156 } 157 } 158 }; 159 160 /** 161 * Get a fix by its index. 162 * 163 * @param i the index 164 * @return the fix at that index 165 */ 166 public static StandardIntegrityFix forIndex(int i) { 167 return fixes[i]; 168 } 169 170 /** 171 * @return the number of fixes 172 */ 173 public static int count() { 174 return fixes.length; 175 } 176 177 private static final Hashtable<String,IntegrityFix> fixOfName = new Hashtable<String,IntegrityFix>(); 178 179 static { 180 for (int i = 0; i < fixes.length; ++i) 181 fixOfName.put(fixes[i].name, fixes[i]); 182 } 183 184 /** 185 * Thrown when an invalid {@link StandardIntegrityFix} is specified, 186 * by a typing mistake in the DSD for example. 187 */ 188 public static class NameUnrecognisedException extends PoemException { 189 private static final long serialVersionUID = 1L; 190 191 /** The name. */ 192 public String name; 193 194 /** 195 * Constructor. 196 * @param name the name of the fix 197 */ 198 public NameUnrecognisedException(String name) { 199 this.name = name; 200 } 201 202 /** @return The detail message. */ 203 public String getMessage() { 204 return "No integrity fix found which goes by the name `" + name + "'"; 205 } 206 } 207 208 /** 209 * Find by name. 210 * 211 * @param name the name 212 * @return the named fix 213 */ 214 public static StandardIntegrityFix named(String name) { 215 StandardIntegrityFix it = (StandardIntegrityFix)fixOfName.get(name); 216 if (it == null) 217 throw new NameUnrecognisedException(name); 218 return it; 219 } 220 221 /** 222 * Return the name and index. 223 * {@inheritDoc} 224 * @see java.lang.Object#toString() 225 */ 226 public String toString() { 227 return name + "/" + index; 228 } 229 230 231 }