001: /*
002: *
003: * Copyright (c) 2004 SourceTap - www.sourcetap.com
004: *
005: * The contents of this file are subject to the SourceTap Public License
006: * ("License"); You may not use this file except in compliance with the
007: * License. You may obtain a copy of the License at http://www.sourcetap.com/license.htm
008: * Software distributed under the License is distributed on an "AS IS" basis,
009: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
010: * the specific language governing rights and limitations under the License.
011: *
012: * The above copyright notice and this permission notice shall be included
013: * in all copies or substantial portions of the Software.
014: *
015: */
016:
017: package com.sourcetap.sfa.replication;
018:
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Vector;
023:
024: import org.ofbiz.base.util.Debug;
025: import org.ofbiz.base.util.UtilTimer;
026: import org.ofbiz.entity.GenericDelegator;
027: import org.ofbiz.entity.GenericEntityException;
028: import org.ofbiz.entity.GenericPK;
029: import org.ofbiz.entity.GenericValue;
030:
031: import com.sourcetap.sfa.util.UserInfo;
032:
033: /**
034: * This class is used for entity instance replication. <P>
035: *
036: * Typically this class, or its descendant, is used to replicate a single instance
037: * of an entity. This is accomplished by instantiating this class and calling its
038: * replicateInstance() method. <P>
039: *
040: * For each instance replicated, one or more related entity instances may be replicated
041: * when the replicateAllRelated() method is called automatically by the replicateInstance()
042: * method. If the relatedEntityMapVector attribute has been populated, the
043: * replicateAllRelated() method will call the replicateOneRelated() method for each item in
044: * the vector to replicate one entities instances. The related entities are located in the
045: * findOneRelated() method, which is called by replicateOneRelated(). For each related
046: * entity instance found, another instance of this class is used to replicate it. <P>
047: *
048: * Entity replication is used to do full replication. Full replication is required to
049: * populate a newly registered replication node, or to re-populate an inactive
050: * replication node. To perform full replication, the relatedEntityMapVector should be
051: * populated with a list of all entities to be removed and replicated, and the information
052: * required to find them. Then the removeAll() and replicateAll() methods
053: * should be called.
054: *
055: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
056: */
057: public class EntityReplicator extends GenericReplicator {
058: private static final boolean TIMER = false;
059: public static final String module = EntityReplicator.class
060: .getName();
061:
062: /**
063: * The name of the entity to be replicated.
064: */
065: protected String entityName;
066:
067: /**
068: * Related Entity Map Vector <P>
069: *
070: * Each vector element contains a HashMap describing a related entity to be replicated
071: * for each instance of the main entity that is replicated. <P>
072: *
073: * Each HashMap contains: <P>
074: *
075: * String relationTitle <BR>
076: * String relatedEntityName <BR>
077: * HashMap filterMap <BR>
078: * String replicatorClassName <BR>
079: * Boolean replicateAll
080: * Boolean removeAll
081: */
082: protected Vector relatedEntityMapVector = new Vector();
083:
084: /**
085: * User Information
086: */
087: protected UserInfo userInfo;
088:
089: /**
090: * Constructor with no args.
091: */
092: public EntityReplicator() {
093: populateRelatedEntityMapVector();
094: }
095:
096: /**
097: * Constructor with args.
098: *
099: * @param mainInstance Main entity instance for which related entities will be replicated
100: * @param localDelegator Delegator to attach to local data base
101: * @param masterDelegator Delegator to attach to master data base
102: * @param entityName Name of the entity to be replicated
103: * @param userInfo UserInfo object containing user information
104: */
105: public EntityReplicator(GenericDelegator localDelegator,
106: GenericDelegator masterDelegator, String entityName,
107: UserInfo userInfo) {
108: super (localDelegator, masterDelegator);
109: setEntityName(entityName);
110: setUserInfo(userInfo);
111: populateRelatedEntityMapVector();
112: }
113:
114: /**
115: * Gets the name of the entity to be replicated.
116: *
117: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
118: *
119: * @return Name of the entity to be replicated
120: *
121: */
122: public String getEntityName() {
123: return entityName;
124: }
125:
126: /**
127: * Sets the name of the entity to be replicated.
128: *
129: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
130: *
131: * @param entityName_ Name of the entity to be replicated
132: *
133: */
134: public void setEntityName(String entityName_) {
135: entityName = entityName_;
136:
137: return;
138: }
139:
140: /**
141: * Adds a related entity map to the related entity map vector.
142: *
143: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
144: *
145: * @param relatedEntityMap HashMap containing information about a releated entity
146: */
147: public void addRelatedEntityMap(HashMap relatedEntityMap) {
148:
149: relatedEntityMapVector.add(relatedEntityMap);
150:
151: return;
152: }
153:
154: /**
155: * Adds a related entity map to the related entity map vector.
156: *
157: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
158: *
159: * @param relationTitle Relation title to be used by the entity engine to find related
160: * entity instances
161: * @param relatedEntityName Name of the related entity to be replicated
162: * @param filterMap HashMap containing additional filter values to be used by the entity
163: * engine when finding related entity instances
164: * @param replicateAll Flag indicating to replicate all instances of this entity
165: * instead of just the ones related to the main entity.
166: * @param removeAll Flag indicating to remove all instances of this entity instead of
167: * just the ones related to the main entity.
168: * @param replicatorClassName Name of a descendant class of this class which will be used
169: * to replicate the related entity instances
170: */
171: public void addRelatedEntityMap(String relationTitle,
172: String relatedEntityName, HashMap filterMap,
173: boolean replicateAll, boolean removeAll,
174: String replicatorClassName) {
175:
176: HashMap relatedEntityMap = new HashMap();
177: relatedEntityMap.put("relationTitle", relationTitle);
178: relatedEntityMap.put("relatedEntityName", relatedEntityName);
179: relatedEntityMap.put("filterMap", filterMap);
180: relatedEntityMap.put("replicateAll", new Boolean(replicateAll));
181: relatedEntityMap.put("removeAll", new Boolean(removeAll));
182: relatedEntityMap
183: .put("replicatorClassName", replicatorClassName);
184: addRelatedEntityMap(relatedEntityMap);
185:
186: return;
187: }
188:
189: /**
190: * Populate the related entity map vector. This method is called from the constructors
191: * to allow the related entities to be specified before replication begins.
192: *
193: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
194: */
195: public void populateRelatedEntityMapVector() {
196: }
197:
198: /**
199: * Gets the related entity map vector.
200: *
201: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
202: *
203: * @return Related entity map vector.
204: *
205: */
206: public Vector getRelatedEntityMapVector() {
207: return relatedEntityMapVector;
208: }
209:
210: /**
211: * Gets the user information
212: *
213: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
214: *
215: * @return UserInfo object
216: *
217: */
218: public UserInfo getUserInfo() {
219: return userInfo;
220: }
221:
222: /**
223: * Sets the user information
224: *
225: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
226: *
227: * @param userInfo_ UserInfo object
228: *
229: */
230: public void setUserInfo(UserInfo userInfo_) {
231: userInfo = userInfo_;
232:
233: return;
234: }
235:
236: /**
237: * This method replicates one instance of the entity named in the entityName attribute. <P>
238: *
239: * Ths instance passed in the instance argument is copied from the master data base
240: * to the local data base. Then the replicateRelatedEntities() method is
241: * called so child entity instance can be replicated. <P>
242: *
243: * This method requires that all arguments passed to the constructor were not null and
244: * not empty. Alternatively, this method requires the setEntityName, setLocalDelegator,
245: * and setMasterDelegator methods to have been called since construction.
246: *
247: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
248: *
249: * @param mainInstance Entity instance being replicated
250: *
251: * @return The status of the replication. Possible values: STATUS_CONTINUE, STATUS_ERROR,
252: * STATUS_CANCEL
253: */
254: public int replicateInstance(GenericValue mainInstance) {
255:
256: // Check pre-conditions.
257: if (mainInstance == null) {
258: Debug.logError(
259: "[replicateInstance] Main entity instance is required. "
260: + "Replication canceled.", module);
261:
262: return STATUS_ERROR;
263: }
264:
265: ;
266:
267: // Insert the instance into the local data base.
268: int status = insertLocalInstance(mainInstance);
269:
270: if (status != STATUS_CONTINUE) {
271: return status;
272: }
273:
274: // Insert all related entity instances.
275: status = replicateAllRelated(mainInstance);
276:
277: if (status != STATUS_CONTINUE) {
278: return status;
279: }
280:
281: return STATUS_CONTINUE;
282: }
283:
284: /**
285: * This method removes one instance of the entity named in the entityName attribute. <P>
286: *
287: * First the removeRelatedEntities() method is called so child entity instances
288: * can be removed from the local data base. Then the instance passed in the
289: * instance argument is removed from the local data base.
290: *
291: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
292: *
293: * @param mainInstance Entity instance being replicated
294: *
295: * @return The status of the replication. Possible values: STATUS_CONTINUE, STATUS_ERROR,
296: * STATUS_CANCEL
297: */
298: public int removeInstance(GenericValue mainInstance) {
299:
300: if (mainInstance == null) {
301: Debug
302: .logError(
303: "[replicateInstance] Main entity instance is required.",
304: module);
305:
306: return STATUS_ERROR;
307: }
308:
309: // Remove all related entity instances.
310: int status = removeAllRelated(mainInstance);
311:
312: if (status != STATUS_CONTINUE) {
313: return status;
314: }
315:
316: // Remove the instance from the local data base.
317: status = removeLocalInstance(mainInstance);
318:
319: if (status != STATUS_CONTINUE) {
320: return status;
321: }
322:
323: return STATUS_CONTINUE;
324: }
325:
326: /**
327: * This method stores the instance in the local data base.
328: *
329: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
330: *
331: * @param masterInstance Entity instance from the master data base
332: *
333: * @return Status. Possible values: STATUS_CONTINUE, STATUS_ERROR, STATUS_CANCELED
334: */
335: public int insertLocalInstance(GenericValue masterInstance) {
336:
337: if (masterInstance == null) {
338: Debug
339: .logError(
340: "[replicateInstance] Master entity instance is required.",
341: module);
342:
343: return STATUS_ERROR;
344: }
345:
346: ;
347:
348: if (getLocalDelegator() == null) {
349: Debug
350: .logError(
351: "[insertLocalInstance] Local delegator is required.",
352: module);
353:
354: return STATUS_ERROR;
355: }
356:
357: ;
358:
359: // Copy the instance, and assign it to the local delegator instead of the master one.
360: GenericValue localInstance = new GenericValue(masterInstance);
361: localInstance.setDelegator(getLocalDelegator());
362:
363: GenericPK localInstancePK = localInstance.getPrimaryKey();
364:
365: try {
366: getLocalDelegator().create(localInstance);
367: Debug.logVerbose("Inserted key "
368: + localInstancePK.toString(), module);
369:
370: return STATUS_CONTINUE;
371: } catch (GenericEntityException gee) {
372: if (gee.getLocalizedMessage().indexOf("Duplicate entry") > 0) {
373: Debug.logError("[insertLocalInstance] Duplicate key "
374: + localInstancePK.toString(), module);
375:
376: return STATUS_CONTINUE;
377: } else {
378: Debug.logError(
379: "[insertLocalInstance] Error inserting key "
380: + localInstancePK.toString() + ":",
381: module);
382: Debug.logError("[insertLocalInstance] "
383: + gee.getLocalizedMessage(), module);
384:
385: return STATUS_ERROR;
386: }
387: }
388: }
389:
390: /**
391: * This method removes an instance of the main entity from the local data base.
392: *
393: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
394: *
395: * @param localInstance Entity instance being removed
396: *
397: * @return Status. Possible values: STATUS_CONTINUE, STATUS_ERROR, STATUS_CANCELED
398: */
399: public int removeLocalInstance(GenericValue localInstance) {
400:
401: if (localInstance == null) {
402: Debug
403: .logError(
404: "[replicateInstance] Local entity instance is required.",
405: module);
406:
407: return STATUS_ERROR;
408: }
409:
410: ;
411:
412: if (getLocalDelegator() == null) {
413: Debug
414: .logError(
415: "[insertLocalInstance] Local delegator is required.",
416: module);
417:
418: return STATUS_ERROR;
419: }
420:
421: ;
422:
423: GenericPK localInstancePK = localInstance.getPrimaryKey();
424:
425: try {
426: getLocalDelegator().removeByPrimaryKey(
427: localInstance.getPrimaryKey());
428: Debug.logVerbose("Removed key "
429: + localInstancePK.toString(), module);
430:
431: return STATUS_CONTINUE;
432: } catch (GenericEntityException gee) {
433: Debug.logError("[removeLocalInstance] Error removing key "
434: + localInstancePK.toString() + ":", module);
435: Debug.logError("[removeLocalInstance] "
436: + gee.getLocalizedMessage(), module);
437:
438: return STATUS_ERROR;
439: }
440: }
441:
442: /**
443: * This method replicates all instances for all related entities. <P>
444: *
445: * This method uses the relatedEntityMapVector to determine what related
446: * entities need to be replicated. For each related entity, this method calls
447: * replicateOneRelated(). Each call to replicateOneRelated() calls
448: * findOneRelated(), which finds all instances of the specified entity. Then
449: * replicateOneRelated() calls replicateInstance for each instance of the
450: * related entity to recursively replicate the tree of instances.
451: *
452: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
453: *
454: * @param mainInstance Main entity instance for which related entities will be replicated
455: *
456: * @return Status. Possible values: STATUS_CONTINUE, STATUS_ERROR, STATUS_CANCELED
457: */
458: public int replicateAllRelated(GenericValue mainInstance) {
459: Debug.logVerbose("[replicateAllRelated] Start", module);
460:
461: // if (mainInstance == null) {
462: // Debug.logError("[replicateInstance] Entity instance is required.");
463: // return STATUS_ERROR;
464: // };
465: Iterator relatedEntityMapVectorI = getRelatedEntityMapVector()
466: .iterator();
467:
468: while (relatedEntityMapVectorI.hasNext()) {
469: HashMap relatedEntityMap = (HashMap) relatedEntityMapVectorI
470: .next();
471: String relationTitle = (String) relatedEntityMap
472: .get("relationTitle");
473: String relatedEntityName = (String) relatedEntityMap
474: .get("relatedEntityName");
475: String replicatorClassName = (String) relatedEntityMap
476: .get("replicatorClassName");
477: Boolean replicateAll = (Boolean) relatedEntityMap
478: .get("replicateAll");
479: HashMap filterMap = (HashMap) relatedEntityMap
480: .get("filterMap");
481: int status = replicateOneRelated(mainInstance,
482: relationTitle, relatedEntityName, filterMap,
483: replicateAll.booleanValue(), replicatorClassName);
484:
485: if (status != STATUS_CONTINUE) {
486: return status;
487: }
488: }
489:
490: return STATUS_CONTINUE;
491: }
492:
493: /**
494: * This method removes all instances for all related entities. <P>
495: *
496: * This method uses the relatedEntityMapVector to determine what related
497: * entities need to be removed. For each related entity, this method calls
498: * removeOneRelated(). Each call to removeOneRelated() calls
499: * findOneRelated(), which finds all instances of the specified entity. Then
500: * removeOneRelated() calls removeLocalInstance for each instance of the
501: * related entity to recursively replicate the tree of instances.
502: *
503: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
504: *
505: * @param localInstance Local entity from which related entity instances are to be removed
506: *
507: * @return Status. Possible values: STATUS_CONTINUE, STATUS_ERROR, STATUS_CANCELED
508: */
509: public int removeAllRelated(GenericValue localInstance) {
510: Debug.logVerbose("[removeAllRelated] Start", module);
511:
512: // if (localInstance == null) {
513: // Debug.logError("[replicateInstance] Entity instance is required.");
514: // return STATUS_ERROR;
515: // };
516: // Remove the entities in reverse order in case RI is turned on.
517: for (int relatedEntityNbr = getRelatedEntityMapVector().size() - 1; relatedEntityNbr >= 0; relatedEntityNbr--) {
518: // Iterator relatedEntityMapVectorI = getRelatedEntityMapVector().iterator();
519: // while (relatedEntityMapVectorI.hasNext()) {
520: HashMap relatedEntityMap = (HashMap) getRelatedEntityMapVector()
521: .get(relatedEntityNbr);
522:
523: // HashMap relatedEntityMap = (HashMap)relatedEntityMapVectorI.next();
524: String relationTitle = (String) relatedEntityMap
525: .get("relationTitle");
526: String relatedEntityName = (String) relatedEntityMap
527: .get("relatedEntityName");
528: Boolean removeAll = (Boolean) relatedEntityMap
529: .get("removeAll");
530: String replicatorClassName = (String) relatedEntityMap
531: .get("replicatorClassName");
532: HashMap filterMap = (HashMap) relatedEntityMap
533: .get("filterMap");
534: int status = removeOneRelated(localInstance, relationTitle,
535: relatedEntityName, filterMap, removeAll
536: .booleanValue(), replicatorClassName);
537:
538: if (status != STATUS_CONTINUE) {
539: return status;
540: }
541: }
542:
543: return STATUS_CONTINUE;
544: }
545:
546: /**
547: * This method replicates all instances for one entity related to the main entity. <P>
548: *
549: * This method calls findOneRelated(), which finds all instances of the related entity.
550: * Then this method calls replicateInstance for each instance of the
551: * related entity to recursively replicate the tree of instances.
552: *
553: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
554: *
555: * @param mainInstance Main entity instance for which related entities will be replicated
556: * @param relationTitle Relation title to be used by the entity engine to find related
557: * entity instances
558: * @param relatedEntityName Name of the related entity to be replicated
559: * @param filterMap HashMap containing additional filter values to be used by the entity
560: * engine when finding related entity instances
561: * @param replicatorClassName Name of a descendant class of this class which will be used
562: * to replicate the related entity instances
563: *
564: * @return Status. Possible values: STATUS_CONTINUE, STATUS_ERROR, STATUS_CANCELED
565: */
566: protected int replicateOneRelated(GenericValue mainInstance,
567: String relationTitle, String relatedEntityName,
568: HashMap filterMap, boolean replicateAll,
569: String replicatorClassName) {
570: UtilTimer timer = new UtilTimer();
571:
572: if (TIMER) {
573: timer.timerString(1, "[replicateOneRelated] Start");
574: }
575:
576: Debug.logVerbose("[replicateOneRelated] Start", module);
577:
578: Debug.logVerbose("[replicateOneRelated] relationTitle: "
579: + relationTitle, module);
580: Debug.logVerbose("[replicateOneRelated] relatedEntityName: "
581: + relatedEntityName, module);
582: Debug.logVerbose("[replicateOneRelated] replicatorClassName: "
583: + replicatorClassName, module);
584:
585: // Instantiate related replicator class.
586: EntityReplicator relatedReplicator = getEntityReplicator(
587: replicatorClassName, getLocalDelegator(),
588: getMasterDelegator(), relatedEntityName, getUserInfo());
589:
590: if (relatedReplicator == null) {
591: return STATUS_ERROR;
592: }
593:
594: String entityName = "*";
595:
596: if (mainInstance != null) {
597: entityName = mainInstance.getEntityName();
598: }
599:
600: if (TIMER) {
601: timer.timerString(1,
602: "[EntityReplicator.replicateOneRelated] Starting findOneRelated ("
603: + entityName + "/" + relationTitle
604: + relatedEntityName + ")");
605: }
606:
607: List relatedGVL = findOneRelated(getMasterDelegator(),
608: mainInstance, relationTitle, relatedEntityName,
609: filterMap, replicateAll);
610:
611: if (relatedGVL == null) {
612: return STATUS_ERROR;
613: }
614:
615: if (TIMER) {
616: timer.timerString(1,
617: "[EntityReplicator.replicateOneRelated] Finished findOneRelated ("
618: + entityName + "/" + relationTitle
619: + relatedEntityName + ")");
620: }
621:
622: Iterator relatedGVI = relatedGVL.iterator();
623:
624: while (relatedGVI.hasNext()) {
625: GenericValue relatedGV = (GenericValue) relatedGVI.next();
626: int status = relatedReplicator.replicateInstance(relatedGV);
627:
628: if (status != STATUS_CONTINUE) {
629: return status;
630: }
631: }
632:
633: if (TIMER) {
634: timer.timerString(1, "[replicateOneRelated] End");
635: }
636:
637: return STATUS_CONTINUE;
638: }
639:
640: /**
641: * This method removes all instances for one entity related to the main entity. <P>
642: *
643: * This method calls findOneRelated(), which finds all instances of the related entity.
644: * Then this method calls removeInstance for each instance of the
645: * related entity to recursively replicate the tree of instances.
646: *
647: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
648: *
649: * @param mainInstance Main entity instance for which related entities will be replicated
650: * @param relationTitle Relation title to be used by the entity engine to find related
651: * entity instances
652: * @param relatedEntityName Name of the related entity to be replicated
653: * @param filterMap HashMap containing additional filter values to be used by the entity
654: * engine when finding related entity instances
655: * @param removeAll Flag indicating to remove all instances of this entity instead of
656: * just removing the ones related to the main entity.
657: * @param replicatorClassName Name of a descendant class of this class which will be used
658: * to replicate the related entity instances
659: *
660: * @return Status. Possible values: STATUS_CONTINUE, STATUS_ERROR, STATUS_CANCELED
661: */
662: protected int removeOneRelated(GenericValue mainInstance,
663: String relationTitle, String relatedEntityName,
664: HashMap filterMap, boolean removeAll,
665: String replicatorClassName) {
666:
667: // Instantiate related replicator class.
668: EntityReplicator relatedReplicator = getEntityReplicator(
669: replicatorClassName, getLocalDelegator(),
670: getMasterDelegator(), relatedEntityName, getUserInfo());
671:
672: if (relatedReplicator == null) {
673: return STATUS_ERROR;
674: }
675:
676: List relatedGVL = findOneRelated(getLocalDelegator(),
677: mainInstance, relationTitle, relatedEntityName,
678: filterMap, removeAll);
679:
680: if (relatedGVL == null) {
681: return STATUS_ERROR;
682: }
683:
684: Iterator relatedGVI = relatedGVL.iterator();
685:
686: while (relatedGVI.hasNext()) {
687: GenericValue relatedGV = (GenericValue) relatedGVI.next();
688: int status = relatedReplicator.removeInstance(relatedGV);
689:
690: if (status != STATUS_CONTINUE) {
691: return status;
692: }
693: }
694:
695: return STATUS_CONTINUE;
696: }
697:
698: /**
699: * This method finds all instances of an entity related to the main entity.
700: * This is used for replicating and removing, so it accepts the delegator as an
701: * argument to point it to the correct data base.
702: *
703: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
704: *
705: * @param mainInstance Main entity instance for which related entities will be replicated
706: * @param relationTitle Relation title to be used by the entity engine to find related
707: * entity instances
708: * @param relatedEntityName Name of the related entity to be replicated
709: * @param filterMap HashMap containing additional filter values to be used by the entity
710: * engine when finding related entity instances
711: * @param findAll Flag indicating to find all instances of the entity instead of using
712: * a relation
713: *
714: * @return List of generic values related to the main entity instance
715: */
716: protected List findOneRelated(GenericDelegator delegator,
717: GenericValue mainInstance, String relationTitle,
718: String relatedEntityName, HashMap filterMap, boolean findAll) {
719:
720: UtilTimer timer = new UtilTimer();
721:
722: if (TIMER) {
723: timer.timerString(2,
724: "[EntityReplicator.findOneRelated] Start");
725: }
726:
727: String entityName = "*";
728:
729: if (mainInstance != null) {
730: entityName = mainInstance.getEntityName();
731: }
732:
733: if (delegator == null) {
734: Debug.logError("[findOneRelated] Delegator is required.",
735: module);
736:
737: return null;
738: }
739:
740: if (userInfo == null) {
741: Debug.logError(
742: "[findOneRelated] User info object is required.",
743: module);
744:
745: return null;
746: }
747:
748: GenericPK entityPK = null;
749:
750: String entityKeyString = null;
751: List relatedGVL = null;
752:
753: if (findAll) {
754: // Need to find all entity instances, not just the ones related to
755: // the main entity instance.
756: try {
757: if (TIMER) {
758: timer
759: .timerString(2,
760: "[EntityReplicator.findOneRelated] Start findByAnd");
761: }
762:
763: relatedGVL = delegator.findByAnd(relatedEntityName,
764: filterMap);
765:
766: if (TIMER) {
767: timer
768: .timerString(2,
769: "[EntityReplicator.findOneRelated] Finished findByAnd");
770: }
771:
772: return relatedGVL;
773: } catch (GenericEntityException e) {
774: Debug.logError("[findOneRelated] Error getting "
775: + relatedEntityName + " records by and: "
776: + e.getLocalizedMessage(), module);
777:
778: return null;
779: }
780: } else {
781: // Need to find just the entity instances related to the main entity instance.
782: if (mainInstance == null) {
783: Debug
784: .logError(
785: "[findOneRelated] Main instance is required if findAll is false.",
786: module);
787:
788: return null;
789: }
790:
791: entityPK = mainInstance.getPrimaryKey();
792: entityKeyString = entityPK.toString();
793: Debug.logVerbose("[findOneRelated] Retrieving all "
794: + relatedEntityName + " records related to "
795: + entityKeyString, module);
796:
797: try {
798: if (TIMER) {
799: timer
800: .timerString(2,
801: "[EntityReplicator.findOneRelated] Start getRelated");
802: }
803:
804: relatedGVL = delegator.getRelated(relationTitle
805: + relatedEntityName, filterMap, null,
806: mainInstance);
807:
808: if (TIMER) {
809: timer
810: .timerString(2,
811: "[EntityReplicator.findOneRelated] Finished getRelated");
812: }
813:
814: return relatedGVL;
815: } catch (GenericEntityException e) {
816: Debug.logError(
817: "[findOneRelated] Error getting the related "
818: + relatedEntityName + " records: "
819: + e.getLocalizedMessage(), module);
820:
821: return null;
822: }
823: }
824: }
825:
826: /**
827: * Instantiates EntityReplicator or one of its descendant classes.
828: *
829: * @param className The class to be instantiated
830: *
831: * @return Object of class specified by className parameter
832: */
833: public static EntityReplicator getEntityReplicator(
834: String className, GenericDelegator localDelegator,
835: GenericDelegator masterDelegator, String entityName,
836: UserInfo userInfo) {
837:
838: Debug.logVerbose("[getEntityReplicator] className: "
839: + className, module);
840: Debug.logVerbose("[getEntityReplicator] entityName: "
841: + entityName, module);
842:
843: Class entityReplicatorClass = null;
844: EntityReplicator entityReplicator = null;
845:
846: if ((className.length() > 0) && !className.equals("null")) {
847: try {
848: entityReplicatorClass = Class.forName(className);
849: } catch (ClassNotFoundException e) {
850: Debug
851: .logError(
852: "[getEntityReplicator] Class \""
853: + className
854: + "\" specified in relatedEntityMapVector could not be found.",
855: module);
856: Debug.logError(e, module);
857:
858: return null;
859: }
860:
861: try {
862: entityReplicator = (EntityReplicator) entityReplicatorClass
863: .newInstance();
864: } catch (IllegalAccessException e) {
865: Debug
866: .logError(
867: "[getEntityReplicator] EntityReplicator class \""
868: + className
869: + "\" could not be instantiated because "
870: + "the class or initializer is not accessible.",
871: module);
872: Debug.logError(e, module);
873:
874: return null;
875: } catch (InstantiationException e) {
876: Debug
877: .logError(
878: "[getEntityReplicator] EntityReplicator class \""
879: + className
880: + "\" cannot be instantiated because it is an "
881: + "abstract class, an interface, an array class, a primitive type, or void.",
882: module);
883: Debug.logError(e, module);
884:
885: return null;
886: }
887: } else {
888: // Class name was not specified in the display object. Use the default class.
889: entityReplicator = new EntityReplicator();
890: }
891:
892: // Set the delegators on the new entity replicator object.
893: entityReplicator.setLocalDelegator(localDelegator);
894: entityReplicator.setMasterDelegator(masterDelegator);
895: entityReplicator.setEntityName(entityName);
896: entityReplicator.setUserInfo(userInfo);
897:
898: // Return the new instance of EntityReplicator.
899: return entityReplicator;
900: }
901: }
|