/* Wotonomy: OpenStep design patterns for pure Java applications. Copyright (C) 2001 Michael Powers This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, see http://www.gnu.org */ package net.wotonomy.access; import net.wotonomy.foundation.NSArray; import net.wotonomy.foundation.NSDictionary; import net.wotonomy.foundation.NSMutableArray; import net.wotonomy.foundation.NSMutableDictionary; /** * Represents a relationship from one entity to another. Relationships are unidirectional. * * @author ezamudio@nasoft.com * @author $Author: cgruber $ * @version $Revision: 894 $ */ public class EORelationship extends EOProperty implements EOPropertyListEncoding { public static final int InnerJoin = 0; public static final int FullOuterJoin = 1; public static final int LeftOuterJoin = 2; public static final int RightOuterJoin = 3; protected String _name; protected int _batchCount; protected int _deleteRule; protected int _joinSemantic; protected EOEntity _destination; protected EOEntity _entity; protected NSMutableArray _joins = new NSMutableArray(); protected boolean _isMandatory; protected boolean _isToMany; protected boolean _isFlattened; protected boolean _knowsIfFlattened; protected boolean _ownsDestination; protected boolean _propagatesPrimaryKey; protected boolean _useBatchFaulting; protected NSDictionary _userInfo = NSDictionary.EmptyDictionary; protected NSDictionary _internalInfo = NSDictionary.EmptyDictionary; protected NSDictionary plist; protected String _definition; public EORelationship() { super(); } public EORelationship(NSDictionary dict, Object obj) { super(); _entity = (EOEntity)obj; setName((String)dict.objectForKey("name")); setToMany("Y".equals(dict.objectForKey("isToMany"))); setPropagatesPrimaryKey("Y".equals(dict.objectForKey("propagatesPrimaryKey"))); setIsMandatory("Y".equals(dict.objectForKey("isMandatory"))); setOwnsDestination("Y".equals(dict.objectForKey("ownsDestination"))); setDefinition((String)dict.objectForKey("definition")); String delrule = (String)dict.objectForKey("deleteRule"); if (delrule != null) { if (delrule.equals("EODeleteRuleCascade")) setDeleteRule(0); else if (delrule.equals("EODeleteRuleDeny")) setDeleteRule(0); else if (delrule.equals("EODeleteRuleNoAction")) setDeleteRule(0); else if (delrule.equals("EODeleteRuleNullify")) setDeleteRule(0); } delrule = (String)dict.objectForKey("joinSemantic"); if (delrule != null) { if (delrule.equals("EOInnerJoin")) setJoinSemantic(InnerJoin); else if (delrule.equals("EOFullOuterJoin")) setJoinSemantic(FullOuterJoin); else if (delrule.equals("EOLeftOuterJoin")) setJoinSemantic(LeftOuterJoin); else if (delrule.equals("EORightOuterJoin")) setJoinSemantic(RightOuterJoin); } delrule = (String)dict.objectForKey("batchCount"); if (delrule != null) setNumberOfToManyFaultsToBatchFetch(Integer.parseInt(delrule)); NSDictionary d = (NSDictionary)dict.objectForKey("userInfo"); if (d != null) _userInfo = d; d = (NSDictionary)dict.objectForKey("internalInfo"); if (d != null) _internalInfo = d; plist = dict; } public void setName(String name) { _name = name; } public String name() { return _name; } public void addJoin(EOJoin join) { _joins.addObject(join); } public void removeJoin(EOJoin join) { _joins.removeObject(join); } public EOEntity entity() { return _entity; } public EOEntity destinationEntity() { isFlattened(); if (_destination == null && plist != null) { EOModel model = _entity.model(); EOModelGroup group = model.modelGroup(); String destEntity = (String)plist.objectForKey("destination"); if (group != null) _destination = group.entityNamed(destEntity); else _destination = model.entityNamed(destEntity); } return _destination; } public void setOwnsDestination(boolean flag) { _ownsDestination = flag; } public boolean ownsDestination() { return _ownsDestination; } public void setToMany(boolean flag) { _isToMany = flag; } public boolean isToMany() { return _isToMany; } public void setIsMandatory(boolean flag) { _isMandatory = flag; } public boolean isMandatory() { return _isMandatory; } public void setPropagatesPrimaryKey(boolean flag) { _propagatesPrimaryKey = flag; } public boolean propagatesPrimaryKey() { return _propagatesPrimaryKey; } public void setDeleteRule(int value) { _deleteRule = value; } public int deleteRule() { return _deleteRule; } public void setJoinSemantic(int value) { _joinSemantic = value; } public int joinSemantic() { return _joinSemantic; } public void setNumberOfToManyFaultsToBatchFetch(int count) { _batchCount = count; } public int numberOfToManyFaultsToBatchFetch() { return _batchCount; } public NSArray joins() { if (_joins.count() == 0 && plist != null) { NSArray joins = (NSArray)plist.objectForKey("joins"); for (int i = 0; i < joins.count(); i++) { NSDictionary d = (NSDictionary)joins.objectAtIndex(i); String srcName = (String)d.objectForKey("sourceAttribute"); String dstName = (String)d.objectForKey("destinationAttribute"); EOAttribute a1 = _entity.attributeNamed(srcName); EOAttribute a2 = destinationEntity().attributeNamed(dstName); EOJoin j = new EOJoin(a1, a2); addJoin(j); } } return new NSArray(_joins); } public void setDefinition(String def) { _definition = def; } public String definition() { return _definition; } public boolean isFlattened() { if (_knowsIfFlattened) return _isFlattened; _knowsIfFlattened = true; if (definition() == null) return false; NSArray comps = NSArray.componentsSeparatedByString(definition(), "."); if (comps.count() < 2) return false; EORelationship r = null; EOEntity e = entity(); for (int i = 0; i < comps.count(); i++) { String name = (String)comps.objectAtIndex(i); r = e.relationshipNamed(name); if (r == null) return false; e = r.destinationEntity(); } _destination = e; _isFlattened = true; return _isFlattened; } public boolean isMultiHop() { return false; } public String relationshipPath() { if (isFlattened()) return _definition; return null; } public void setUserInfo(NSDictionary value) { _userInfo = value; } public NSDictionary userInfo() { return _userInfo; } public void awakeWithPropertyList(NSDictionary plist) { } public void encodeIntoPropertyList(NSMutableDictionary dict) { dict.setObjectForKey(name(), "name"); if (destinationEntity() != null && definition() == null) dict.setObjectForKey(_destination.name(), "destination"); if (_internalInfo != null && _internalInfo.count() > 0) dict.setObjectForKey(_internalInfo, "internalInfo"); if (_userInfo != null && _userInfo.count() > 0) dict.setObjectForKey(_userInfo, "userInfo"); if (isToMany()) dict.setObjectForKey("Y", "isToMany"); switch (_joinSemantic) { case InnerJoin: dict.setObjectForKey("EOInnerJoin", "joinSemantic"); break; case FullOuterJoin: dict.setObjectForKey("EOFullOuterJoin", "joinSemantic"); break; case LeftOuterJoin: dict.setObjectForKey("EOLefOuterJoin", "joinSemantic"); break; case RightOuterJoin: dict.setObjectForKey("EORightOuterJoin", "joinSemantic"); break; } if (_batchCount > 0) dict.setObjectForKey(new Integer(_batchCount), "batchCount"); if (definition() != null) dict.setObjectForKey(definition(), "definition"); else { NSMutableArray jarr = new NSMutableArray(joins().count()); for (int i = 0; i < _joins.count(); i++) { EOJoin j = (EOJoin)_joins.objectAtIndex(i); NSDictionary d = new NSDictionary( new Object[]{ j.sourceAttribute().name(), j.destinationAttribute().name() }, new Object[]{ "sourceAttribute", "destinationAttribute" }); jarr.addObject(d); } dict.setObjectForKey(jarr, "joins"); } } } /* * $Log$ * Revision 1.2 2006/02/16 16:47:13 cgruber * Move some classes in to "internal" packages and re-work imports, etc. * * Also use UnsupportedOperationExceptions where appropriate, instead of WotonomyExceptions. * * Revision 1.1 2006/02/16 13:19:57 cgruber * Check in all sources in eclipse-friendly maven-enabled packages. * * Revision 1.5 2003/08/11 19:38:27 chochos * Can now read from a file and re-write to another file. * * Revision 1.4 2003/08/09 01:35:35 chochos * implement EOPropertyListEncoding * * Revision 1.3 2003/08/08 06:51:53 chochos * isFlattened() works * * Revision 1.2 2003/08/08 02:17:43 chochos * main accessors are in place. * * Revision 1.1 2003/08/07 02:41:30 chochos * a relationship that for the moment can be created from a property list. * */