View Javadoc

1   /*
2    Wotonomy: OpenStep design patterns for pure Java applications.
3    Copyright (C) 2001 Michael Powers
4   
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9   
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14  
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, see http://www.gnu.org
17   */
18  package net.wotonomy.access;
19  
20  import net.wotonomy.foundation.NSArray;
21  import net.wotonomy.foundation.NSDictionary;
22  import net.wotonomy.foundation.NSMutableArray;
23  import net.wotonomy.foundation.NSMutableDictionary;
24  /***
25  * Represents a relationship from one entity to another. Relationships are unidirectional.
26  *
27  * @author ezamudio@nasoft.com
28  * @author $Author: cgruber $
29  * @version $Revision: 894 $
30  */
31  public class EORelationship extends EOProperty implements EOPropertyListEncoding {
32  
33  	public static final int InnerJoin = 0;
34  	public static final int FullOuterJoin = 1;
35  	public static final int LeftOuterJoin = 2;
36  	public static final int RightOuterJoin = 3;
37  
38  	protected String _name;
39  	protected int _batchCount;
40  	protected int _deleteRule;
41  	protected int _joinSemantic;
42  	protected EOEntity _destination;
43  	protected EOEntity _entity;
44  	protected NSMutableArray _joins = new NSMutableArray();
45  	protected boolean _isMandatory;
46  	protected boolean _isToMany;
47  	protected boolean _isFlattened;
48  	protected boolean _knowsIfFlattened;
49  	protected boolean _ownsDestination;
50  	protected boolean _propagatesPrimaryKey;
51  	protected boolean _useBatchFaulting;
52  	protected NSDictionary _userInfo = NSDictionary.EmptyDictionary;
53  	protected NSDictionary _internalInfo = NSDictionary.EmptyDictionary;
54  	protected NSDictionary plist;
55  	protected String _definition;
56  
57  	public EORelationship() {
58  		super();
59  	}
60  
61  	public EORelationship(NSDictionary dict, Object obj) {
62  		super();
63  		_entity = (EOEntity)obj;
64  		setName((String)dict.objectForKey("name"));
65  		setToMany("Y".equals(dict.objectForKey("isToMany")));
66  		setPropagatesPrimaryKey("Y".equals(dict.objectForKey("propagatesPrimaryKey")));
67  		setIsMandatory("Y".equals(dict.objectForKey("isMandatory")));
68  		setOwnsDestination("Y".equals(dict.objectForKey("ownsDestination")));
69  		setDefinition((String)dict.objectForKey("definition"));
70  		String delrule = (String)dict.objectForKey("deleteRule");
71  		if (delrule != null) {
72  			if (delrule.equals("EODeleteRuleCascade"))
73  				setDeleteRule(0);
74  			else if (delrule.equals("EODeleteRuleDeny"))
75  				setDeleteRule(0);
76  			else if (delrule.equals("EODeleteRuleNoAction"))
77  				setDeleteRule(0);
78  			else if (delrule.equals("EODeleteRuleNullify"))
79  				setDeleteRule(0);
80  		}
81  		delrule = (String)dict.objectForKey("joinSemantic");
82  		if (delrule != null) {
83  			if (delrule.equals("EOInnerJoin"))
84  				setJoinSemantic(InnerJoin);
85  			else if (delrule.equals("EOFullOuterJoin"))
86  				setJoinSemantic(FullOuterJoin);
87  			else if (delrule.equals("EOLeftOuterJoin"))
88  				setJoinSemantic(LeftOuterJoin);
89  			else if (delrule.equals("EORightOuterJoin"))
90  				setJoinSemantic(RightOuterJoin);
91  		}
92  		delrule = (String)dict.objectForKey("batchCount");
93  		if (delrule != null)
94  			setNumberOfToManyFaultsToBatchFetch(Integer.parseInt(delrule));
95  		NSDictionary d = (NSDictionary)dict.objectForKey("userInfo");
96  		if (d != null)
97  			_userInfo = d;
98  		d = (NSDictionary)dict.objectForKey("internalInfo");
99  		if (d != null)
100 			_internalInfo = d;
101 		plist = dict;
102 	}
103 
104 	public void setName(String name) {
105 		_name = name;
106 	}
107 	public String name() {
108 		return _name;
109 	}
110 
111 	public void addJoin(EOJoin join) {
112 		_joins.addObject(join);
113 	}
114 
115 	public void removeJoin(EOJoin join) {
116 		_joins.removeObject(join);
117 	}
118 
119 	public EOEntity entity() {
120 		return _entity;
121 	}
122 
123 	public EOEntity destinationEntity() {
124 		isFlattened();
125 		if (_destination == null && plist != null) {
126 			EOModel model = _entity.model();
127 			EOModelGroup group = model.modelGroup();
128 			String destEntity = (String)plist.objectForKey("destination");
129 			if (group != null)
130 				_destination = group.entityNamed(destEntity);
131 			else
132 				_destination = model.entityNamed(destEntity);
133 		}
134 		return _destination;
135 	}
136 
137 	public void setOwnsDestination(boolean flag) {
138 		_ownsDestination = flag;
139 	}
140 	public boolean ownsDestination() {
141 		return _ownsDestination;
142 	}
143 
144 	public void setToMany(boolean flag) {
145 		_isToMany = flag;
146 	}
147 	public boolean isToMany() {
148 		return _isToMany;
149 	}
150 
151 	public void setIsMandatory(boolean flag) {
152 		_isMandatory = flag;
153 	}
154 	public boolean isMandatory() {
155 		return _isMandatory;
156 	}
157 
158 	public void setPropagatesPrimaryKey(boolean flag) {
159 		_propagatesPrimaryKey = flag;
160 	}
161 	public boolean propagatesPrimaryKey() {
162 		return _propagatesPrimaryKey;
163 	}
164 
165 	public void setDeleteRule(int value) {
166 		_deleteRule = value;
167 	}
168 	public int deleteRule() {
169 		return _deleteRule;
170 	}
171 
172 	public void setJoinSemantic(int value) {
173 		_joinSemantic = value;
174 	}
175 	public int joinSemantic() {
176 		return _joinSemantic;
177 	}
178 
179 	public void setNumberOfToManyFaultsToBatchFetch(int count) {
180 		_batchCount = count;
181 	}
182 	public int numberOfToManyFaultsToBatchFetch() {
183 		return _batchCount;
184 	}
185 
186 	public NSArray joins() {
187 		if (_joins.count() == 0 && plist != null) {
188 			NSArray joins = (NSArray)plist.objectForKey("joins");
189 			for (int i = 0; i < joins.count(); i++) {
190 				NSDictionary d = (NSDictionary)joins.objectAtIndex(i);
191 				String srcName = (String)d.objectForKey("sourceAttribute");
192 				String dstName = (String)d.objectForKey("destinationAttribute");
193 				EOAttribute a1 = _entity.attributeNamed(srcName);
194 				EOAttribute a2 = destinationEntity().attributeNamed(dstName);
195 				EOJoin j = new EOJoin(a1, a2);
196 				addJoin(j);
197 			}
198 		}
199 		return new NSArray(_joins);
200 	}
201 
202 	public void setDefinition(String def) {
203 		_definition = def;
204 	}
205 	public String definition() {
206 		return _definition;
207 	}
208 
209 	public boolean isFlattened() {
210 		if (_knowsIfFlattened)
211 			return _isFlattened;
212 		_knowsIfFlattened = true;
213 		if (definition() == null)
214 			return false;
215 		NSArray comps = NSArray.componentsSeparatedByString(definition(), ".");
216 		if (comps.count() < 2)
217 			return false;
218 		EORelationship r = null;
219 		EOEntity e = entity();
220 		for (int i = 0; i < comps.count(); i++) {
221 			String name = (String)comps.objectAtIndex(i);
222 			r = e.relationshipNamed(name);
223 			if (r == null)
224 				return false;
225 			e = r.destinationEntity();
226 		}
227 		_destination = e;
228 		_isFlattened = true;
229 		return _isFlattened;
230 	}
231 
232 	public boolean isMultiHop() {
233 		return false;
234 	}
235 
236 	public String relationshipPath() {
237 		if (isFlattened())
238 			return _definition;
239 		return null;
240 	}
241 
242 	public void setUserInfo(NSDictionary value) {
243 		_userInfo = value;
244 	}
245 	public NSDictionary userInfo() {
246 		return _userInfo;
247 	}
248 
249 	public void awakeWithPropertyList(NSDictionary plist) {
250 	}
251 
252 	public void encodeIntoPropertyList(NSMutableDictionary dict) {
253 		dict.setObjectForKey(name(), "name");
254 		if (destinationEntity() != null && definition() == null)
255 			dict.setObjectForKey(_destination.name(), "destination");
256 		if (_internalInfo != null && _internalInfo.count() > 0)
257 			dict.setObjectForKey(_internalInfo, "internalInfo");
258 		if (_userInfo != null && _userInfo.count() > 0)
259 			dict.setObjectForKey(_userInfo, "userInfo");
260 		if (isToMany())
261 			dict.setObjectForKey("Y", "isToMany");
262 		switch (_joinSemantic) {
263 			case InnerJoin:
264 				dict.setObjectForKey("EOInnerJoin", "joinSemantic");
265 				break;
266 			case FullOuterJoin:
267 				dict.setObjectForKey("EOFullOuterJoin", "joinSemantic");
268 				break;
269 			case LeftOuterJoin:
270 				dict.setObjectForKey("EOLefOuterJoin", "joinSemantic");
271 				break;
272 			case RightOuterJoin:
273 				dict.setObjectForKey("EORightOuterJoin", "joinSemantic");
274 				break;
275 		}
276 		if (_batchCount > 0)
277 			dict.setObjectForKey(new Integer(_batchCount), "batchCount");
278 		if (definition() != null)
279 			dict.setObjectForKey(definition(), "definition");
280 		else {
281 			NSMutableArray jarr = new NSMutableArray(joins().count());
282 			for (int i = 0; i < _joins.count(); i++) {
283 				EOJoin j = (EOJoin)_joins.objectAtIndex(i);
284 				NSDictionary d = new NSDictionary(
285 					new Object[]{ j.sourceAttribute().name(), j.destinationAttribute().name() },
286 					new Object[]{ "sourceAttribute", "destinationAttribute" });
287 				jarr.addObject(d);
288 			}
289 			dict.setObjectForKey(jarr, "joins");
290 		}
291 	}
292 
293 }
294 /*
295  * $Log$
296  * Revision 1.2  2006/02/16 16:47:13  cgruber
297  * Move some classes in to "internal" packages and re-work imports, etc.
298  *
299  * Also use UnsupportedOperationExceptions where appropriate, instead of WotonomyExceptions.
300  *
301  * Revision 1.1  2006/02/16 13:19:57  cgruber
302  * Check in all sources in eclipse-friendly maven-enabled packages.
303  *
304  * Revision 1.5  2003/08/11 19:38:27  chochos
305  * Can now read from a file and re-write to another file.
306  *
307  * Revision 1.4  2003/08/09 01:35:35  chochos
308  * implement EOPropertyListEncoding
309  *
310  * Revision 1.3  2003/08/08 06:51:53  chochos
311  * isFlattened() works
312  *
313  * Revision 1.2  2003/08/08 02:17:43  chochos
314  * main accessors are in place.
315  *
316  * Revision 1.1  2003/08/07 02:41:30  chochos
317  * a relationship that for the moment can be created from a property list.
318  *
319 */