1 ${database.allClassCopyright}package ${glPackageBaseCommonDBMetaHierarchy};
\r
3 #set ($myClassName = "${glHierarchyArrangerName}")
\r
5 import java.lang.reflect.Method;
\r
6 import java.util.ArrayList;
\r
7 import java.util.HashMap;
\r
8 import java.util.List;
\r
9 import java.util.Map;
\r
10 import java.util.Set;
\r
12 import ${glPackageBaseCommon}.${glEntityInterfaceName};
\r
13 import ${glPackageBaseCommonDBMeta}.${glDBMetaInterfaceName};
\r
14 import ${glPackageBaseCommonDBMetaInfo}.${glColumnInfoName};
\r
15 import ${glPackageBaseCommonDBMetaInfo}.${glForeignInfoName};
\r
16 import ${glPackageBaseCommonDBMetaInfo}.${glReferrerInfoName};
\r
17 import ${glPackageBaseCommonDBMetaInfo}.${glRelationInfoName};
\r
20 * The arranger of hierarchy.
\r
22 * ex) LIBRARY Hierarchy
\r
26 * |--* NEXT_LIBRARY (Referrer)
\r
28 * | |--1 LIBRARY (Foreign)
\r
30 * |--* COLLECTION (Referrer)
\r
32 * | |--1 COLLECTION_STATUS (Referrer)
\r
34 * | | |--1 COLLECTION_STATUS_LOOKUP (Foreign)
\r
36 * | |--1 BOOK (Foreign)
\r
38 * | | |--1 AUTHOR (Foreign)
\r
39 * | | |--1 PUBLISER (Foreign)
\r
40 * | | |--1 GENRE (Foreign)
\r
42 * | | |--1 GENRE (Foreign)
\r
44 * | |--* LENDING_COLLECTION (Referrer)
\r
47 * |--* LIBRARY_USER (Referrer)
\r
49 * | |--* LENDING (Referrer)
\r
51 * | |--* LENDING_COLLECTION (Referrer)
\r
53 * |--1 LB_USER (Foreign)
\r
55 * |--* BLACK_LIST (Referrer)
\r
57 * |--* BLACK_ACTION (Referrer)
\r
59 * |--1 BLACK_ACTION_LOOKUP (Foreign)
\r
62 * ex) The SQL of LIBRARY Hierarchy as FLAT
\r
64 * select library.LIBRARY_ID as LIBRARY_ID
\r
65 * , library.LIBRARY_NAME as LIBRARY_NAME
\r
66 * , library.R_USER as R_USER
\r
67 * , library.R_TIMESTAMP as R_TIMESTAMP
\r
68 * , nextBase.LIBRARY_ID as BASE_LIBRARY_ID
\r
69 * , nextBase.NEXT_LIBRARY_ID as NEXT_LIBRARY_ID
\r
70 * , nextBaseNextLibrary.LIBRARY_ID as NEXT_LIBRARY_NEXT_LIBRARY_ID
\r
71 * , nextBaseNextLibrary.LIBRARY_NAME as NEXT_LIBRARY_NEXT_LIBRARY_NAME
\r
72 * , collection.COLLECTION_ID as COLLECTION_ID
\r
73 * , collection.ARRIVAL_DATE as COLLECTION_ARRIVAL_DATE
\r
74 * , collectionStatus.COLLECTION_ID as COLLECTION_STATUS_ID
\r
75 * , collectionStatus.COLLECTION_STATUS_CODE as COLLECTION_STATUS_CODE
\r
76 * , collectionStatusLookup.COLLECTION_STATUS_CODE as COLLECTION_STATUS_CODE
\r
77 * , collectionStatusLookup.COLLECTION_STATUS_NAME as COLLECTION_STATUS_NAME
\r
78 * , book.BOOK_ID as COLLECTION_BOOK_ID
\r
79 * , book.BOOK_NAME as COLLECTION_BOOK_NAME
\r
80 * , author.AUTHOR_ID as COLLECTION_BOOK_AUTHOR_ID
\r
81 * , author.AUTHOR_NAME as COLLECTION_BOOK_AUTHOR_NAME
\r
82 * , libraryUser.LIBRARY_ID as LIBRARY_USER_LIBRARY_ID
\r
83 * , libraryUser.LB_USER_ID as LIBRARY_USER_LB_USER_ID
\r
84 * , lending.LIBRARY_ID as LENDING_LIBRARY_ID
\r
85 * , lending.LB_USER_ID as LENDING_LB_USER_ID
\r
86 * , lending.LENDING_DATE as LENDING_DATE
\r
87 * , lending.U_USER as LENDING_U_USER
\r
88 * , lending.U_MODULE as LENDING_U_MODULE
\r
89 * , lbUser.LB_USER_ID as LB_USER_ID
\r
90 * , lbUser.LB_USER_NAME as LB_USER_NAME
\r
91 * from LIBRARY library
\r
92 * left outer join NEXT_LIBRARY nextBase on library.LIBRARY_ID = nextBase.LIBRARY_ID
\r
93 * left outer join LIBRARY nextBaseNextLibrary on nextBase.NEXT_LIBRARY_ID = nextBaseNextLibrary.LIBRARY_ID
\r
94 * left outer join COLLECTION collection on library.LIBRARY_ID = collection.LIBRARY_ID
\r
95 * left outer join COLLECTION_STATUS collectionStatus on collection.COLLECTION_ID = collectionStatus.COLLECTION_ID
\r
96 * left outer join COLLECTION_STATUS_LOOKUP collectionStatusLookup on collectionStatus.COLLECTION_STATUS_CODE = collectionStatusLookup.COLLECTION_STATUS_CODE
\r
97 * left outer join BOOK book on collection.BOOK_ID = book.BOOK_ID
\r
98 * left outer join AUTHOR author on book.AUTHOR_ID = author.AUTHOR_ID
\r
99 * left outer join LIBRARY_USER libraryUser on library.LIBRARY_ID = libraryUser.LIBRARY_ID
\r
100 * left outer join LENDING lending on libraryUser.LIBRARY_ID = lending.LIBRARY_ID and libraryUser.LB_USER_ID = lending.LB_USER_ID
\r
101 * left outer join LB_USER lbUser on libraryUser.LB_USER_ID = lbUser.LB_USER_ID
\r
104 * ex) Invoking Hierarchy Arranger
\r
106 * private List<Library> makeLibraryList() {
\r
107 * final HierarchyRequest<Library> request = createHierarchyRequest(createFlatLibraryList());
\r
108 * return new HierarchyArranger<Library>().arrangeHierarchy(request);
\r
112 * ex) Creating Hierarchy Request
\r
114 * private HierarchyRequest<Library> createHierarchsyRequest(java.util.List>HierarchyFlatLibrary> flatLibraryList) {
\r
116 * // Define dbmeta.
\r
117 * final HierarchyFlatLibraryDbm sourceDbm = HierarchyFlatLibraryDbm.getInstance();
\r
119 * // Define hierarychy request as library.
\r
120 * final HierarchyRequest<Library> request = new HierarchyRequest<Library>(Library.class);
\r
122 * // Register the list of source iterator. (by calling creator for flat library list)
\r
123 * request.registerSourceList(flatLibraryList);
\r
125 * // Create relation trace.
\r
126 * final LibraryRelationTrace trace = LibraryDbm.getInstance().createRelationTrace(null);
\r
128 * // Register column [libraryId]
\r
129 * request.mapping(sourceDbm.columnLibraryId(), trace.columnLibraryId());
\r
131 * // Register column [libraryName]
\r
132 * request.mapping(sourceDbm.columnLibraryName(), trace.columnLibraryName());
\r
134 * // Register column [RUser]
\r
135 * request.mapping(sourceDbm.columnRUser(), trace.columnRUser());
\r
137 * // Register column [RTimestamp]
\r
138 * request.mapping(sourceDbm.columnRTimestamp(), trace.columnRTimestamp());
\r
140 * // Register column [baseLibraryId]
\r
141 * request.mapping(sourceDbm.columnBaseLibraryId(), trace.referrerNextLibraryByBaseIdList().columnLibraryId());
\r
143 * // Register column [nextLibraryId]
\r
144 * request.mapping(sourceDbm.columnNextLibraryId(), trace.referrerNextLibraryByBaseIdList().columnNextLibraryId());
\r
146 * // Register column [nextLibraryNextLibraryId]
\r
147 * request.mapping(sourceDbm.columnNextLibraryNextLibraryId(), trace.referrerNextLibraryByBaseIdList().foreignLibraryByNextId().columnLibraryId());
\r
149 * // Register column [nextLibraryNextLibraryName]
\r
150 * request.mapping(sourceDbm.columnNextLibraryNextLibraryName(), trace.referrerNextLibraryByBaseIdList().foreignLibraryByNextId().columnLibraryName());
\r
152 * // Register column [collectionId]
\r
153 * request.mapping(sourceDbm.columnCollectionId(), trace.referrerCollectionList().columnCollectionId());
\r
155 * // Register column [arrivalDate]
\r
156 * request.mapping(sourceDbm.columnCollectionArrivalDate(), trace.referrerCollectionList().columnArrivalDate());
\r
158 * // Register column [collectionStatusId]
\r
159 * request.mapping(sourceDbm.columnCollectionStatusId(), trace.referrerCollectionList().foreignCollectionStatusAsOne().columnCollectionId());
\r
161 * // Register column [collectionStatusCode]
\r
162 * request.mapping(sourceDbm.columnCollectionStatusCode(), trace.referrerCollectionList().foreignCollectionStatusAsOne().foreignCollectionStatusLookup().columnCollectionStatusCode());
\r
164 * // Register column [collectionStatusName]
\r
165 * request.mapping(sourceDbm.columnCollectionStatusName(), trace.referrerCollectionList().foreignCollectionStatusAsOne().foreignCollectionStatusLookup().columnCollectionStatusName());
\r
167 * // Register column [collectionBookId]
\r
168 * request.mapping(sourceDbm.columnCollectionBookId(), trace.referrerCollectionList().foreignBook().columnBookId());
\r
170 * // Register column [collectionBookName]
\r
171 * request.mapping(sourceDbm.columnCollectionBookName(), trace.referrerCollectionList().foreignBook().columnBookName());
\r
173 * // Register column [collectionBookAuthorId]
\r
174 * request.mapping(sourceDbm.columnCollectionBookAuthorId(), trace.referrerCollectionList().foreignBook().foreignAuthor().columnAuthorId());
\r
176 * // Register column [collectionBookAuthorName]
\r
177 * request.mapping(sourceDbm.columnCollectionBookAuthorName(), trace.referrerCollectionList().foreignBook().foreignAuthor().columnAuthorName());
\r
179 * // Register column [libraryUserLibraryId]
\r
180 * request.mapping(sourceDbm.columnLibraryUserLibraryId(), trace.referrerLibraryUserList().columnLibraryId());
\r
182 * // Register column [libraryUserLbUserId]
\r
183 * request.mapping(sourceDbm.columnLibraryUserLbUserId(), trace.referrerLibraryUserList().columnLbUserId());
\r
185 * // Register column [lendingLibraryId]
\r
186 * request.mapping(sourceDbm.columnLendingLibraryId(), trace.referrerLibraryUserList().referrerLendingList().columnLibraryId());
\r
188 * // Register column [lendingLbUserId]
\r
189 * request.mapping(sourceDbm.columnLendingLbUserId(), trace.referrerLibraryUserList().referrerLendingList().columnLbUserId());
\r
191 * // Register column [lendingDate]
\r
192 * request.mapping(sourceDbm.columnLendingDate(), trace.referrerLibraryUserList().referrerLendingList().columnLendingDate());
\r
194 * // Register column [lendingUUser]
\r
195 * request.mapping(sourceDbm.columnLendingUUser(), trace.referrerLibraryUserList().referrerLendingList().columnUUser());
\r
197 * // Register column [lendingUModule]
\r
198 * request.mapping(sourceDbm.columnLendingUModule(), trace.referrerLibraryUserList().referrerLendingList().columnUModule());
\r
200 * // Register column [lbUserId]
\r
201 * request.mapping(sourceDbm.columnLbUserId(), trace.referrerLibraryUserList().foreignLbUser().columnLbUserId());
\r
203 * // Register column [lbUserName]
\r
204 * request.mapping(sourceDbm.columnLbUserName(), trace.referrerLibraryUserList().foreignLbUser().columnLbUserName());
\r
209 * private java.util.List>HierarchyFlatLibrary> createFlatLibraryList() {
\r
210 * (...select and get list)
\r
211 * return flatLibraryList;
\r
215 * === Relation Trace Tips ===
\r
217 * RelationTrace.f + [Code Assist] -- go to Foreign
\r
218 * RelationTrace.r + [Code Assist] -- go to Referrer
\r
219 * RelationTrace.c + [Code Assist] -- end relation by Column
\r
223 * @author ${database.ClassAuthor}
\r
224 * @param <LOCAL_ENTITY> The type of local entity extends Entity
\r
225 */${database.outputSuppressWarningsAfterLineSeparator()}
\r
226 public class ${myClassName}<LOCAL_ENTITY extends ${glEntityInterfaceName}> {
\r
228 // ===================================================================================
\r
232 * Arrange hierarchy.
\r
234 * @param request Hierarchy request. (NotNull)
\r
235 * @return The list of local entity. (NotNull)
\r
237 public List<LOCAL_ENTITY> arrangeHierarchy(${glHierarchyRequestName}<LOCAL_ENTITY> request) {
\r
238 final List<LOCAL_ENTITY> localTableList = new ArrayList<LOCAL_ENTITY>();
\r
239 final Map<String, ${glEntityInterfaceName}> alreadyRegisteredEntityMap = new HashMap<String, ${glEntityInterfaceName}>();
\r
244 final ${glHierarchySourceIteratorName} sourceIterator = request.getSourceIterator();
\r
245 while (sourceIterator.hasNext()) {
\r
246 final ${glHierarchySourceRowName} sourceRow = sourceIterator.next();
\r
247 final TopInfo<LOCAL_ENTITY> topInfo = new TopInfo<LOCAL_ENTITY>();
\r
248 topInfo.setHierarchyRequest(request);
\r
249 topInfo.setSourceRow(sourceRow);
\r
250 topInfo.setAlreadyRegisteredEntityMap(alreadyRegisteredEntityMap);
\r
252 final Map<String, Object> primaryKeyMap = extractTopPrimaryKeyMapFromSource(topInfo);
\r
253 final String alreadyRegisteredKey = buildTopAlreadyRegisteredKey(primaryKeyMap);
\r
254 if (alreadyRegisteredEntityMap.containsKey(alreadyRegisteredKey)) {
\r
255 final ${glEntityInterfaceName} localEntity = alreadyRegisteredEntityMap.get(alreadyRegisteredKey);
\r
256 topInfo.setLocalEntity(localEntity);
\r
258 // Make local entity and register it to the result list.
\r
259 final LOCAL_ENTITY localEntity = newLocalEntity(request.getDestinationDBMeta());
\r
260 topInfo.setLocalEntity(localEntity);
\r
261 localTableList.add(localEntity);
\r
262 alreadyRegisteredEntityMap.put(alreadyRegisteredKey, localEntity);
\r
268 doColumnLoop(topInfo);
\r
271 // Clear modified properties.
\r
272 final java.util.Set<String> alreadyRegisteredEntityKeySet = alreadyRegisteredEntityMap.keySet();
\r
273 for (String key : alreadyRegisteredEntityKeySet) {
\r
274 final ${glEntityInterfaceName} currentRegisteredEntity = alreadyRegisteredEntityMap.get(key);
\r
275 currentRegisteredEntity.clearModifiedPropertyNames();
\r
278 return localTableList;
\r
282 * Build top already-registered key.
\r
284 * @param primaryKeyMap The map of primary key. (NotNull)
\r
285 * @return Top already-registered key. (NotNull)
\r
287 protected String buildTopAlreadyRegisteredKey(Map<String, Object> primaryKeyMap) {
\r
288 return ${glHierarchyRequestElementName}.TOP_KEY + ":" + primaryKeyMap;
\r
294 * @param topInfo The information object of top that has generics of the type of local entity. (NotNull)
\r
296 protected void doColumnLoop(TopInfo<LOCAL_ENTITY> topInfo) {
\r
297 final ${glHierarchyRequestName}<LOCAL_ENTITY> request = topInfo.getHierarchyRequest();
\r
298 final ${glEntityInterfaceName} localEntity = topInfo.getLocalEntity();
\r
299 final List<${glHierarchyRequestElementName}> requestElementList = request.getRequestElementList();
\r
304 for (${glHierarchyRequestElementName} requestElement : requestElementList) {
\r
305 final List<String> relationPropertyNameList = requestElement.getRelationPropertyNameList();
\r
307 // If the column belongs to local entity, inject the value to entity and continue loop.
\r
308 if (relationPropertyNameList == null || relationPropertyNameList.isEmpty()) {
\r
309 final ${glHierarchySourceColumnName} sourceColumn = requestElement.getSourceColumnInfo();
\r
310 final ${glHierarchySourceRowName} sourceRow = topInfo.getSourceRow();
\r
311 final Object sourceColumnValue = extractColumnValueFromSource(sourceRow, sourceColumn);
\r
312 final ${glColumnInfoName} destinationColumnInfo = requestElement.getDestinationColumnInfo();
\r
313 injectColumnValueToDestinationIfNotNull(localEntity, destinationColumnInfo, sourceColumnValue);
\r
320 doRelationLoop(topInfo, requestElement, relationPropertyNameList);
\r
325 * Do relation loop.
\r
327 * @param topInfo The information object of top that has generics of local entity. (NotNull)
\r
328 * @param requestElement The element of request. This is relation loop resource. (NotNull)
\r
329 * @param relationPropNameList The list of relation property name that has generics of string. (NotNull)
\r
331 protected void doRelationLoop(TopInfo<LOCAL_ENTITY> topInfo, ${glHierarchyRequestElementName} requestElement, java.util.List<String> relationPropNameList) {
\r
332 final ${glHierarchyRequestName}<LOCAL_ENTITY> request = topInfo.getHierarchyRequest();
\r
333 final Map<String, ${glEntityInterfaceName}> alreadyRegisteredEntityMap = topInfo.getAlreadyRegisteredEntityMap();
\r
335 // Temporary variables for local
\r
336 ${glEntityInterfaceName} localEntity = topInfo.getLocalEntity();// as Default
\r
337 ${glDBMetaInterfaceName} localDBMeta = request.getDestinationDBMeta();// as Default
\r
338 String localRelationPath = ${glHierarchyRequestElementName}.TOP_KEY;// as Default
\r
343 final StringBuilder relationPropKeyStringBuilder = new StringBuilder();
\r
344 int relationLoopCount = 0;
\r
345 for (String relationPropName : relationPropNameList) {
\r
346 if (relationPropKeyStringBuilder.length() > 0) {
\r
347 relationPropKeyStringBuilder.append("_");
\r
349 relationPropKeyStringBuilder.append(relationPropName);
\r
350 final String targetRelationPath = relationPropKeyStringBuilder.toString();
\r
351 final ${glRelationInfoName} relationInfo = localDBMeta.findRelationInfo(relationPropName);
\r
353 final Map<String, Object> targetPrimaryKeyMap;
\r
354 final String alreadyRegisteredEntityKey;
\r
355 if (!relationInfo.isReferrer()) {
\r
359 final ${glForeignInfoName} foreignInfo = localDBMeta.findForeignInfo(relationPropName);
\r
360 final String foreignPropName = foreignInfo.getForeignPropertyName();
\r
362 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
363 // If the value of primary key does not exist, break this relation path!
\r
364 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
365 if (isNotExistPrimaryKey(topInfo, targetRelationPath)) {
\r
369 targetPrimaryKeyMap = extractPrimaryKeyMapFromSource(topInfo, targetRelationPath);
\r
370 alreadyRegisteredEntityKey = targetRelationPath + ":" + targetPrimaryKeyMap.toString();
\r
371 if (!alreadyRegisteredEntityMap.containsKey(alreadyRegisteredEntityKey)) {
\r
372 // - - - - - - - - - - - - - - - - - - - - - - -
\r
373 // Initialize the foreign entity and inject it.
\r
374 // - - - - - - - - - - - - - - - - - - - - - - -
\r
375 final ${glEntityInterfaceName} foreignEntity = foreignInfo.getForeignDBMeta().newEntity();
\r
376 injectForeignEntity(localEntity, foreignPropName, foreignEntity);
\r
378 // - - - - - - - - - - - - - - - - - -
\r
379 // Initialize primary key of foreign.
\r
380 // - - - - - - - - - - - - - - - - - -
\r
381 injectForeignPrimaryKey(foreignEntity, targetPrimaryKeyMap);
\r
383 // - - - - - - - - - - - - - - - - - -
\r
384 // Initialize foreign key of local.
\r
385 // - - - - - - - - - - - - - - - - - -
\r
386 injectLocalForeignKey(topInfo, localEntity, foreignInfo, targetRelationPath);
\r
388 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
389 // Put foreign entity to the map of already-registered-entity.
\r
390 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
391 alreadyRegisteredEntityMap.put(alreadyRegisteredEntityKey.toString(), foreignEntity);
\r
393 // - - - - - - - - - - - - - -
\r
394 // Inject the foreign entity.
\r
395 // - - - - - - - - - - - - - -
\r
396 final ${glEntityInterfaceName} foreignEntity = alreadyRegisteredEntityMap.get(alreadyRegisteredEntityKey);
\r
397 injectForeignEntity(localEntity, foreignPropName, foreignEntity);
\r
403 final ${glReferrerInfoName} referrerInfo = localDBMeta.findReferrerInfo(relationPropName);
\r
405 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
406 // Extract referrer list from current local entity and initialize it if needs.
\r
407 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
408 List<${glEntityInterfaceName}> referrerList = extractReferrerList(localEntity, referrerInfo);
\r
409 if (referrerList == null) {
\r
410 #if (!$database.isOneToManyReturnNullIfNonSelect())
\r
411 String msg = "The referrer list should not be null: localEntity=" + localEntity + " referrerInfo=" + referrerInfo;
\r
412 throw new IllegalStateException(msg);
\r
414 // Initialize the list of referrer and inject it.
\r
415 referrerList = new ArrayList<${glEntityInterfaceName}>();
\r
416 injectReferrerList(localEntity, referrerInfo, referrerList);
\r
420 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
421 // If the value of primary key does not exist, break this relation path!
\r
422 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
423 if (isNotExistPrimaryKey(topInfo, targetRelationPath)) {
\r
427 targetPrimaryKeyMap = extractPrimaryKeyMapFromSource(topInfo, targetRelationPath);
\r
428 alreadyRegisteredEntityKey = targetRelationPath + ":" + targetPrimaryKeyMap.toString();
\r
429 if (!alreadyRegisteredEntityMap.containsKey(alreadyRegisteredEntityKey)) {
\r
430 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
431 // Initialize referrer entity and register it to the list of referrer with primary key value.
\r
432 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
433 final ${glEntityInterfaceName} referrerEntity = relationInfo.getTargetDBMeta().newEntity();
\r
434 referrerList.add(referrerEntity);
\r
436 // - - - - - - - - - - - - - - - - - -
\r
437 // Initialize primary key of referrer.
\r
438 // - - - - - - - - - - - - - - - - - -
\r
439 injectReferrerPrimaryKey(referrerEntity, targetPrimaryKeyMap);
\r
441 // - - - - - - - - - - - - - - - - - -
\r
442 // Initialize foreign key of referrer.
\r
443 // - - - - - - - - - - - - - - - - - -
\r
444 injectReferrerForeignKey(topInfo, referrerEntity, referrerInfo, localRelationPath);
\r
446 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
447 // Put referrer entity to the map of already-registered-entity.
\r
448 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
449 alreadyRegisteredEntityMap.put(alreadyRegisteredEntityKey.toString(), referrerEntity);
\r
453 // - - - - - - - - - - - - - - - - - -
\r
454 // Set next value to current element.
\r
455 // - - - - - - - - - - - - - - - - - -
\r
456 localEntity = alreadyRegisteredEntityMap.get(alreadyRegisteredEntityKey);
\r
457 localDBMeta = localEntity.getDBMeta();
\r
458 localRelationPath = targetRelationPath;
\r
460 if (relationLoopCount == (relationPropNameList.size() - 1)) {// The last loop!
\r
461 // - - - - - - - - - - - -
\r
462 // Here is the last loop!
\r
463 // - - - - - - - - - - - -
\r
464 doLastLoopInjection(topInfo, requestElement, localEntity, targetPrimaryKeyMap);
\r
466 ++relationLoopCount;
\r
471 * Is not existing primary key at the relation path?.
\r
473 * @param topInfo The information object of top that has generics of local entity. (NotNull)
\r
474 * @param relationPath The path of relation. (NotNull)
\r
475 * @return Determination.
\r
477 protected boolean isNotExistPrimaryKey(TopInfo<LOCAL_ENTITY> topInfo, String relationPath) {
\r
478 final Map<String, Object> primaryKeyMap = extractPrimaryKeyMapFromSource(topInfo, relationPath);
\r
479 final Set<String> keySet = primaryKeyMap.keySet();
\r
480 for (String key : keySet) {
\r
481 final Object value = primaryKeyMap.get(key);
\r
482 if (value == null) {
\r
490 * Do last loop injection.
\r
492 * @param topInfo The information object of top that has generics of local entity. (NotNull)
\r
493 * @param requestElement The element of request. This is relation loop resource. (NotNull)
\r
494 * @param localEntity The interface of local entity. (NotNull)
\r
495 * @param primaryKeyMap The map of primary key. (NotNull)
\r
497 protected void doLastLoopInjection(TopInfo<LOCAL_ENTITY> topInfo, ${glHierarchyRequestElementName} requestElement,
\r
498 ${glEntityInterfaceName} localEntity, Map<String, Object> primaryKeyMap) {
\r
499 final ${glColumnInfoName} destinationColumnInfo = requestElement.getDestinationColumnInfo();
\r
500 if (!primaryKeyMap.containsKey(destinationColumnInfo.getColumnDbName())) {// The column is primary key!
\r
501 final ${glHierarchySourceRowName} sourceRow = topInfo.getSourceRow();
\r
502 final ${glHierarchySourceColumnName} sourceColumnInfo = requestElement.getSourceColumnInfo();
\r
503 final Object sourceColumnValue = extractColumnValueFromSource(sourceRow, sourceColumnInfo);
\r
504 if (sourceColumnValue != null) {
\r
505 injectColumnValueToDestinationIfNotNull(localEntity, destinationColumnInfo, sourceColumnValue);
\r
510 // ===================================================================================
\r
513 protected Map<String, Object> extractTopPrimaryKeyMapFromSource(TopInfo<LOCAL_ENTITY> topInfo) {
\r
514 return extractPrimaryKeyMapFromSource(topInfo, ${glHierarchyRequestElementName}.TOP_KEY);
\r
517 protected Map<String, Object> extractPrimaryKeyMapFromSource(TopInfo<LOCAL_ENTITY> topInfo, String relationPath) {
\r
518 final ${glHierarchyRequestName}<LOCAL_ENTITY> request = topInfo.getHierarchyRequest();
\r
519 final ${glHierarchySourceRowName} sourceRow = topInfo.getSourceRow();
\r
520 final java.util.List<${glHierarchyRequestElementName}> primaryKeyElement = request.findPrimaryKeyElement(relationPath);
\r
521 final java.util.Map<String, Object> primaryKeyMap = new java.util.LinkedHashMap<String, Object>();
\r
522 for (${glHierarchyRequestElementName} element : primaryKeyElement) {
\r
523 final ${glHierarchySourceColumnName} sourcePrimaryKey = element.getSourceColumnInfo();
\r
524 final Object sourcePrimaryKeyValue = extractColumnValueFromSource(sourceRow, sourcePrimaryKey);
\r
525 primaryKeyMap.put(element.getDestinationColumnInfo().getColumnDbName(), sourcePrimaryKeyValue);
\r
527 return primaryKeyMap;
\r
530 protected Object extractColumnValueFromSource(${glHierarchySourceRowName} sourceRow,
\r
531 ${glHierarchySourceColumnName} sourceColumn) {
\r
532 return sourceRow.extractColumnValue(sourceColumn);
\r
535 @SuppressWarnings("unchecked")
\r
536 protected java.util.List<${glEntityInterfaceName}> extractReferrerList(${glEntityInterfaceName} entity, ${glReferrerInfoName} referrerInfo) {
\r
537 return (java.util.List<${glEntityInterfaceName}>) invoke(referrerInfo.findGetter(), entity, new Object[] {});
\r
540 // ===================================================================================
\r
544 * @param entity Entity. (NotNull)
\r
545 * @param columnInfo Column info. (NotNull)
\r
546 * @param columnValue Column value. (NotNull)
\r
548 protected void injectColumnValueToDestinationIfNotNull(${glEntityInterfaceName} entity, ${glColumnInfoName} columnInfo, final Object columnValue) {
\r
549 if (columnValue != null) {
\r
550 injectColumnValueToDestination(entity, columnInfo.getColumnDbName(), columnValue);
\r
554 protected void injectColumnValueToDestination(${glEntityInterfaceName} entity, String columnDbName, final Object columnValue) {
\r
555 if (columnValue == null) {
\r
556 String msg = "The argument[columnValue] should not be null: ";
\r
557 msg = msg + " table=" + entity.getTableDbName() + " column=" + columnDbName;
\r
558 throw new IllegalStateException(msg);
\r
560 invoke(entity.getDBMeta().findColumnInfo(columnDbName).findSetter(), entity, new Object[] { columnValue });
\r
563 protected void injectColumnValueMapToDestination(${glEntityInterfaceName} entity, final Map<String, Object> columnValueMap) {
\r
564 final Set<String> columnNameSet = columnValueMap.keySet();
\r
565 for (String columnName : columnNameSet) {
\r
566 final Object columnValue = columnValueMap.get(columnName);
\r
567 injectColumnValueToDestination(entity, columnName, columnValue);
\r
571 protected void injectForeignEntity(${glEntityInterfaceName} entity, String foreignPropName, ${glEntityInterfaceName} foreignEntity) {
\r
572 final String capPropReferrerName = initCap(foreignPropName);
\r
573 final Method method = findMethod(entity.getClass(), "set" + capPropReferrerName, new Class[] { foreignEntity.getDBMeta().getEntityType() });
\r
574 invoke(method, entity, new Object[] { foreignEntity });
\r
577 protected void injectReferrerList(${glEntityInterfaceName} entity, ${glReferrerInfoName} referrerInfo, java.util.List<${glEntityInterfaceName}> referrerList) {
\r
578 invoke(referrerInfo.findSetter(), entity, new Object[] { referrerList });
\r
581 protected void injectForeignPrimaryKey(${glEntityInterfaceName} foreignEntity, Map<String, Object> foreigPrimaryKeyMap) {
\r
582 injectColumnValueMapToDestination(foreignEntity, foreigPrimaryKeyMap);
\r
585 protected void injectReferrerPrimaryKey(${glEntityInterfaceName} referrerEntity, Map<String, Object> referrerPrimaryKeyMap) {
\r
586 injectColumnValueMapToDestination(referrerEntity, referrerPrimaryKeyMap);
\r
589 protected void injectLocalForeignKey(TopInfo<LOCAL_ENTITY> topInfo, ${glEntityInterfaceName} localEntity, ${glForeignInfoName} foreignInfo, String foreignRelationPath) {
\r
590 final ${glHierarchyRequestName}<LOCAL_ENTITY> request = topInfo.getHierarchyRequest();
\r
591 final Map<String, Object> foreignPrimaryKeyMap = extractPrimaryKeyMapFromSource(topInfo, foreignRelationPath);
\r
592 final List<${glHierarchyRequestElementName}> primaryKeyElementList = request.findPrimaryKeyElement(foreignRelationPath);
\r
593 final Map<String, Object> localForeignKeyMap = new HashMap<String, Object>();
\r
594 for (${glHierarchyRequestElementName} foreignElement : primaryKeyElementList) {
\r
595 final String foreignPrimaryKeyColumnName = foreignElement.getDestinationColumnInfo().getColumnDbName();
\r
596 final ${glColumnInfoName} localForeignKeyInfo = foreignInfo.findLocalByForeign(foreignPrimaryKeyColumnName);
\r
597 final Object localForeignKeyValue = foreignPrimaryKeyMap.get(foreignPrimaryKeyColumnName);
\r
598 localForeignKeyMap.put(localForeignKeyInfo.getColumnDbName(), localForeignKeyValue);
\r
600 injectColumnValueMapToDestination(localEntity, localForeignKeyMap);
\r
603 protected void injectReferrerForeignKey(TopInfo<LOCAL_ENTITY> topInfo, ${glEntityInterfaceName} referrerEntity,
\r
604 ${glReferrerInfoName} referrerInfo, String localRelationPath) {
\r
605 final ${glHierarchyRequestName}<LOCAL_ENTITY> request = topInfo.getHierarchyRequest();
\r
606 final Map<String, Object> localPrimaryKeyMap = extractPrimaryKeyMapFromSource(topInfo, localRelationPath);
\r
607 final List<${glHierarchyRequestElementName}> primaryKeyElementList = request.findPrimaryKeyElement(localRelationPath);
\r
608 final Map<String, Object> referrerForeignKeyMap = new HashMap<String, Object>();
\r
609 for (${glHierarchyRequestElementName} localElement : primaryKeyElementList) {
\r
610 final String localPrimaryKeyName = localElement.getDestinationColumnInfo().getColumnDbName();
\r
611 final ${glColumnInfoName} referrerForeignKeyInfo = referrerInfo.findReferrerByLocal(localPrimaryKeyName);
\r
612 final Object referrerForeignKeyValue = localPrimaryKeyMap.get(localPrimaryKeyName);
\r
613 referrerForeignKeyMap.put(referrerForeignKeyInfo.getColumnDbName(), referrerForeignKeyValue);
\r
615 injectColumnValueMapToDestination(referrerEntity, referrerForeignKeyMap);
\r
618 // ===================================================================================
\r
621 @SuppressWarnings("unchecked")
\r
622 protected LOCAL_ENTITY newLocalEntity(final ${glDBMetaInterfaceName} destinationDBMeta) {
\r
623 final LOCAL_ENTITY localEntity;
\r
625 localEntity = (LOCAL_ENTITY) destinationDBMeta.getEntityType().newInstance();
\r
626 } catch (InstantiationException e) {
\r
627 throw new IllegalStateException(e);
\r
628 } catch (IllegalAccessException e) {
\r
629 throw new IllegalStateException(e);
\r
631 return localEntity;
\r
634 // ===================================================================================
\r
637 protected String initCap(final String name) {
\r
638 final String capPropReferrerName = name.substring(0, 1).toUpperCase() + name.substring(1);
\r
639 return capPropReferrerName;
\r
642 private java.lang.reflect.Method findMethod(Class clazz, String methodName, Class[] argTypes) {
\r
644 return clazz.getMethod(methodName, argTypes);
\r
645 } catch (NoSuchMethodException ex) {
\r
646 String msg = "class=" + clazz + " method=" + methodName + "-" + java.util.Arrays.asList(argTypes);
\r
647 throw new RuntimeException(msg, ex);
\r
651 private Object invoke(java.lang.reflect.Method method, Object target, Object[] args) {
\r
653 return method.invoke(target, args);
\r
654 } catch (RuntimeException e) {
\r
655 final String lineSeparator = System.getProperty("line.separator");
\r
656 final Class<?>[] parameterTypes = method.getParameterTypes();
\r
657 String msg = "Invoking method threw the exception:" + lineSeparator;
\r
658 msg = msg + "/* * * * * * * * * * * * * * * * * * * * * * * * * * * *" + lineSeparator;
\r
659 msg = msg + "[" + method.getDeclaringClass().getSimpleName() + "." + method.getName() + "()]" + lineSeparator;
\r
660 msg = msg + " methodArgTypes = {" + createTypeViewFromTypeArray(parameterTypes) + "}" + lineSeparator;
\r
661 msg = msg + " specifiedArgValues = {" + createValueViewFromValueArray(args) + "}" + lineSeparator;
\r
662 msg = msg + " specifiedArgTypes = {" + createTypeViewFromValueArray(args) + "}" + lineSeparator;
\r
663 if (parameterTypes.length > 0 && args.length > 0 && args[0] != null && !parameterTypes[0].equals(args[0].getClass())) {
\r
664 msg = msg + " " + lineSeparator;
\r
665 final String compareString = "{" + parameterTypes[0] + " -- " + args[0].getClass() + "}";
\r
666 msg = msg + " *Warning! The argType is ummatched: " + compareString + lineSeparator;
\r
668 msg = msg + "* * * * * * * * * */" + lineSeparator;
\r
669 throw new RuntimeException(msg, e);
\r
670 } catch (java.lang.reflect.InvocationTargetException ex) {
\r
671 Throwable t = ex.getCause();
\r
672 if (t instanceof RuntimeException) {
\r
673 throw (RuntimeException) t;
\r
675 if (t instanceof Error) {
\r
678 String msg = "target=" + target + " method=" + method + "-" + java.util.Arrays.asList(args);
\r
679 throw new RuntimeException(msg, ex);
\r
680 } catch (IllegalAccessException ex) {
\r
681 String msg = "target=" + target + " method=" + method + "-" + java.util.Arrays.asList(args);
\r
682 throw new RuntimeException(msg, ex);
\r
686 private String createValueViewFromValueArray(Object[] array) {
\r
687 final StringBuffer sb = new StringBuffer();
\r
688 for (int i=0; i < array.length; i++) {
\r
689 final Object value = array[i];
\r
690 if (sb.length() == 0) {
\r
693 sb.append(", ").append(value);
\r
696 return sb.toString();
\r
699 private String createTypeViewFromValueArray(Object[] array) {
\r
700 final StringBuffer sb = new StringBuffer();
\r
701 for (int i=0; i < array.length; i++) {
\r
702 final Object value = array[i];
\r
703 final String typeName = value != null ? value.getClass().getSimpleName() : "null";
\r
704 if (sb.length() == 0) {
\r
705 sb.append(typeName);
\r
707 sb.append(", ").append(typeName);
\r
710 return sb.toString();
\r
713 private String createTypeViewFromTypeArray(Class[] array) {
\r
714 final StringBuffer sb = new StringBuffer();
\r
715 for (int i=0; i < array.length; i++) {
\r
716 final Class type = array[i];
\r
717 if (sb.length() == 0) {
\r
718 sb.append(type.getSimpleName());
\r
720 sb.append(", ").append(type.getSimpleName());
\r
723 return sb.toString();
\r
726 // ===================================================================================
\r
729 protected static class TopInfo<LOCAL_ENTITY extends ${glEntityInterfaceName}> {
\r
730 private ${glHierarchyRequestName}<LOCAL_ENTITY> hierarchyRequest;
\r
732 private ${glHierarchySourceRowName} sourceRow;
\r
734 private ${glEntityInterfaceName} localEntity;
\r
736 private Map<String, ${glEntityInterfaceName}> alreadyRegisteredEntityMap;
\r
738 public ${glHierarchySourceRowName} getSourceRow() {
\r
742 public void setSourceRow(${glHierarchySourceRowName} sourceRow) {
\r
743 this.sourceRow = sourceRow;
\r
746 public ${glEntityInterfaceName} getLocalEntity() {
\r
747 return localEntity;
\r
750 public void setLocalEntity(${glEntityInterfaceName} localEntity) {
\r
751 this.localEntity = localEntity;
\r
754 public Map<String, ${glEntityInterfaceName}> getAlreadyRegisteredEntityMap() {
\r
755 return alreadyRegisteredEntityMap;
\r
758 public void setAlreadyRegisteredEntityMap(Map<String, ${glEntityInterfaceName}> alreadyRegisteredEntityMap) {
\r
759 this.alreadyRegisteredEntityMap = alreadyRegisteredEntityMap;
\r
762 public ${glHierarchyRequestName}<LOCAL_ENTITY> getHierarchyRequest() {
\r
763 return hierarchyRequest;
\r
766 public void setHierarchyRequest(${glHierarchyRequestName}<LOCAL_ENTITY> hierarchyRequest) {
\r
767 this.hierarchyRequest = hierarchyRequest;
\r