View Javadoc
1 package com.bonevich.erj.model; 2 3 import com.bonevich.util.dependency.Dynamic; 4 5 import java.util.Iterator; 6 7 /*** A class that represents ... 8 * 9 * @see Relation 10 * @author Jeffrey D. Bonevich <bonevich@telocity.com> 11 */ 12 public final class ForeignKey extends KeyConstraint 13 { 14 ////////////////////////////////////////////////////////// 15 // Constants 16 public static final String NEW_FOREIGNKEY_STR = "fk_"; 17 18 public static final String ZERO_TO_ZERO_STR = "ZERO_TO_ZERO"; 19 public static final String ONE_TO_ZERO_STR = "ONE_TO_ZERO"; 20 public static final String ONE_TO_ONE_STR = "ONE_TO_ONE"; 21 public static final String ZERO_TO_MANY_STR = "ZERO_TO_MANY"; 22 public static final String ONE_TO_MANY_STR = "ONE_TO_MANY"; 23 public static final String ZERO_TO_MANY_MANDATORY_STR = "ZERO_TO_MANY_MANDATORY"; 24 public static final String ONE_TO_MANY_MANDATORY_STR = "ONE_TO_MANY_MANDATORY"; 25 public static final String MANY_TO_MANY_STR = "MANY_TO_MANY"; 26 27 public static class Cardinality 28 { 29 private String _name; 30 private String _label; 31 protected Cardinality(String name, String label) 32 { 33 _name = name; 34 _label = label; 35 } 36 public String getName() 37 { 38 return _name; 39 } 40 public String toString() 41 { 42 return _label; 43 } 44 } 45 public static final Cardinality ZERO_TO_ZERO = new Cardinality(ZERO_TO_ZERO_STR, "0:0"); 46 public static final Cardinality ONE_TO_ZERO = new Cardinality(ONE_TO_ZERO_STR, "1:0"); 47 public static final Cardinality ONE_TO_ONE = new Cardinality(ONE_TO_ONE_STR, "1:1"); 48 public static final Cardinality ZERO_TO_MANY = new Cardinality(ZERO_TO_MANY_STR, "0:M"); 49 public static final Cardinality ONE_TO_MANY = new Cardinality(ONE_TO_MANY_STR, "1:M"); 50 public static final Cardinality ZERO_TO_MANY_MANDATORY = new Cardinality(ZERO_TO_MANY_MANDATORY_STR, "0:M+"); 51 public static final Cardinality ONE_TO_MANY_MANDATORY = new Cardinality(ONE_TO_MANY_MANDATORY_STR, "1:M+"); 52 public static final Cardinality MANY_TO_MANY = new Cardinality(MANY_TO_MANY_STR, "M:M"); 53 54 public static final Cardinality[] CARDINALITY_ARRAY = { 55 ZERO_TO_ZERO, 56 ONE_TO_ZERO , 57 ONE_TO_ONE , 58 ZERO_TO_MANY, 59 ONE_TO_MANY , 60 ZERO_TO_MANY_MANDATORY, 61 ONE_TO_MANY_MANDATORY , 62 MANY_TO_MANY 63 }; 64 65 ////////////////////////////////////////////////////////// 66 // Attributes 67 private Cardinality _cardinality = ZERO_TO_MANY; 68 69 ////////////////////////////////////////////////////////// 70 // Associations 71 private Relation _referentRelation; 72 73 ////////////////////////////////////////////////////////// 74 // Dependency sentries 75 private Dynamic _dyn_cardinality = new Dynamic(); 76 77 ////////////////////////////////////////////////////////// 78 // Constructors 79 public ForeignKey(Relation relation, Attribute[] attributes, Relation referentRelation) 80 { 81 super(relation, attributes); 82 _referentRelation = referentRelation; 83 setIdentifier(NEW_FOREIGNKEY_STR + relation.getKeyCount()); 84 } 85 86 ////////////////////////////////////////////////////////// 87 // Getter/Setters 88 public Cardinality getCardinality() 89 { 90 _dyn_cardinality.onGet(); 91 return _cardinality; 92 } 93 public void setCardinality(Cardinality cardinality) 94 { 95 if (_cardinality != cardinality) 96 { 97 _dyn_cardinality.onSet(); 98 _cardinality = cardinality; 99 100 if (cardinality != MANY_TO_MANY) 101 { 102 // copy over attributes from referent's primary key 103 // FIXME: don't want to do this multiple times, just once 104 // Maybe make it a dependency tracked issue - automatically update 105 // by tracking PK of referent as a dependent attr? 106 107 // go with more traditional entity-relationship model? 108 // more accurately reflected in graph than relational model, 109 // but not really the info model I want 110 } 111 112 if (cardinality == ONE_TO_MANY || 113 cardinality == ONE_TO_MANY_MANDATORY) 114 { 115 Iterator attrs = getAttributeIterator(); 116 while (attrs.hasNext()) 117 { 118 ((Attribute) attrs.next()).setConstraint(AttributeConstraint.NOTNULL); 119 } 120 } 121 else if (cardinality == ONE_TO_ZERO || 122 cardinality == ONE_TO_ONE) 123 { 124 boolean makePK = true; 125 Iterator keys = getRelation().getKeyIterator(); 126 while (keys.hasNext()) 127 { 128 if (keys.next() instanceof PrimaryKey) 129 { 130 makePK = false; 131 break; 132 } 133 } 134 135 Attribute[] attrArray = new Attribute[_attributes.size()]; 136 attrArray = (Attribute[])_attributes.toArray(attrArray); 137 if (makePK) 138 { 139 getRelation().createPrimaryKey(attrArray); 140 } else { 141 getRelation().createUniqueKey(attrArray); 142 for (int i = 0; i < attrArray.length; i++) 143 { 144 attrArray[i].setConstraint(AttributeConstraint.NOTNULL); 145 } 146 } 147 } 148 else if (cardinality == MANY_TO_MANY) 149 { 150 Iterator attrs = getAttributeIterator(); 151 while (attrs.hasNext()) 152 { 153 //FIXME: concurrent mod problem here? 154 // or something else; can still see attr in FigRelation, 155 // changed to null or notnull constraint 156 getRelation().deleteAttribute((Attribute) attrs.next()); 157 } 158 } 159 160 } 161 } 162 163 ////////////////////////////////////////////////////////// 164 // Operations 165 public Relation getReferentRelation() 166 { 167 return _referentRelation; 168 } 169 170 public void accept(KeyVisitor visitor) 171 { 172 visitor.visitForeignKey(this); 173 } 174 175 } /* end class ForeignKey */

This page was automatically generated by Maven