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.LinkedList;
022: import java.util.List;
023:
024: import org.ofbiz.base.util.Debug;
025: import org.ofbiz.entity.GenericDelegator;
026: import org.ofbiz.entity.GenericEntityException;
027: import org.ofbiz.entity.GenericValue;
028: import org.ofbiz.entity.condition.EntityCondition;
029: import org.ofbiz.entity.condition.EntityExpr;
030: import org.ofbiz.entity.condition.EntityOperator;
031:
032: import com.sourcetap.sfa.product.ProductHelper;
033: import com.sourcetap.sfa.security.SecurityLinkInfo;
034: import com.sourcetap.sfa.security.SecurityWrapper;
035: import com.sourcetap.sfa.util.UserInfo;
036:
037: /**
038: * This class is used for full data replication for the Sales Force Automation application. <P>
039: *
040: * Full replication is required to populate a newly registered replication node, or
041: * to re-populate an inactive replication node.<P>
042: *
043: * This class calls the populateRelatedEntityMapVector() method to specify what
044: * entities are to be replicated.
045: *
046: * To perform full replication, instantiate this class, and call the replicateFull()
047: * method.
048: *
049: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
050: */
051: public class SFAFullReplicator extends FullReplicator {
052:
053: public static final String module = SFAFullReplicator.class
054: .getName();
055:
056: /**
057: * Constructor with no args.
058: */
059: public SFAFullReplicator() {
060: super ();
061: }
062:
063: /**
064: * Constructor with args.
065: *
066: * @param mainInstance Main entity instance for which related entities will be replicated
067: * @param localDelegator Delegator to attach to local data base
068: * @param masterDelegator Delegator to attach to master data base
069: * @param entityName Name of the entity to be replicated
070: * @param userInfo UserInfo object containing user information
071: */
072: public SFAFullReplicator(GenericDelegator localDelegator,
073: GenericDelegator masterDelegator, String entityName,
074: UserInfo userInfo) {
075: super (localDelegator, masterDelegator, entityName, userInfo);
076: }
077:
078: /**
079: * Populate the related entity map vector. This method is called from the constructors
080: * to allow the related entities to be specified before replication begins.
081: *
082: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
083: */
084: public void populateRelatedEntityMapVector() {
085: // Add related entity maps for all entities to be replicated at the top level.
086: // Set the relation title to "*" to indicate that all entities are to be found
087: // and replicated, not just the ones related to a given entity instance.
088: Debug.logVerbose("[populateRelatedEntityMapVector] Start",
089: module);
090:
091: // Replicate all entities that do not depend on accounts.
092: addRelatedEntityMap("", "AccountType", null, true, true, "");
093: addRelatedEntityMap("", "ActivityType", null, true, true, "");
094: addRelatedEntityMap("", "AddressType", null, true, true, "");
095: addRelatedEntityMap("", "AlertType", null, true, true, "");
096: addRelatedEntityMap("", "Alert", null, true, true, "");
097: addRelatedEntityMap("", "CodeType", null, true, true, "");
098: addRelatedEntityMap("", "Code", null, false, false, "");
099: addRelatedEntityMap("", "ContactAttitudeType", null, true,
100: true, "");
101: addRelatedEntityMap("", "ContactType", null, true, true, "");
102: addRelatedEntityMap("", "DealType", null, true, true, "");
103: addRelatedEntityMap("", "DealStageType", null, true, true, "");
104: addRelatedEntityMap("", "DealStage", null, true, true, "");
105: addRelatedEntityMap("", "DealStageSteps", null, true, true, "");
106: addRelatedEntityMap("", "DealStatus", null, true, true, "");
107: addRelatedEntityMap("", "ExpenseType", null, true, true, "");
108: addRelatedEntityMap("", "Expense", null, true, true, "");
109: addRelatedEntityMap("", "ItDefault", null, true, true, "");
110: addRelatedEntityMap("", "LeadSource", null, true, true, "");
111: addRelatedEntityMap("", "OwnershipType", null, true, true, "");
112: addRelatedEntityMap("", "ProductAssocType", null, true, true,
113: "");
114: addRelatedEntityMap("", "ProductFeature", null, true, true, "");
115: addRelatedEntityMap("", "ProductFeatureApplType", null, true,
116: true, "");
117: addRelatedEntityMap("", "ProductFeatureType", null, true, true,
118: "");
119: addRelatedEntityMap("", "ProductType", null, true, true, "");
120: addRelatedEntityMap("", "ProductTypeAttr", null, true, true, "");
121: addRelatedEntityMap("", "SicCode", null, true, true, "");
122: addRelatedEntityMap("", "SecurityGroupPermission", null, true,
123: true, "");
124:
125: // Replicate the account and all the entities nested under it.
126: addRelatedEntityMap("", "Account", null, false, true,
127: "com.sourcetap.sfa.replication.AccountReplicator");
128:
129: // Replicate all entities that depend on accounts.
130: addRelatedEntityMap("", "LargeData", null, true, true, "");
131: addRelatedEntityMap("", "ItIssue", null, true, true, "");
132: addRelatedEntityMap("", "ItIssueHistory", null, true, true, "");
133:
134: // addRelatedEntityMap("", "ItIssue", null, true, true,
135: // "com.sourcetap.sfa.replication.ItIssueReplicator");
136: addRelatedEntityMap("", "PartyAttribute", null, true, true, "");
137: addRelatedEntityMap("", "Product", null, false, false,
138: "com.sourcetap.sfa.replication.ProductReplicator");
139: addRelatedEntityMap("", "ProductCategory", null, false, false,
140: "com.sourcetap.sfa.replication.ProductCategoryReplicator");
141: addRelatedEntityMap("", "UiApplication", null, true, true, "");
142: addRelatedEntityMap("", "UiAttribute", null, true, true, "");
143: addRelatedEntityMap("", "UiDisplayAttrib", null, true, true, "");
144: addRelatedEntityMap("", "UiDisplayObject", null, true, true, "");
145: addRelatedEntityMap("", "UiDisplayObjectAttrib", null, true,
146: true, "");
147: addRelatedEntityMap("", "UiDisplayType", null, true, true, "");
148: addRelatedEntityMap("", "UiEntity", null, true, true, "");
149: addRelatedEntityMap("", "UiLayoutType", null, true, true, "");
150: addRelatedEntityMap("", "UiQuery", null, true, true, "");
151: addRelatedEntityMap("", "UiQueryValue", null, true, true, "");
152: addRelatedEntityMap("", "UiScreen", null, true, true, "");
153: addRelatedEntityMap("", "UiScreenSection", null, true, true, "");
154: addRelatedEntityMap("", "UiScreenSectionEntity", null, true,
155: true, "");
156: addRelatedEntityMap("", "UiScreenSectionInfo", null, true,
157: true, "");
158: addRelatedEntityMap("", "UserPreferenceDefinitions", null,
159: true, true, "");
160: }
161:
162: /**
163: * This method finds all instances of an entity related to the main entity.
164: *
165: * This method overrides the ancestor to filter out instances for the SFA application.
166: *
167: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
168: *
169: * @param mainInstance Main entity instance for which related entities will be replicated
170: * @param relationTitle Relation title to be used by the entity engine to find related
171: * entity instances
172: * @param relatedEntityName Name of the related entity to be replicated
173: * @param filterMap HashMap containing additional filter values to be used by the entity
174: * engine when finding related entity instances
175: *
176: * @return List of generic values related to the main entity instance
177: */
178: protected List findOneRelated(GenericDelegator delegator,
179: GenericValue mainInstance, String relationTitle,
180: String relatedEntityName, HashMap filterMap, boolean findAll) {
181: Debug.logVerbose("[findOneRelated] Start", module);
182:
183: List relatedGVL = null;
184:
185: if (relatedEntityName.equals("Code")) {
186: // Special processing for Code entity. Exclude replication node ID parameter.
187: return findCodes(delegator);
188: } else if (relatedEntityName.equals("Account") && !findAll) {
189: // Special processing for Account entity unless the findAll flag was set, which
190: // means we are removing, in which case the default search will be done.
191: // If findAll was not set, we are replicating, so we need to
192: // Filter accounts according to the company's security settings.
193: return findAccounts(delegator);
194: } else if (relatedEntityName.equals("Product")) {
195: // Special processing for Product entity.
196: try {
197: return ProductHelper.getProducts(delegator,
198: getUserInfo());
199: } catch (GenericEntityException e) {
200: Debug.logError(
201: "[findOneRelated] An error occurred while finding "
202: + "Product instances: "
203: + e.getLocalizedMessage(), module);
204:
205: return null;
206: }
207: } else if (relatedEntityName.equals("ProductCategory")) {
208: // Special processing for ProductCategory entity.
209: try {
210: return ProductHelper.getProductCategories(delegator,
211: getUserInfo());
212: } catch (GenericEntityException e) {
213: Debug.logError(
214: "[findOneRelated] An error occurred while finding "
215: + "Product Category instances: "
216: + e.getLocalizedMessage(), module);
217:
218: return null;
219: }
220: } else {
221: // Default processing for all other entities.
222: return super .findOneRelated(delegator, mainInstance,
223: relationTitle, relatedEntityName, filterMap,
224: findAll);
225: }
226: }
227:
228: /**
229: * This method finds all instances of the Code entity for replication. The code holding
230: * the system parameter for the replication node ID is excluded.
231: *
232: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
233: *
234: * @return List of Code generic values
235: */
236: protected List findCodes(GenericDelegator delegator) {
237: Debug.logVerbose("[findCodes] Start", module);
238:
239: List filteredGVL = new LinkedList();
240:
241: // Replicate all Codes except the system parameter that holds
242: // the replication node ID.
243: try {
244: List codeGVL = delegator.findAll("Code");
245: Iterator codeGVI = codeGVL.iterator();
246:
247: // Remove codes from the data base except the ones we want to skip.
248: while (codeGVI.hasNext()) {
249: GenericValue codeGV = (GenericValue) codeGVI.next();
250: String codeTypeId = codeGV.getString("codeTypeId");
251: String codeId = codeGV.getString("codeId");
252:
253: if (!codeTypeId.equals("SYSTEM_PARAMETER")
254: && !codeId.equals("REPL_NODE_ID")) {
255: filteredGVL.add(codeGV);
256: }
257: }
258: } catch (GenericEntityException e) {
259: Debug.logError(
260: "[findCodes] An error occurred while finding "
261: + "Code instances: "
262: + e.getLocalizedMessage(), module);
263:
264: return null;
265: }
266:
267: return filteredGVL;
268: }
269:
270: /**
271: * This method finds all Accounts for replication. Filtering is applied according
272: * to the company's security settings. Accounts will be limited to the current
273: * user's company regardless of security settings, even if the mode is ALL.
274: * Team or territory filtering will be applied if specified in the company's
275: * security settings.
276: *
277: * @author <a href='mailto:jnutting@sourcetap.com'>John Nutting</a>
278: *
279: * @return List of Account generic values
280: */
281: protected List findAccounts(GenericDelegator delegator) {
282: Debug.logVerbose("[findAccounts] Start", module);
283:
284: if (getUserInfo() == null) {
285: Debug.logError("[findAccounts] User info is required.",
286: module);
287:
288: return null;
289: }
290:
291: ;
292:
293: if (delegator == null) {
294: Debug.logError("[findAccounts] Delegator is required.",
295: module);
296:
297: return null;
298: }
299:
300: ;
301:
302: Debug.logVerbose("[findAccounts] getUserInfo(): "
303: + getUserInfo(), module);
304:
305: // Find the base account for this company so it will go first in the list.
306: // We want to make sure this one gets replicated first in case there is a
307: // problem so the user will still be able to log into the local system.
308: HashMap companyFindMap = new HashMap();
309: companyFindMap.put("accountId", getUserInfo().getAccountId());
310:
311: try {
312: GenericValue companyGV = delegator.findByPrimaryKey(
313: "Account", companyFindMap);
314:
315: Debug.logVerbose("[findAccounts] Company account: "
316: + companyGV.toString(), module);
317:
318: List accountGVL = new LinkedList();
319: accountGVL.add(companyGV);
320:
321: // Find all the non-base accounts this user is allowed to see.
322: EntityCondition condition = new EntityExpr("accountTypeId",
323: EntityOperator.NOT_EQUAL, "base");
324:
325: try {
326: accountGVL.addAll(SecurityWrapper.findByCondition(
327: "Account", condition, null, getUserInfo(),
328: new SecurityLinkInfo("Account", "accountId",
329: true), delegator));
330:
331: Debug.logVerbose("[findAccounts] Account List: "
332: + accountGVL.toString(), module);
333:
334: return accountGVL;
335: } catch (GenericEntityException e2) {
336: Debug
337: .logError(
338: "[findAccounts] An error occurred in "
339: + "SecurityWrapper.findByCondition while looking for non-base accounts: "
340: + e2.getLocalizedMessage(),
341: module);
342:
343: return null;
344: }
345: } catch (GenericEntityException e1) {
346: Debug.logError(
347: "[findAccounts] An error occurred while looking for the "
348: + "base company account: "
349: + e1.getLocalizedMessage(), module);
350:
351: return null;
352: }
353: }
354: }
|