001: /*
002: * Copyright 2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.module.chart.rules;
017:
018: import java.util.List;
019:
020: import org.apache.commons.lang.StringUtils;
021: import org.kuali.core.bo.PersistableBusinessObject;
022: import org.kuali.core.document.MaintenanceDocument;
023: import org.kuali.core.util.GlobalVariables;
024: import org.kuali.kfs.KFSConstants;
025: import org.kuali.kfs.KFSKeyConstants;
026: import org.kuali.kfs.KFSPropertyConstants;
027: import org.kuali.module.chart.bo.AccountGlobalDetail;
028: import org.kuali.module.chart.bo.SubObjCdGlobal;
029: import org.kuali.module.chart.bo.SubObjCdGlobalDetail;
030:
031: /**
032: *
033: * This class implements the business rules specific to the {@link SubObjCdGlobal} Maintenance Document.
034: */
035: public class SubObjCdGlobalRule extends GlobalDocumentRuleBase {
036: private SubObjCdGlobal subObjCdGlobal;
037:
038: /**
039: * This method sets the convenience objects like subObjCdGlobal and all the detail objects, so you have short and easy handles to the new and
040: * old objects contained in the maintenance document. It also calls the BusinessObjectBase.refresh(), which will attempt to load
041: * all sub-objects from the DB by their primary keys, if available. This also loops through each detail item (SubObjCdGlobalDetail and AccountGlobalDetail)
042: * are refreshed
043: *
044: * @param document - the maintenanceDocument being evaluated
045: */
046: @Override
047: public void setupConvenienceObjects() {
048:
049: // setup subObjCdGlobal convenience objects,
050: // make sure all possible sub-objects are populated
051: subObjCdGlobal = (SubObjCdGlobal) super .getNewBo();
052:
053: // forces refreshes on all the sub-objects in the lists
054: for (SubObjCdGlobalDetail objectCodeGlobalDetail : subObjCdGlobal
055: .getSubObjCdGlobalDetails()) {
056: objectCodeGlobalDetail.refreshNonUpdateableReferences();
057: }
058: for (AccountGlobalDetail accountGlobalDetail : subObjCdGlobal
059: .getAccountGlobalDetails()) {
060: accountGlobalDetail.refreshNonUpdateableReferences();
061: }
062: }
063:
064: /**
065: * This performs rules checks on document approve
066: * <ul>
067: * <li>{@link SubObjCdGlobalRule#checkSimpleRulesAllLines()}</li>
068: * </ul>
069: * This rule fails on business rule failures
070: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomApproveDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
071: */
072: @Override
073: protected boolean processCustomApproveDocumentBusinessRules(
074: MaintenanceDocument document) {
075: boolean success = true;
076: setupConvenienceObjects();
077: // check simple rules
078: success &= checkSimpleRulesAllLines();
079:
080: success &= checkOnlyOneChartErrorWrapper(subObjCdGlobal
081: .getAccountGlobalDetails());
082:
083: return success;
084: }
085:
086: /**
087: * This performs rules checks on document route
088: * <ul>
089: * <li>{@link SubObjCdGlobalRule#checkSimpleRulesAllLines()}</li>
090: * </ul>
091: * This rule fails on business rule failures
092: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
093: */
094: @Override
095: protected boolean processCustomRouteDocumentBusinessRules(
096: MaintenanceDocument document) {
097: boolean success = true;
098: setupConvenienceObjects();
099: // check simple rules
100: success &= checkSimpleRulesAllLines();
101:
102: success &= checkAccountDetails(subObjCdGlobal
103: .getAccountGlobalDetails());
104:
105: return success;
106: }
107:
108: /**
109: * This performs rules checks on document save
110: * <ul>
111: * <li>{@link SubObjCdGlobalRule#checkSimpleRulesAllLines()}</li>
112: * </ul>
113: * This rule does not fail on business rule failures
114: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
115: */
116: @Override
117: protected boolean processCustomSaveDocumentBusinessRules(
118: MaintenanceDocument document) {
119: setupConvenienceObjects();
120: // check simple rules
121: checkSimpleRulesAllLines();
122:
123: return true;
124: }
125:
126: /**
127: * Before adding either a {@link AccountGlobalDetail} or {@link SubObjCdGlobalDetail} this checks to make sure
128: * that the account and chart are filled in, in the case of SubObjCdGlobalDetail it also checks
129: * that the object code and fiscal year are filled in
130: * If any of these fail, it fails to add the new line to the collection
131: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.core.document.MaintenanceDocument, java.lang.String, org.kuali.core.bo.PersistableBusinessObject)
132: */
133: public boolean processCustomAddCollectionLineBusinessRules(
134: MaintenanceDocument document, String collectionName,
135: PersistableBusinessObject bo) {
136: boolean success = true;
137: if (bo instanceof AccountGlobalDetail) {
138: AccountGlobalDetail detail = (AccountGlobalDetail) bo;
139: // make sure that both primary keys are available for this object
140: if (!checkEmptyValue(detail.getAccountNumber())) {
141: // put an error about accountnumber
142: GlobalVariables.getErrorMap().putError("accountNumber",
143: KFSKeyConstants.ERROR_REQUIRED,
144: "Account Number");
145: success &= false;
146: }
147: if (!checkEmptyValue(detail.getChartOfAccountsCode())) {
148: // put an error about chart code
149: GlobalVariables.getErrorMap().putError(
150: "chartOfAccountsCode",
151: KFSKeyConstants.ERROR_REQUIRED,
152: "Chart of Accounts Code");
153: success &= false;
154: }
155: success &= checkAccountDetails(detail);
156: } else if (bo instanceof SubObjCdGlobalDetail) {
157: SubObjCdGlobalDetail detail = (SubObjCdGlobalDetail) bo;
158: if (!checkEmptyValue(detail.getChartOfAccountsCode())) {
159: // put an error about accountnumber
160: GlobalVariables.getErrorMap().putError(
161: "chartOfAccountsCode",
162: KFSKeyConstants.ERROR_REQUIRED,
163: "Chart of Accounts Code");
164: success &= false;
165: }
166: if (!checkEmptyValue(detail.getFinancialObjectCode())) {
167: // put an error about financial object code
168: GlobalVariables.getErrorMap().putError(
169: "financialObjectCode",
170: KFSKeyConstants.ERROR_REQUIRED,
171: "Financial Object Code");
172: success &= false;
173: }
174: if (!checkEmptyValue(detail.getUniversityFiscalYear())) {
175: // put an error about financial object code
176: GlobalVariables.getErrorMap().putError(
177: "universityFiscalYear",
178: KFSKeyConstants.ERROR_REQUIRED,
179: "University Fiscal Year");
180: success &= false;
181: }
182: success &= checkSubObjectCodeDetails(detail);
183: }
184: return success;
185: }
186:
187: /**
188: *
189: * This calls the {@link SubObjCdGlobalRule#checkAccountDetails(AccountGlobalDetail)} on each AccountGlobalDetail as well as calling
190: * {@link SubObjCdGlobalRule#checkOnlyOneChartErrorWrapper(List)} to ensure there is just one chart
191: * @param details
192: * @return false if any of the detail objects fail they're sub-rule
193: */
194: public boolean checkAccountDetails(List<AccountGlobalDetail> details) {
195: boolean success = true;
196:
197: // check if there are any accounts
198: if (details.size() == 0) {
199: putFieldError(
200: KFSConstants.MAINTENANCE_ADD_PREFIX
201: + "accountGlobalDetails.accountNumber",
202: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_NO_ACCOUNTS);
203: success = false;
204: } else {
205: // check each account
206: int index = 0;
207: for (AccountGlobalDetail dtl : details) {
208: String errorPath = MAINTAINABLE_ERROR_PREFIX
209: + "accountGlobalDetails[" + index + "]";
210: GlobalVariables.getErrorMap().addToErrorPath(errorPath);
211: success &= checkAccountDetails(dtl);
212: GlobalVariables.getErrorMap().removeFromErrorPath(
213: errorPath);
214: index++;
215: }
216: success &= checkOnlyOneChartErrorWrapper(details);
217: }
218:
219: return success;
220: }
221:
222: /**
223: *
224: * This checks that if the account and chart are entered that the account associated with the AccountGlobalDetail is valid
225: * @param dtl - the AccountGlobalDetail we are dealing with
226: * @return false if any of the fields are found to be invalid
227: */
228: public boolean checkAccountDetails(AccountGlobalDetail dtl) {
229: boolean success = true;
230: int originalErrorCount = GlobalVariables.getErrorMap()
231: .getErrorCount();
232: getDictionaryValidationService().validateBusinessObject(dtl);
233: if (StringUtils.isNotBlank(dtl.getAccountNumber())
234: && StringUtils.isNotBlank(dtl.getChartOfAccountsCode())) {
235: dtl.refreshReferenceObject("account");
236: if (dtl.getAccount() == null) {
237: GlobalVariables
238: .getErrorMap()
239: .putError(
240: "accountNumber",
241: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_INVALID_ACCOUNT,
242: new String[] {
243: dtl.getChartOfAccountsCode(),
244: dtl.getAccountNumber() });
245: }
246: }
247: success &= GlobalVariables.getErrorMap().getErrorCount() == originalErrorCount;
248:
249: return success;
250: }
251:
252: /**
253: *
254: * This checks that if the object code, chart code, and fiscal year are entered it is a valid Object Code, chart, and Fiscal Year
255: * associated with this SubObjectCode
256: * @param dtl - the SubObjCdGlobalDetail we are checking
257: * @return false if any of the fields are found to be invalid
258: */
259: public boolean checkSubObjectCodeDetails(SubObjCdGlobalDetail dtl) {
260: boolean success = true;
261: int originalErrorCount = GlobalVariables.getErrorMap()
262: .getErrorCount();
263: getDictionaryValidationService().validateBusinessObject(dtl);
264: if (StringUtils.isNotBlank(dtl.getFinancialObjectCode())
265: && StringUtils.isNotBlank(dtl.getChartOfAccountsCode())
266: && dtl.getUniversityFiscalYear() > 0) {
267: dtl.refreshReferenceObject("financialObject");
268: dtl.refreshReferenceObject("universityFiscal");
269: dtl.refreshReferenceObject("chartOfAccounts");
270: if (dtl.getChartOfAccounts() == null
271: || dtl.getUniversityFiscal() == null
272: || dtl.getFinancialObject() == null) {
273: GlobalVariables
274: .getErrorMap()
275: .putError(
276: "financialObjectCode",
277: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_INVALID_OBJECT_CODE,
278: new String[] {
279: dtl.getFinancialObjectCode(),
280: dtl.getChartOfAccountsCode(),
281: dtl.getUniversityFiscalYear()
282: .toString() });
283: }
284: }
285: success &= GlobalVariables.getErrorMap().getErrorCount() == originalErrorCount;
286:
287: return success;
288: }
289:
290: /**
291: * This method checks the simple rules for all lines at once and gets called on save, submit, etc. but not on add
292: * <ul>
293: * <li>{@link SubObjCdGlobalRule#checkForSubObjCdGlobalDetails(List)}</li>
294: * <li>{@link SubObjCdGlobalRule#checkForAccountGlobalDetails(List)}</li>
295: * <li>{@link SubObjCdGlobalRule#checkFiscalYearAllLines(SubObjCdGlobal)}</li>
296: * <li>{@link SubObjCdGlobalRule#checkChartAllLines(SubObjCdGlobal)}</li>
297: * </ul>
298: * @return
299: */
300: protected boolean checkSimpleRulesAllLines() {
301: boolean success = true;
302: // check if there are any object codes and accounts, if either fails this should fail
303: if (!checkForSubObjCdGlobalDetails(subObjCdGlobal
304: .getSubObjCdGlobalDetails())
305: && !checkForAccountGlobalDetails(subObjCdGlobal
306: .getAccountGlobalDetails())) {
307: success = false;
308: } else {
309: // check object codes
310: success &= checkFiscalYearAllLines(subObjCdGlobal);
311:
312: // check chart code
313: success &= checkChartAllLines(subObjCdGlobal);
314:
315: }
316: return success;
317: }
318:
319: /**
320: *
321: * This checks that the SubObjCdGlobalDetail list isn't empty or null
322: * @param subObjCdGlobalDetails
323: * @return false if the list is null or empty
324: */
325: protected boolean checkForSubObjCdGlobalDetails(
326: List<SubObjCdGlobalDetail> subObjCdGlobalDetails) {
327: if (subObjCdGlobalDetails == null
328: || subObjCdGlobalDetails.size() == 0) {
329: putFieldError(
330: KFSConstants.MAINTENANCE_ADD_PREFIX
331: + KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
332: + "."
333: + KFSPropertyConstants.FINANCIAL_DOCUMENT_TYPE_CODE,
334: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_NO_OBJECT_CODE);
335: return false;
336: }
337: return true;
338: }
339:
340: /**
341: *
342: * This checks that the AccountGlobalDetail list isn't empty or null
343: * @param acctChangeDetails
344: * @return false if the list is null or empty
345: */
346: protected boolean checkForAccountGlobalDetails(
347: List<AccountGlobalDetail> acctChangeDetails) {
348: if (acctChangeDetails == null || acctChangeDetails.size() == 0) {
349: putFieldError(
350: KFSConstants.MAINTENANCE_ADD_PREFIX
351: + KFSPropertyConstants.ACCOUNT_CHANGE_DETAILS
352: + "."
353: + KFSPropertyConstants.FINANCIAL_DOCUMENT_TYPE_CODE,
354: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_NO_ACCOUNT);
355: return false;
356: }
357: return true;
358: }
359:
360: /**
361: *
362: * This checks that the fiscal year is the same on the doc and all SubObjCdGlobalDetails
363: * @param socChangeDocument
364: * @return false if the fiscal year is not the same on the doc and any of the SubObjCdGlobalDetails
365: */
366: protected boolean checkFiscalYearAllLines(
367: SubObjCdGlobal socChangeDocument) {
368: boolean success = true;
369: int i = 0;
370: for (SubObjCdGlobalDetail subObjCdGlobal : socChangeDocument
371: .getSubObjCdGlobalDetails()) {
372:
373: // check fiscal year first
374: success &= checkFiscalYear(socChangeDocument,
375: subObjCdGlobal, i, false);
376:
377: // increment counter for sub object changes list
378: i++;
379: }
380:
381: return success;
382: }
383:
384: /**
385: *
386: * This checks that the chart is the same on the document, SubObjCdGlobalDetails and AccountGlobalDetails
387: * @param socChangeDocument
388: * @return false if the chart is missing or not the same on the doc, or the detail lists
389: */
390: protected boolean checkChartAllLines(
391: SubObjCdGlobal socChangeDocument) {
392: boolean success = true;
393: int i = 0;
394: for (SubObjCdGlobalDetail subObjCdGlobal : socChangeDocument
395: .getSubObjCdGlobalDetails()) {
396:
397: // check chart
398: success &= checkChartOnSubObjCodeDetails(socChangeDocument,
399: subObjCdGlobal, i, false);
400: // increment counter for sub object changes list
401: i++;
402: }
403:
404: // check each account change
405: i = 0;
406: for (AccountGlobalDetail acctChangeDetail : socChangeDocument
407: .getAccountGlobalDetails()) {
408:
409: // check chart
410: success &= checkChartOnAccountDetails(socChangeDocument,
411: acctChangeDetail, i, false);
412: // increment counter for account changes list
413: i++;
414: }
415:
416: return success;
417: }
418:
419: /**
420: * This checks to make sure that the fiscal year on the {@link SubObjCdGlobalDetail} is not empty and
421: * the document's fiscal year matches the detail's fiscal year
422: *
423: * @param socChangeDocument
424: * @return false if the fiscal year is missing or is not the same between the doc and the detail
425: */
426: protected boolean checkFiscalYear(SubObjCdGlobal socChangeDocument,
427: SubObjCdGlobalDetail socChangeDetail, int lineNum,
428: boolean add) {
429: boolean success = true;
430: String errorPath = KFSConstants.EMPTY_STRING;
431: // first must have an actual fiscal year
432: if (socChangeDetail.getUniversityFiscal() == null) {
433: if (add) {
434: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
435: + KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
436: + "." + "universityFiscalYear";
437: putFieldError(
438: errorPath,
439: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_FISCAL_YEAR_MUST_EXIST);
440: } else {
441: errorPath = KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
442: + "[" + lineNum + "]." + "universityFiscalYear";
443: putFieldError(
444: errorPath,
445: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_FISCAL_YEAR_MUST_EXIST);
446: }
447: success &= false;
448: return success;
449: }
450:
451: // the two fiscal years from the document and detail must match
452: if (!socChangeDocument.getUniversityFiscal().equals(
453: socChangeDetail.getUniversityFiscal())) {
454: if (add) {
455: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
456: + KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
457: + "." + "universityFiscalYear";
458: putFieldError(
459: errorPath,
460: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_FISCAL_YEAR_MUST_BE_SAME);
461: } else {
462: errorPath = KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
463: + "[" + lineNum + "]." + "universityFiscalYear";
464: putFieldError(
465: errorPath,
466: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_FISCAL_YEAR_MUST_BE_SAME);
467: }
468: success &= false;
469: return success;
470: }
471:
472: return success;
473: }
474:
475: /**
476: *
477: * This checks to make sure that the chart of accounts on the {@link SubObjCdGlobalDetail} is not empty and
478: * the document's chart matches the detail's chart
479: * @param socChangeDocument
480: * @param socChangeDetail
481: * @param lineNum
482: * @param add
483: * @return false if the chart is missing or is not the same between the doc and the detail
484: */
485: protected boolean checkChartOnSubObjCodeDetails(
486: SubObjCdGlobal socChangeDocument,
487: SubObjCdGlobalDetail socChangeDetail, int lineNum,
488: boolean add) {
489: boolean success = true;
490: String errorPath = KFSConstants.EMPTY_STRING;
491: // first must have an actual fiscal year
492: if (socChangeDetail.getChartOfAccounts() == null) {
493: if (add) {
494: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
495: + KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
496: + "." + "chartOfAccountsCode";
497: putFieldError(
498: errorPath,
499: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_CHART_MUST_EXIST);
500: } else {
501: errorPath = KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
502: + "[" + lineNum + "]." + "chartOfAccountsCode";
503: putFieldError(
504: errorPath,
505: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_CHART_MUST_EXIST);
506: }
507: success &= false;
508: return success;
509: }
510:
511: // the two fiscal years from the document and detail must match
512: if (!socChangeDocument.getChartOfAccounts().equals(
513: socChangeDetail.getChartOfAccounts())) {
514: if (add) {
515: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
516: + KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
517: + "." + "chartOfAccountsCode";
518: putFieldError(
519: errorPath,
520: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_CHART_MUST_BE_SAME);
521: } else {
522: errorPath = KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
523: + "[" + lineNum + "]." + "chartOfAccountsCode";
524: putFieldError(
525: errorPath,
526: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_CHART_MUST_BE_SAME);
527: }
528: success &= false;
529: return success;
530: }
531:
532: return success;
533: }
534:
535: /**
536: *
537: * This checks that the chart of accounts on the {@link AccountGlobalDetail} is not empty and matches
538: * the document's chart matches the detail's chart
539: * @param socChangeDocument
540: * @param acctDetail
541: * @param lineNum
542: * @param add
543: * @return false if the chart is missing or is not the same between the doc and the detail
544: */
545: protected boolean checkChartOnAccountDetails(
546: SubObjCdGlobal socChangeDocument,
547: AccountGlobalDetail acctDetail, int lineNum, boolean add) {
548: boolean success = true;
549: String errorPath = KFSConstants.EMPTY_STRING;
550: // first must have an actual fiscal year
551: if (acctDetail.getChartOfAccounts() == null) {
552: if (add) {
553: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
554: + KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
555: + "." + "chartOfAccountsCode";
556: putFieldError(
557: errorPath,
558: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_CHART_MUST_EXIST);
559: } else {
560: errorPath = KFSPropertyConstants.SUB_OBJ_CODE_CHANGE_DETAILS
561: + "[" + lineNum + "]." + "chartOfAccountsCode";
562: putFieldError(
563: errorPath,
564: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_CHART_MUST_EXIST);
565: }
566: success &= false;
567: return success;
568: }
569:
570: // the two fiscal years from the document and detail must match
571: if (!socChangeDocument.getChartOfAccounts().equals(
572: acctDetail.getChartOfAccounts())) {
573: if (add) {
574: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
575: + KFSPropertyConstants.ACCOUNT_CHANGE_DETAILS
576: + "." + "chartOfAccountsCode";
577: putFieldError(
578: errorPath,
579: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_CHART_MUST_BE_SAME);
580: } else {
581: errorPath = KFSPropertyConstants.ACCOUNT_CHANGE_DETAILS
582: + "[" + lineNum + "]." + "chartOfAccountsCode";
583: putFieldError(
584: errorPath,
585: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_SUBOBJECTMAINT_CHART_MUST_BE_SAME);
586: }
587: success &= false;
588: return success;
589: }
590:
591: return success;
592: }
593:
594: }
|