KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > metadata > torque > TorqueForeignKeyGenerator


1 package org.apache.ojb.broker.metadata.torque;
2
3 /* Copyright 2002-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import org.apache.ojb.broker.metadata.ClassDescriptor;
19 import org.apache.ojb.broker.metadata.CollectionDescriptor;
20 import org.apache.ojb.broker.metadata.DescriptorRepository;
21 import org.apache.ojb.broker.metadata.FieldDescriptor;
22 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
23 import org.apache.ojb.broker.util.logging.Logger;
24 import org.apache.ojb.broker.util.logging.LoggerFactory;
25
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.Vector JavaDoc;
29
30 public class TorqueForeignKeyGenerator {
31     private final Logger logger = LoggerFactory.getLogger(this.getClass());
32     private DescriptorRepository repository;
33     private HashMap JavaDoc mappingTables = new HashMap JavaDoc();
34     private HashMap JavaDoc foreignKeyVectors = new HashMap JavaDoc();
35
36     public TorqueForeignKeyGenerator(DescriptorRepository repository) {
37         this.repository = repository;
38     }
39
40     public void buildConstraintsMap() {
41         Iterator JavaDoc classDescriptorIterators = this.repository.iterator();
42         while (classDescriptorIterators.hasNext()) {
43             ClassDescriptor cd = (ClassDescriptor) classDescriptorIterators.next();
44             if(cd.isAbstract() || cd.isInterface())
45             {
46                 logger.debug( "Skip constraint build for abstract class/ interface " + cd.getClassNameOfObject() );
47             }
48             else
49             {
50                 buildConstraints(cd);
51                 buildOneToOneConstraints(cd);
52             }
53         }
54     }
55
56     public Vector JavaDoc getForeignKeysForTable(String JavaDoc tableName) {
57         return (Vector JavaDoc) this.foreignKeyVectors.get(tableName);
58     }
59
60     public HashMap JavaDoc getMappingTables() {
61         return this.mappingTables;
62     }
63
64     private void buildTableFieldDescriptors(FieldDescriptor fieldDescriptors[], TableDescriptor tableDescriptor) {
65         for (int i = 0; i < fieldDescriptors.length; i++) {
66             tableDescriptor.addColumn(fieldDescriptors[i]);
67         }
68     }
69
70     private void buildConstraints(ClassDescriptor cd) {
71         Vector JavaDoc collectionDescriptors = cd.getCollectionDescriptors();
72         for (int i = 0; i < collectionDescriptors.size(); i++) {
73             CollectionDescriptor collectionDescriptor = (CollectionDescriptor) collectionDescriptors.get(i);
74             if (collectionDescriptor.isMtoNRelation()) {
75                 buildManyToManyConstraints(cd, collectionDescriptor);
76             } else {
77                 buildOneToManyReferences(cd, collectionDescriptor);
78             }
79         }
80     }
81
82     private void buildManyToManyConstraints(ClassDescriptor cd, CollectionDescriptor collectionDescriptor) {
83         Vector JavaDoc columns = new Vector JavaDoc();
84
85         ClassDescriptor itemDescriptor = this.repository.getDescriptorFor(collectionDescriptor.getItemClass());
86         buildManyToManyReferences(cd, collectionDescriptor, collectionDescriptor.getFksToThisClass(), columns);
87         buildManyToManyReferences(itemDescriptor, collectionDescriptor, collectionDescriptor.getFksToItemClass(), columns);
88
89         if (isImplicitlyMapped(collectionDescriptor.getIndirectionTable())) {
90             TableDescriptor mappingTable = new TableDescriptor();
91             buildTableFieldDescriptors((FieldDescriptor[]) columns.toArray(new FieldDescriptor[0]), mappingTable);
92             mappingTable.setName(collectionDescriptor.getIndirectionTable());
93             this.mappingTables.put(mappingTable.getName(), mappingTable);
94         }
95     }
96
97     private void buildManyToManyReferences(ClassDescriptor cd, CollectionDescriptor collectionDescriptor,
98                                            Object JavaDoc keys[], Vector JavaDoc columns)
99     {
100         if(cd.isAbstract() || cd.isInterface())
101         {
102             logger.debug( "Skip foreign key build for MtoM, found abstract base class or interface " + cd.getClassNameOfObject() );
103             return;
104         }
105         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(256);
106         buildForeignKeyHeader(cd.getFullTableName(), buffer);
107
108         for (int i = 0; i < keys.length; i++) {
109             String JavaDoc columnName = (String JavaDoc) keys[i];
110
111             FieldDescriptor foreignColumn = cd.getPkFields()[i];
112             String JavaDoc foreignColumnName = foreignColumn.getPersistentField().getName();
113             buildReferenceForColumn(buffer, columnName, foreignColumnName);
114             FieldDescriptor fieldDescriptor = (FieldDescriptor)foreignColumn.clone();
115             fieldDescriptor.setColumnName(columnName);
116             columns.add(fieldDescriptor);
117         }
118         buffer.append(" </foreign-key>\n");
119
120         addReferenceToTable(collectionDescriptor.getIndirectionTable(), buffer.toString());
121     }
122
123     private void buildOneToManyReferences(ClassDescriptor cd, CollectionDescriptor collectionDescriptor) {
124         Vector JavaDoc foreignKeyIndices = collectionDescriptor.getForeignKeyFields();
125         ClassDescriptor foreignKeyClassDescriptor = this.repository.getDescriptorFor(collectionDescriptor.getItemClass());
126         buildForeignKey(cd, foreignKeyIndices, foreignKeyClassDescriptor);
127     }
128
129
130     private void buildOneToOneConstraints(ClassDescriptor classDescriptor) {
131         Vector JavaDoc referenceDescriptors = classDescriptor.getObjectReferenceDescriptors();
132         for (int i = 0; i < referenceDescriptors.size(); i++) {
133             ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) referenceDescriptors.get(i);
134
135             Vector JavaDoc foreignKeyIndices = ord.getForeignKeyFields();
136             ClassDescriptor foreignClassDescriptor = this.repository.getDescriptorFor(ord.getItemClass());
137             buildForeignKey(foreignClassDescriptor, foreignKeyIndices, classDescriptor);
138         }
139     }
140
141     private void buildForeignKey(ClassDescriptor foreignClassDescriptor, Vector JavaDoc foreignKeyIndices, ClassDescriptor classDescriptor) {
142
143         if(classDescriptor.isAbstract() || classDescriptor.isInterface())
144         {
145             logger.debug( "Skip foreign key build, found abstract base class or interface " + classDescriptor.getClassNameOfObject() );
146             return;
147         }
148         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(256);
149         buildForeignKeyHeader(foreignClassDescriptor.getFullTableName(), buffer);
150
151         for (int i = 0; i < foreignKeyIndices.size(); i++) {
152             String JavaDoc columnName = null;
153             Object JavaDoc obj = foreignKeyIndices.get(i);
154
155             if (obj instanceof Integer JavaDoc)
156             {
157                 int foreignKeyIndex = ((Integer JavaDoc) obj).intValue();
158                 columnName = classDescriptor.getFieldDescriptorByIndex(foreignKeyIndex).getColumnName();
159             }
160             else
161             {
162                     FieldDescriptor fld = classDescriptor.getFieldDescriptorByName((String JavaDoc) obj);
163                     if(fld == null)
164                     {
165                         logger.debug( "FieldDescriptor for foreign key parameter \n" + obj + " was not found in ClassDescriptor \n" + classDescriptor );
166                     }
167                     else columnName = fld.getColumnName();
168             }
169
170             FieldDescriptor foreignColumn = foreignClassDescriptor.getPkFields()[i];
171             String JavaDoc foreignColumnName = foreignColumn.getColumnName();
172             buildReferenceForColumn(buffer, columnName, foreignColumnName);
173         }
174         buffer.append(" </foreign-key>\n");
175         addReferenceToTable(classDescriptor.getFullTableName(), buffer.toString());
176     }
177
178     private void buildForeignKeyHeader(String JavaDoc foreignClassName, StringBuffer JavaDoc buffer) {
179         buffer.append(" <foreign-key foreignTable=\"");
180         buffer.append(foreignClassName);
181         buffer.append("\">\n");
182     }
183
184     private void buildReferenceForColumn(StringBuffer JavaDoc buffer, String JavaDoc columnName, String JavaDoc foreignColumnName) {
185         buffer.append(" <reference local=\"");
186         buffer.append(columnName);
187         buffer.append("\" foreign=\"");
188         buffer.append(foreignColumnName);
189         buffer.append("\"/>\n");
190     }
191
192
193     private boolean isImplicitlyMapped(String JavaDoc tableName) {
194         Iterator JavaDoc classDescriptorIterator = repository.iterator();
195
196         while (classDescriptorIterator.hasNext()) {
197             ClassDescriptor cd = (ClassDescriptor) classDescriptorIterator.next();
198             if (tableName.equals(cd.getFullTableName())) {
199                 return false;
200             }
201         }
202
203         return true;
204     }
205
206     private void addReferenceToTable(String JavaDoc tableName, String JavaDoc reference) {
207         Vector JavaDoc tableReferences = (Vector JavaDoc) this.foreignKeyVectors.get(tableName);
208         if (tableReferences == null) {
209             tableReferences = new Vector JavaDoc();
210             this.foreignKeyVectors.put(tableName, tableReferences);
211
212         }
213         if (!tableReferences.contains(reference)) {
214             tableReferences.add(reference);
215         }
216     }
217 }
218
Popular Tags