KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > util > EntityMergeSupport


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.util;
57
58 import java.util.ArrayList JavaDoc;
59 import java.util.Collection JavaDoc;
60 import java.util.Iterator JavaDoc;
61 import java.util.List JavaDoc;
62
63 import org.objectstyle.cayenne.dba.TypesMapping;
64 import org.objectstyle.cayenne.map.DataMap;
65 import org.objectstyle.cayenne.map.DbAttribute;
66 import org.objectstyle.cayenne.map.DbEntity;
67 import org.objectstyle.cayenne.map.DbJoin;
68 import org.objectstyle.cayenne.map.DbRelationship;
69 import org.objectstyle.cayenne.map.Entity;
70 import org.objectstyle.cayenne.map.ObjAttribute;
71 import org.objectstyle.cayenne.map.ObjEntity;
72 import org.objectstyle.cayenne.map.ObjRelationship;
73 import org.objectstyle.cayenne.project.NamedObjectFactory;
74
75 /**
76  * Implements methods for entity merging.
77  *
78  * @author Andrei Adamchik
79  */

80 public class EntityMergeSupport {
81
82     protected DataMap map;
83
84     public EntityMergeSupport(DataMap map) {
85         this.map = map;
86     }
87     
88
89     /**
90      * Updates each one of the collection of ObjEntities, adding attributes and relationships
91      * based on the current state of its DbEntity.
92      *
93      * @since 1.2 changed signature to use Collection instead of List.
94      */

95     public void synchronizeWithDbEntities(Collection JavaDoc objEntities) {
96         Iterator JavaDoc it = objEntities.iterator();
97         while (it.hasNext()) {
98             this.synchronizeWithDbEntity((ObjEntity) it.next());
99         }
100     }
101
102     /**
103      * Updates ObjEntity attributes and relationships based on the current state of its
104      * DbEntity.
105      */

106     public void synchronizeWithDbEntity(ObjEntity entity) {
107
108         if (entity == null || entity.getDbEntity() == null) {
109             return;
110         }
111
112         // synchronization on DataMap is some (weak) protection
113
// against simulteneous modification of the map (like double-clicking on sync
114
// button)
115
synchronized (map) {
116             List JavaDoc removeAttributes = getAttributesToRemove(entity);
117             
118             // get rid of attributes that are now src attributes for relationships
119
Iterator JavaDoc rait = removeAttributes.iterator();
120             while (rait.hasNext()) {
121                 DbAttribute da = (DbAttribute) rait.next();
122                 ObjAttribute oa = entity.getAttributeForDbAttribute(da);
123                 while (oa != null){
124                     String JavaDoc attrName = oa.getName();
125                     entity.removeAttribute(attrName);
126                     oa = entity.getAttributeForDbAttribute(da);
127                 }
128             }
129             
130             List JavaDoc addAttributes = getAttributesToAdd(entity);
131
132             // add missing attributes
133
Iterator JavaDoc ait = addAttributes.iterator();
134             while (ait.hasNext()) {
135                 DbAttribute da = (DbAttribute) ait.next();
136                 String JavaDoc attrName = NameConverter.undescoredToJava(da.getName(), false);
137
138                 // avoid duplicate names
139
attrName = NamedObjectFactory.createName(
140                         ObjAttribute.class,
141                         entity,
142                         attrName);
143
144                 String JavaDoc type = TypesMapping.getJavaBySqlType(da.getType());
145
146                 ObjAttribute oa = new ObjAttribute(attrName, type, entity);
147                 oa.setDbAttribute(da);
148                 entity.addAttribute(oa);
149             }
150             
151             List JavaDoc addRelationships = getRelationshipsToAdd(entity);
152
153             // add missing relationships
154
Iterator JavaDoc rit = addRelationships.iterator();
155             while (rit.hasNext()) {
156                 DbRelationship dr = (DbRelationship) rit.next();
157                 DbEntity dbEntity = (DbEntity) dr.getTargetEntity();
158
159                 Iterator JavaDoc targets = map.getMappedEntities(dbEntity).iterator();
160                 if (targets.hasNext()) {
161
162                     Entity mappedTarget = (Entity) targets.next();
163
164                     // avoid duplicate names
165
String JavaDoc relationshipName = NameConverter.undescoredToJava(dr.getName(), false);
166                     relationshipName = NamedObjectFactory.createName(
167                             ObjRelationship.class,
168                             entity,
169                             relationshipName);
170
171                     ObjRelationship or = new ObjRelationship(relationshipName);
172                     or.addDbRelationship(dr);
173                     or.setSourceEntity(entity);
174                     or.setTargetEntity(mappedTarget);
175                     entity.addRelationship(or);
176                 }
177             }
178         }
179     }
180
181     /**
182      * Returns a list of src attributes for the DbEntity relationships (Foreign Keys),
183      * these do not need to be attributes of the ObjEntity.
184      *
185      * @since 1.2
186      */

187     protected List JavaDoc getAttributesToRemove(ObjEntity objEntity){
188         List JavaDoc removeList = new ArrayList JavaDoc();
189         Iterator JavaDoc it = objEntity.getDbEntity().getRelationships().iterator();
190         while (it.hasNext()) {
191             DbRelationship dbrel = (DbRelationship) it.next();
192             
193             // check if adding it makes sense at all
194
if (dbrel.getName() == null) {
195                 continue;
196             }
197
198             // get all of the srcAttributes for the relationship
199
Iterator JavaDoc srcAttIterator = dbrel.getSourceAttributes().iterator();
200             while(srcAttIterator.hasNext()){
201                 removeList.add(srcAttIterator.next());
202             }
203         }
204         
205         return removeList;
206     }
207
208     /**
209      * Returns a list of attributes that exist in the DbEntity, but are missing from the
210      * ObjEntity.
211      */

212     protected List JavaDoc getAttributesToAdd(ObjEntity objEntity) {
213         List JavaDoc missing = new ArrayList JavaDoc();
214         Iterator JavaDoc it = objEntity.getDbEntity().getAttributes().iterator();
215         Collection JavaDoc rels = objEntity.getDbEntity().getRelationships();
216
217         while (it.hasNext()) {
218             DbAttribute dba = (DbAttribute) it.next();
219             // already there
220
if (objEntity.getAttributeForDbAttribute(dba) != null) {
221                 continue;
222             }
223
224             // check if adding it makes sense at all
225
if (dba.getName() == null || dba.isPrimaryKey()) {
226                 continue;
227             }
228
229             // check FK's
230
boolean isFK = false;
231             Iterator JavaDoc rit = rels.iterator();
232             while (!isFK && rit.hasNext()) {
233                 DbRelationship rel = (DbRelationship) rit.next();
234                 Iterator JavaDoc jit = rel.getJoins().iterator();
235                 while (jit.hasNext()) {
236                     DbJoin join = (DbJoin) jit.next();
237                     if (join.getSource() == dba) {
238                         isFK = true;
239                         break;
240                     }
241                 }
242             }
243
244             if (isFK) {
245                 continue;
246             }
247
248             missing.add(dba);
249         }
250
251         return missing;
252     }
253
254     protected List JavaDoc getRelationshipsToAdd(ObjEntity objEntity) {
255         List JavaDoc missing = new ArrayList JavaDoc();
256         Iterator JavaDoc it = objEntity.getDbEntity().getRelationships().iterator();
257         while (it.hasNext()) {
258             DbRelationship dbrel = (DbRelationship) it.next();
259             // check if adding it makes sense at all
260
if (dbrel.getName() == null) {
261                 continue;
262             }
263
264             if (objEntity.getRelationshipForDbRelationship(dbrel) == null) {
265                 missing.add(dbrel);
266             }
267         }
268
269         return missing;
270     }
271     
272     public DataMap getMap() {
273         return map;
274     }
275
276     public void setMap(DataMap map) {
277         this.map = map;
278     }
279 }
Popular Tags