Source Code Cross Referenced for KualiOrgReviewAttribute.java in  » ERP-CRM-Financial » Kuali-Financial-System » org » kuali » workflow » attribute » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » ERP CRM Financial » Kuali Financial System » org.kuali.workflow.attribute 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2006-2007 The Kuali Foundation.
0003:         *
0004:         * Licensed under the Educational Community License, Version 1.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         * http://www.opensource.org/licenses/ecl1.php
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:
0017:        package org.kuali.workflow.attribute;
0018:
0019:        import java.util.ArrayList;
0020:        import java.util.Collections;
0021:        import java.util.Comparator;
0022:        import java.util.HashMap;
0023:        import java.util.HashSet;
0024:        import java.util.Iterator;
0025:        import java.util.List;
0026:        import java.util.Map;
0027:        import java.util.Set;
0028:
0029:        import javax.xml.xpath.XPath;
0030:        import javax.xml.xpath.XPathConstants;
0031:
0032:        import org.apache.commons.lang.StringUtils;
0033:        import org.apache.log4j.Logger;
0034:        import org.kuali.core.bo.DocumentHeader;
0035:        import org.kuali.core.lookup.LookupUtils;
0036:        import org.kuali.core.util.FieldUtils;
0037:        import org.kuali.core.util.KualiDecimal;
0038:        import org.kuali.core.util.ObjectUtils;
0039:        import org.kuali.core.workflow.attribute.WorkflowLookupableImpl;
0040:        import org.kuali.kfs.KFSConstants;
0041:        import org.kuali.kfs.KFSPropertyConstants;
0042:        import org.kuali.kfs.bo.SourceAccountingLine;
0043:        import org.kuali.kfs.context.SpringContext;
0044:        import org.kuali.module.chart.bo.Account;
0045:        import org.kuali.module.chart.bo.Chart;
0046:        import org.kuali.module.chart.bo.Org;
0047:        import org.kuali.module.chart.service.AccountService;
0048:        import org.kuali.module.chart.service.OrganizationService;
0049:        import org.kuali.workflow.KualiWorkflowUtils;
0050:        import org.w3c.dom.Document;
0051:        import org.w3c.dom.Element;
0052:        import org.w3c.dom.Node;
0053:        import org.w3c.dom.NodeList;
0054:
0055:        import edu.iu.uis.eden.WorkflowServiceErrorImpl;
0056:        import edu.iu.uis.eden.doctype.DocumentType;
0057:        import edu.iu.uis.eden.engine.RouteContext;
0058:        import edu.iu.uis.eden.lookupable.Field;
0059:        import edu.iu.uis.eden.lookupable.Row;
0060:        import edu.iu.uis.eden.plugin.attributes.MassRuleAttribute;
0061:        import edu.iu.uis.eden.plugin.attributes.WorkflowAttribute;
0062:        import edu.iu.uis.eden.routeheader.DocumentContent;
0063:        import edu.iu.uis.eden.routetemplate.RuleBaseValues;
0064:        import edu.iu.uis.eden.routetemplate.RuleExtension;
0065:        import edu.iu.uis.eden.routetemplate.RuleExtensionValue;
0066:        import edu.iu.uis.eden.util.Utilities;
0067:
0068:        /**
0069:         * KualiOrgReviewAttribute should be used when using Orgs and thier inner details to do routing.
0070:         */
0071:        public class KualiOrgReviewAttribute implements  WorkflowAttribute,
0072:                MassRuleAttribute {
0073:
0074:            static final long serialVersionUID = 1000;
0075:
0076:            private static Logger LOG = Logger
0077:                    .getLogger(KualiOrgReviewAttribute.class);
0078:
0079:            public static final String FIN_COA_CD_KEY = "fin_coa_cd";
0080:
0081:            public static final String ORG_CD_KEY = "org_cd";
0082:
0083:            public static final String FROM_AMOUNT_KEY = "fromAmount";
0084:
0085:            public static final String TO_AMOUNT_KEY = "toAmount";
0086:
0087:            private static final String TOTAL_AMOUNT_KEY = "totalAmount";
0088:
0089:            public static final String OVERRIDE_CD_KEY = "overrideCd";
0090:
0091:            private static final String ORG_REVIEW_ATTRIBUTE = "KUALI_ORG_REVIEW_ATTRIBUTE";
0092:
0093:            private static Map ORGS = new HashMap();
0094:
0095:            private static final String DOCUMENT_CHART_ORG_VALUES_KEY = "organizations";
0096:
0097:            private String finCoaCd;
0098:
0099:            private String orgCd;
0100:
0101:            private String toAmount;
0102:
0103:            private String fromAmount;
0104:
0105:            private String overrideCd;
0106:
0107:            private String totalDollarAmount;
0108:
0109:            private boolean required;
0110:
0111:            private List ruleRows;
0112:
0113:            private List routingDataRows;
0114:
0115:            /**
0116:             * TODO clean the rest of the field defs up once chart is working this code up no arg constructor, which will initialize the
0117:             * fields and rows of the attribute
0118:             */
0119:            public KualiOrgReviewAttribute() {
0120:                List fields = new ArrayList();
0121:
0122:                ruleRows = new ArrayList();
0123:                ruleRows.add(getChartRowUsingKualiWorkflowUtils());
0124:                ruleRows.add(getOrgRowUsingKualiWorkflowUtils());
0125:                ruleRows.add(getOverrideCodeRowUsingKualiWorkflowUtils());
0126:
0127:                fields = new ArrayList();
0128:                fields.add(new Field("From Amount", "", Field.TEXT, true,
0129:                        FROM_AMOUNT_KEY, "", null, null, FROM_AMOUNT_KEY));
0130:                ruleRows.add(new Row(fields));
0131:                fields = new ArrayList();
0132:                fields.add(new Field("To Amount", "", Field.TEXT, true,
0133:                        TO_AMOUNT_KEY, "", null, null, TO_AMOUNT_KEY));
0134:                ruleRows.add(new Row(fields));
0135:
0136:                routingDataRows = new ArrayList();
0137:                routingDataRows.add(getChartRowUsingKualiWorkflowUtils());
0138:                routingDataRows.add(getOrgRowUsingKualiWorkflowUtils());
0139:                routingDataRows
0140:                        .add(getOverrideCodeRowUsingKualiWorkflowUtils());
0141:
0142:                // fields = new ArrayList();
0143:                // fields.add(new Field("Total Amount", "", Field.TEXT, true, TOTAL_AMOUNT_KEY, "", null, null, TOTAL_AMOUNT_KEY));
0144:                // routingDataRows.add(new Row(fields));
0145:                routingDataRows.add(KualiWorkflowUtils.buildTextRow(
0146:                        DocumentHeader.class,
0147:                        KFSPropertyConstants.FINANCIAL_DOCUMENT_TOTAL_AMOUNT,
0148:                        TOTAL_AMOUNT_KEY));
0149:            }
0150:
0151:            /**
0152:             * This method produces a chart row.
0153:             *
0154:             * @return
0155:             * @deprecated Use getChartRowUsingKualiWorkflowUtils() instead
0156:             */
0157:            public edu.iu.uis.eden.lookupable.Row getChartRow() {
0158:                org.kuali.core.web.ui.Field kualiChartField = FieldUtils
0159:                        .getPropertyField(
0160:                                Chart.class,
0161:                                KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
0162:                                false);
0163:                List chartFields = new ArrayList();
0164:                chartFields.add(new Field(kualiChartField.getFieldLabel(),
0165:                        KualiWorkflowUtils.getHelpUrl(kualiChartField),
0166:                        Field.TEXT, true, FIN_COA_CD_KEY, kualiChartField
0167:                                .getPropertyValue(), kualiChartField
0168:                                .getFieldValidValues(), WorkflowLookupableImpl
0169:                                .getLookupableImplName(Chart.class),
0170:                        FIN_COA_CD_KEY));
0171:                chartFields
0172:                        .add(new Field(
0173:                                "",
0174:                                "",
0175:                                Field.QUICKFINDER,
0176:                                false,
0177:                                "",
0178:                                "",
0179:                                null,
0180:                                WorkflowLookupableImpl
0181:                                        .getLookupableName(
0182:                                                WorkflowLookupableImpl
0183:                                                        .getLookupableImplName(Chart.class),
0184:                                                new StringBuffer(
0185:                                                        WorkflowLookupableImpl.LOOKUPABLE_IMPL_NAME_PREFIX)
0186:                                                        .append(
0187:                                                                KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME)
0188:                                                        .append(":").append(
0189:                                                                FIN_COA_CD_KEY)
0190:                                                        .toString())));
0191:                return new Row(chartFields);
0192:            }
0193:
0194:            public edu.iu.uis.eden.lookupable.Row getChartRowUsingKualiWorkflowUtils() {
0195:                return KualiWorkflowUtils.buildTextRowWithLookup(Chart.class,
0196:                        KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
0197:                        FIN_COA_CD_KEY);
0198:            }
0199:
0200:            /**
0201:             * This method produces an org row.
0202:             *
0203:             * @return
0204:             * @deprecated Use getOrgRowUsingKualiWorkflowUtils() instead
0205:             */
0206:            public edu.iu.uis.eden.lookupable.Row getOrgRow() {
0207:                org.kuali.core.web.ui.Field kualiOrgField = FieldUtils
0208:                        .getPropertyField(Org.class,
0209:                                KFSConstants.ORGANIZATION_CODE_PROPERTY_NAME,
0210:                                false);
0211:                List orgFields = new ArrayList();
0212:                orgFields.add(new Field(kualiOrgField.getFieldLabel(),
0213:                        KualiWorkflowUtils.getHelpUrl(kualiOrgField),
0214:                        Field.TEXT, true, ORG_CD_KEY, kualiOrgField
0215:                                .getPropertyValue(), kualiOrgField
0216:                                .getFieldValidValues(), WorkflowLookupableImpl
0217:                                .getLookupableImplName(Org.class), ORG_CD_KEY));
0218:                orgFields
0219:                        .add(new Field(
0220:                                "",
0221:                                "",
0222:                                Field.QUICKFINDER,
0223:                                false,
0224:                                "",
0225:                                "",
0226:                                null,
0227:                                WorkflowLookupableImpl
0228:                                        .getLookupableName(
0229:                                                WorkflowLookupableImpl
0230:                                                        .getLookupableImplName(Org.class),
0231:                                                new StringBuffer("")
0232:                                                        .append(
0233:                                                                WorkflowLookupableImpl.LOOKUPABLE_IMPL_NAME_PREFIX)
0234:                                                        .append(
0235:                                                                KFSConstants.ORGANIZATION_CODE_PROPERTY_NAME)
0236:                                                        .append(":")
0237:                                                        .append(ORG_CD_KEY)
0238:                                                        .append(",")
0239:                                                        .append(
0240:                                                                WorkflowLookupableImpl.LOOKUPABLE_IMPL_NAME_PREFIX)
0241:                                                        .append(
0242:                                                                KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME)
0243:                                                        .append(":").append(
0244:                                                                FIN_COA_CD_KEY)
0245:                                                        .toString())));
0246:                return new Row(orgFields);
0247:            }
0248:
0249:            public edu.iu.uis.eden.lookupable.Row getOrgRowUsingKualiWorkflowUtils() {
0250:                Map fieldConversionMap = new HashMap();
0251:                fieldConversionMap.put(
0252:                        KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
0253:                        FIN_COA_CD_KEY);
0254:                return KualiWorkflowUtils.buildTextRowWithLookup(Org.class,
0255:                        KFSConstants.ORGANIZATION_CODE_PROPERTY_NAME,
0256:                        ORG_CD_KEY, fieldConversionMap);
0257:            }
0258:
0259:            /**
0260:             * This method produces an overrideCode row.
0261:             *
0262:             * @return
0263:             * @deprecated Use getOverrideCodeRowUsingKualiWorkflowUtils() instead
0264:             */
0265:            public edu.iu.uis.eden.lookupable.Row getOverrideCodeRow() {
0266:                org.kuali.core.web.ui.Field kualiOverrideCodeField;
0267:                kualiOverrideCodeField = FieldUtils.getPropertyField(
0268:                        SourceAccountingLine.class, "overrideCode", false);
0269:                List orgFields = new ArrayList();
0270:                orgFields.add(new Field(kualiOverrideCodeField.getFieldLabel(),
0271:                        KualiWorkflowUtils.getHelpUrl(kualiOverrideCodeField),
0272:                        Field.TEXT, true, OVERRIDE_CD_KEY,
0273:                        kualiOverrideCodeField.getPropertyValue(),
0274:                        kualiOverrideCodeField.getFieldValidValues(), null,
0275:                        OVERRIDE_CD_KEY));
0276:                return new Row(orgFields);
0277:            }
0278:
0279:            public edu.iu.uis.eden.lookupable.Row getOverrideCodeRowUsingKualiWorkflowUtils() {
0280:                return KualiWorkflowUtils.buildTextRow(
0281:                        SourceAccountingLine.class, "overrideCode",
0282:                        OVERRIDE_CD_KEY);
0283:            }
0284:
0285:            /**
0286:             * constructor that takes the chart, org, which calls the no arg constructor
0287:             *
0288:             * @param finCoaCd
0289:             * @param orgCd
0290:             */
0291:            public KualiOrgReviewAttribute(String finCoaCd, String orgCd) {
0292:                this ();
0293:                this .finCoaCd = LookupUtils.forceUppercase(Org.class,
0294:                        "chartOfAccountsCode", finCoaCd);
0295:                this .orgCd = LookupUtils.forceUppercase(Org.class,
0296:                        "organizationCode", orgCd);
0297:            }
0298:
0299:            public List getRuleExtensionValues() {
0300:                List extensions = new ArrayList();
0301:                extensions.add(new RuleExtensionValue(FIN_COA_CD_KEY,
0302:                        this .finCoaCd));
0303:                extensions.add(new RuleExtensionValue(ORG_CD_KEY, this .orgCd));
0304:                if (!StringUtils.isBlank(this .fromAmount)) {
0305:                    extensions.add(new RuleExtensionValue(FROM_AMOUNT_KEY,
0306:                            this .fromAmount));
0307:                }
0308:                if (!StringUtils.isBlank(this .toAmount)) {
0309:                    extensions.add(new RuleExtensionValue(TO_AMOUNT_KEY,
0310:                            this .toAmount));
0311:                }
0312:                if (!StringUtils.isBlank(this .overrideCd)) {
0313:                    extensions.add(new RuleExtensionValue(OVERRIDE_CD_KEY,
0314:                            this .overrideCd));
0315:                }
0316:                return extensions;
0317:            }
0318:
0319:            /**
0320:             * @see edu.iu.uis.eden.plugin.attributes.WorkflowAttribute#validateRuleData(java.util.Map)
0321:             */
0322:            public List validateRuleData(Map paramMap) {
0323:                List errors = new ArrayList();
0324:                this .finCoaCd = LookupUtils.forceUppercase(Org.class,
0325:                        "chartOfAccountsCode", (String) paramMap
0326:                                .get(FIN_COA_CD_KEY));
0327:                this .orgCd = LookupUtils.forceUppercase(Org.class,
0328:                        "organizationCode", (String) paramMap.get(ORG_CD_KEY));
0329:                this .fromAmount = (String) paramMap.get(FROM_AMOUNT_KEY);
0330:                this .toAmount = (String) paramMap.get(TO_AMOUNT_KEY);
0331:                this .overrideCd = LookupUtils.forceUppercase(
0332:                        SourceAccountingLine.class, "overrideCode",
0333:                        (String) paramMap.get(OVERRIDE_CD_KEY));
0334:                if (isRequired()) {
0335:                    validateOrg(errors);
0336:                    if (StringUtils.isNotBlank(toAmount)
0337:                            && !StringUtils.isNumeric(toAmount)) {
0338:                        errors
0339:                                .add(new WorkflowServiceErrorImpl(
0340:                                        "To Amount is invalid.",
0341:                                        "routetemplate.dollarrangeattribute.toamount.invalid"));
0342:                    }
0343:                    if (StringUtils.isNotBlank(fromAmount)
0344:                            && !StringUtils.isNumeric(fromAmount)) {
0345:                        errors
0346:                                .add(new WorkflowServiceErrorImpl(
0347:                                        "From Amount is invalid.",
0348:                                        "routetemplate.dollarrangeattribute.fromamount.invalid"));
0349:                    }
0350:                }
0351:                return errors;
0352:            }
0353:
0354:            public List validateRoutingData(Map paramMap) {
0355:                List errors = new ArrayList();
0356:                this .finCoaCd = LookupUtils.forceUppercase(Org.class,
0357:                        "chartOfAccountsCode", (String) paramMap
0358:                                .get(FIN_COA_CD_KEY));
0359:                this .orgCd = LookupUtils.forceUppercase(Org.class,
0360:                        "organizationCode", (String) paramMap.get(ORG_CD_KEY));
0361:                this .totalDollarAmount = (String) paramMap
0362:                        .get(TOTAL_AMOUNT_KEY);
0363:                this .overrideCd = LookupUtils.forceUppercase(
0364:                        SourceAccountingLine.class, "overrideCode",
0365:                        (String) paramMap.get(OVERRIDE_CD_KEY));
0366:                if (isRequired()) {
0367:                    validateOrg(errors);
0368:                    if (!StringUtils.isNumeric(this .totalDollarAmount)) {
0369:                        errors.add(new WorkflowServiceErrorImpl(
0370:                                "Total Amount is invalid.", ""));
0371:                    }
0372:                }
0373:                return errors;
0374:            }
0375:
0376:            private void validateOrg(List errors) {
0377:                if (StringUtils.isBlank(this .finCoaCd)
0378:                        || StringUtils.isBlank(this .orgCd)) {
0379:                    errors
0380:                            .add(new WorkflowServiceErrorImpl(
0381:                                    "Chart/org is required.",
0382:                                    "routetemplate.chartorgattribute.chartorg.required"));
0383:                } else {
0384:                    Org org = SpringContext.getBean(OrganizationService.class)
0385:                            .getByPrimaryIdWithCaching(finCoaCd, orgCd);
0386:                    if (org == null) {
0387:                        errors
0388:                                .add(new WorkflowServiceErrorImpl(
0389:                                        "Chart/org is invalid.",
0390:                                        "routetemplate.chartorgattribute.chartorg.invalid"));
0391:                    }
0392:                }
0393:            }
0394:
0395:            /**
0396:             * @see edu.iu.uis.eden.plugin.attributes.WorkflowAttribute#getDocContent()
0397:             */
0398:            public String getDocContent() {
0399:                if (Utilities.isEmpty(getFinCoaCd())
0400:                        || Utilities.isEmpty(getOrgCd())) {
0401:                    return "";
0402:                }
0403:                return new StringBuffer(
0404:                        KualiWorkflowUtils.XML_REPORT_DOC_CONTENT_PREFIX
0405:                                + "<chart>")
0406:                        .append(getFinCoaCd())
0407:                        .append("</chart><org>")
0408:                        .append(getOrgCd())
0409:                        .append("</org><totalDollarAmount>")
0410:                        .append(getTotalDollarAmount())
0411:                        .append("</totalDollarAmount><overrideCode>")
0412:                        .append(getOverrideCd())
0413:                        .append(
0414:                                "</overrideCode>"
0415:                                        + KualiWorkflowUtils.XML_REPORT_DOC_CONTENT_SUFFIX)
0416:                        .toString();
0417:            }
0418:
0419:            public String getAttributeLabel() {
0420:                return "";
0421:            }
0422:
0423:            /**
0424:             * Actual matching logic is handled in filterNonMatchingRules where the List of rules is narrowed down to those that should
0425:             * fire.
0426:             *
0427:             * @see #filterNonMatchingRules(RouteContext, List)
0428:             * @see edu.iu.uis.eden.plugin.attributes.WorkflowAttribute#isMatch(java.lang.String, java.util.List)
0429:             */
0430:            public boolean isMatch(DocumentContent docContent,
0431:                    List ruleExtensions) {
0432:                return true;
0433:            }
0434:
0435:            /**
0436:             * Filters the List of Rules by those that will match and then sorts the List with those that have Orgs at the bottom of the
0437:             * hierarchy first. This will allow for requests generated by rules at the bottom of the hierarchy to be activated first. We've
0438:             * collapsed this method and isMatch into one to allow for optimal sorting (i.e. we only sort the rules that actually match and
0439:             * don't have to fetch every Org in the hierarchy to sort the full List of Rules).
0440:             */
0441:            public List filterNonMatchingRules(RouteContext routeContext,
0442:                    List rules) {
0443:                List filteredRules = new ArrayList();
0444:                DocumentType documentType = routeContext.getDocument()
0445:                        .getDocumentType();
0446:                Set chartOrgValues = populateFromDocContent(documentType,
0447:                        routeContext.getDocumentContent(), routeContext);
0448:                for (Iterator iterator = rules.iterator(); iterator.hasNext();) {
0449:                    RuleBaseValues rule = (RuleBaseValues) iterator.next();
0450:                    List ruleExtensions = rule.getRuleExtensions();
0451:                    this .finCoaCd = LookupUtils.forceUppercase(Org.class,
0452:                            "chartOfAccountsCode", getRuleExtentionValue(
0453:                                    FIN_COA_CD_KEY, ruleExtensions));
0454:                    this .orgCd = LookupUtils.forceUppercase(Org.class,
0455:                            "organizationCode", getRuleExtentionValue(
0456:                                    ORG_CD_KEY, ruleExtensions));
0457:                    this .fromAmount = getRuleExtentionValue(FROM_AMOUNT_KEY,
0458:                            ruleExtensions);
0459:                    this .toAmount = getRuleExtentionValue(TO_AMOUNT_KEY,
0460:                            ruleExtensions);
0461:                    this .overrideCd = LookupUtils.forceUppercase(
0462:                            SourceAccountingLine.class, "overrideCode",
0463:                            getRuleExtentionValue(OVERRIDE_CD_KEY,
0464:                                    ruleExtensions));
0465:                    if (ruleMatches(rule, chartOrgValues, routeContext)) {
0466:                        filteredRules.add(rule);
0467:                    }
0468:                }
0469:                Collections.sort(filteredRules, new ChartOrgRuleComparator(
0470:                        chartOrgValues));
0471:                return filteredRules;
0472:            }
0473:
0474:            /**
0475:             * Determines if the given Rule matches the document data by comparing the Org, total dollar amount, and override code.
0476:             */
0477:            protected boolean ruleMatches(RuleBaseValues rule,
0478:                    Set chartOrgValues, RouteContext routeContext) {
0479:                boolean matchesOrg = false;
0480:                for (Iterator iter = chartOrgValues.iterator(); iter.hasNext();) {
0481:                    Org org = (Org) iter.next();
0482:                    if (org.getChartOfAccountsCode().equals(this .getFinCoaCd())
0483:                            && org.getOrganizationCode()
0484:                                    .equals(this .getOrgCd())) {
0485:                        matchesOrg = true;
0486:                        break;
0487:                    }
0488:                }
0489:
0490:                if (!matchesOrg) {
0491:                    return false;
0492:                }
0493:
0494:                Float documentAmount = getAmount(routeContext.getDocument()
0495:                        .getDocumentType(), routeContext.getDocumentContent());
0496:                if (documentAmount != null) {
0497:                    Float ruleFromAmount = null;
0498:                    Float ruleToAmount = null;
0499:                    if (!StringUtils.isBlank(fromAmount)) {
0500:                        ruleFromAmount = new Float(fromAmount);
0501:                        if (ruleFromAmount.floatValue() > documentAmount
0502:                                .floatValue()) {
0503:                            return false;
0504:                        }
0505:                    }
0506:                    if (!StringUtils.isBlank(toAmount)) {
0507:                        ruleToAmount = new Float(toAmount);
0508:                        if (ruleToAmount.floatValue() < documentAmount
0509:                                .floatValue()) {
0510:                            return false;
0511:                        }
0512:                    }
0513:                }
0514:
0515:                if (this .overrideCd != null) {
0516:                    String docOverrideCd = getOverrideCd(routeContext
0517:                            .getDocument().getDocumentType(), routeContext
0518:                            .getDocumentContent());
0519:                    if (!this .overrideCd.equalsIgnoreCase(docOverrideCd)) {
0520:                        return false;
0521:                    }
0522:                }
0523:                return true;
0524:            }
0525:
0526:            /**
0527:             * This method is a recursive method that will retrive reports to orgs to build up the hierarchy of organizations
0528:             *
0529:             * @param chartOrgSet
0530:             * @param chartOrg
0531:             */
0532:            private void buildOrgReviewHierarchy(int counter, Set chartOrgSet,
0533:                    Org startOrg) {
0534:                LOG.info("buildOrgReviewHierarchy iteration: " + counter);
0535:                // this will cause NPEs, so we dont let it through
0536:                if (startOrg == null) {
0537:                    throw new IllegalArgumentException(
0538:                            "Parameter value for startOrg passed in was null.");
0539:                }
0540:
0541:                // we're done if the reportsToOrg is the same as the Org, ie we're at the top of the Org hiearchy
0542:                if (startOrg.getChartOfAccountsCode().equalsIgnoreCase(
0543:                        startOrg.getReportsToChartOfAccountsCode())) {
0544:                    if (startOrg.getOrganizationCode().equalsIgnoreCase(
0545:                            startOrg.getReportsToOrganizationCode())) {
0546:                        return;
0547:                    }
0548:                }
0549:                Org reportsToOrg = SpringContext.getBean(
0550:                        OrganizationService.class).getByPrimaryIdWithCaching(
0551:                        startOrg.getReportsToChartOfAccountsCode(),
0552:                        startOrg.getReportsToOrganizationCode());
0553:                if (reportsToOrg == null) {
0554:                    throw new RuntimeException("Org "
0555:                            + startOrg.getChartOfAccountsCode() + "-"
0556:                            + startOrg.getOrganizationCode()
0557:                            + " has a reportsToOrganization ("
0558:                            + startOrg.getReportsToChartOfAccountsCode() + "-"
0559:                            + startOrg.getReportsToOrganizationCode() + ") "
0560:                            + " that does not exist in the system.");
0561:                }
0562:                chartOrgSet.add(reportsToOrg);
0563:                buildOrgReviewHierarchy(++counter, chartOrgSet, reportsToOrg);
0564:            }
0565:
0566:            private String getRuleExtentionValue(String key, List ruleExtensions) {
0567:                for (Iterator iter = ruleExtensions.iterator(); iter.hasNext();) {
0568:                    RuleExtension extension = (RuleExtension) iter.next();
0569:                    if (extension.getRuleTemplateAttribute().getRuleAttribute()
0570:                            .getClassName().equals(this .getClass().getName())) {
0571:                        for (Iterator iterator = extension.getExtensionValues()
0572:                                .iterator(); iterator.hasNext();) {
0573:                            RuleExtensionValue value = (RuleExtensionValue) iterator
0574:                                    .next();
0575:                            if (value.getKey().equals(key)) {
0576:                                return value.getValue();
0577:                            }
0578:                        }
0579:                    }
0580:                }
0581:                return null;
0582:            }
0583:
0584:            /**
0585:             * this method will take the document content, and populate a list of OrgReviewAttribute objects that also contain the rollup in
0586:             * terms of organizational hierarchy as well.
0587:             *
0588:             * @param docContent
0589:             * @return a list of OrgReviewAttribute objects that are contained in the doc, or roll up to able by one that is contained in
0590:             *         the document
0591:             */
0592:            private Set populateFromDocContent(DocumentType docType,
0593:                    DocumentContent docContent, RouteContext routeContext) {
0594:                Set chartOrgValues = null;
0595:                if (routeContext.getParameters().containsKey(
0596:                        DOCUMENT_CHART_ORG_VALUES_KEY)) {
0597:                    chartOrgValues = (Set) routeContext.getParameters().get(
0598:                            DOCUMENT_CHART_ORG_VALUES_KEY);
0599:                } else {
0600:                    chartOrgValues = new HashSet();
0601:                    NodeList nodes = null;
0602:                    XPath xpath = KualiWorkflowUtils.getXPath(docContent
0603:                            .getDocument());
0604:                    try {
0605:                        String chart = null;
0606:                        String org = null;
0607:                        boolean isReport = ((Boolean) xpath
0608:                                .evaluate(
0609:                                        new StringBuffer(
0610:                                                KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0611:                                                .append(
0612:                                                        KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0613:                                                .append(
0614:                                                        KualiWorkflowUtils.XML_REPORT_DOC_CONTENT_XPATH_PREFIX)
0615:                                                .append(
0616:                                                        KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0617:                                                .toString(), docContent
0618:                                                .getDocument(),
0619:                                        XPathConstants.BOOLEAN)).booleanValue();
0620:                        if (isReport) {
0621:                            chart = xpath
0622:                                    .evaluate(
0623:                                            new StringBuffer(
0624:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0625:                                                    .append(
0626:                                                            KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0627:                                                    .append("chart")
0628:                                                    .append(
0629:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0630:                                                    .toString(), docContent
0631:                                                    .getDocument());
0632:                            org = xpath
0633:                                    .evaluate(
0634:                                            new StringBuffer(
0635:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0636:                                                    .append(
0637:                                                            KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0638:                                                    .append("org")
0639:                                                    .append(
0640:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0641:                                                    .toString(), docContent
0642:                                                    .getDocument());
0643:                        } else if (KualiWorkflowUtils.ACCOUNT_DOC_TYPE
0644:                                .equals(docType.getName())
0645:                                || KualiWorkflowUtils.FIS_USER_DOC_TYPE
0646:                                        .equals(docType.getName())
0647:                                || KualiWorkflowUtils.PROJECT_CODE_DOC_TYPE
0648:                                        .equals(docType.getName())) {
0649:                            chart = xpath
0650:                                    .evaluate(
0651:                                            new StringBuffer(
0652:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0653:                                                    .append(
0654:                                                            KualiWorkflowUtils.NEW_MAINTAINABLE_PREFIX)
0655:                                                    .append(
0656:                                                            KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME)
0657:                                                    .append(
0658:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0659:                                                    .toString(), docContent
0660:                                                    .getDocument());
0661:                            org = xpath
0662:                                    .evaluate(
0663:                                            new StringBuffer(
0664:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0665:                                                    .append(
0666:                                                            KualiWorkflowUtils.NEW_MAINTAINABLE_PREFIX)
0667:                                                    .append(
0668:                                                            KFSConstants.ORGANIZATION_CODE_PROPERTY_NAME)
0669:                                                    .append(
0670:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0671:                                                    .toString(), docContent
0672:                                                    .getDocument());
0673:                        } else if (KualiWorkflowUtils.ORGANIZATION_DOC_TYPE
0674:                                .equals(docType.getName())) {
0675:                            chart = xpath
0676:                                    .evaluate(
0677:                                            new StringBuffer(
0678:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0679:                                                    .append(
0680:                                                            KualiWorkflowUtils.NEW_MAINTAINABLE_PREFIX)
0681:                                                    .append("finCoaCd")
0682:                                                    .append(
0683:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0684:                                                    .toString(), docContent
0685:                                                    .getDocument());
0686:                            org = xpath
0687:                                    .evaluate(
0688:                                            new StringBuffer(
0689:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0690:                                                    .append(
0691:                                                            KualiWorkflowUtils.NEW_MAINTAINABLE_PREFIX)
0692:                                                    .append("orgCd")
0693:                                                    .append(
0694:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0695:                                                    .toString(), docContent
0696:                                                    .getDocument());
0697:                        } else if (KualiWorkflowUtils.SUB_ACCOUNT_DOC_TYPE
0698:                                .equals(docType.getName())
0699:                                || KualiWorkflowUtils.ACCOUNT_DEL_DOC_TYPE
0700:                                        .equals(docType.getName())
0701:                                || KualiWorkflowUtils.SUB_OBJECT_DOC_TYPE
0702:                                        .equals(docType.getName())) {
0703:                            // these documents don't have the organization code on them so it must be looked up
0704:                            chart = xpath
0705:                                    .evaluate(
0706:                                            new StringBuffer(
0707:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0708:                                                    .append(
0709:                                                            KualiWorkflowUtils.NEW_MAINTAINABLE_PREFIX)
0710:                                                    .append(
0711:                                                            KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME)
0712:                                                    .append(
0713:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0714:                                                    .toString(), docContent
0715:                                                    .getDocument());
0716:                            String accountNumber = xpath
0717:                                    .evaluate(
0718:                                            new StringBuffer(
0719:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0720:                                                    .append(
0721:                                                            KualiWorkflowUtils.NEW_MAINTAINABLE_PREFIX)
0722:                                                    .append(
0723:                                                            KFSConstants.ACCOUNT_NUMBER_PROPERTY_NAME)
0724:                                                    .append(
0725:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0726:                                                    .toString(), docContent
0727:                                                    .getDocument());
0728:                            Account account = SpringContext.getBean(
0729:                                    AccountService.class)
0730:                                    .getByPrimaryIdWithCaching(chart,
0731:                                            accountNumber);
0732:                            org = account.getOrganizationCode();
0733:                        } else if (KualiWorkflowUtils.C_G_AWARD_DOC_TYPE
0734:                                .equals(docType.getName())
0735:                                || KualiWorkflowUtils.C_G_PROPOSAL_DOC_TYPE
0736:                                        .equals(docType.getName())) {
0737:                            chart = xpath
0738:                                    .evaluate(
0739:                                            new StringBuffer(
0740:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0741:                                                    .append(
0742:                                                            KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0743:                                                    .append("routingChart")
0744:                                                    .append(
0745:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0746:                                                    .toString(), docContent
0747:                                                    .getDocument());
0748:                            org = xpath
0749:                                    .evaluate(
0750:                                            new StringBuffer(
0751:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0752:                                                    .append(
0753:                                                            KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0754:                                                    .append("routingOrg")
0755:                                                    .append(
0756:                                                            KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0757:                                                    .toString(), docContent
0758:                                                    .getDocument());
0759:                        } else if (KualiWorkflowUtils.USER_DOC_TYPE
0760:                                .equals(docType.getName())) {
0761:                            // TODO: fix this xpath to use the central stuff after document xml is modified to remove string element
0762:                            chart = xpath
0763:                                    .evaluate(
0764:                                            "//newMaintainableObject/businessObject/moduleProperties/entry[string=\"chart\"]/map/entry[string=\"chartOfAccountsCode\"]/string[2]",
0765:                                            docContent.getDocument());
0766:                            org = xpath
0767:                                    .evaluate(
0768:                                            "//newMaintainableObject/businessObject/moduleProperties/entry[string=\"chart\"]/map/entry[string=\"organizationCode\"]/string[2]",
0769:                                            docContent.getDocument());
0770:                        } else if (KualiWorkflowUtils.CHART_ORG_WORKGROUP_DOC_TYPE
0771:                                .equals(docType.getName())) {
0772:                            chart = xpath
0773:                                    .evaluate(
0774:                                            "//workgroup/extensions/extension/data[@key='"
0775:                                                    + KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME
0776:                                                    + "']", docContent
0777:                                                    .getDocument());
0778:                            org = xpath
0779:                                    .evaluate(
0780:                                            "//workgroup/extensions/extension/data[@key='"
0781:                                                    + KFSConstants.ORGANIZATION_CODE_PROPERTY_NAME
0782:                                                    + "']", docContent
0783:                                                    .getDocument());
0784:                        }
0785:                        if (!StringUtils.isEmpty(chart)
0786:                                && !StringUtils.isEmpty(org)) {
0787:                            Org docOrg = SpringContext.getBean(
0788:                                    OrganizationService.class)
0789:                                    .getByPrimaryIdWithCaching(chart, org);
0790:                            if (docOrg == null) {
0791:                                throw new RuntimeException(
0792:                                        "Org declared on the document cannot be found in the system, routing cannot continue.");
0793:                            }
0794:                            // possibly duplicate add, but this is safe in a HashSet
0795:                            chartOrgValues.add(docOrg);
0796:                            buildOrgReviewHierarchy(0, chartOrgValues, docOrg);
0797:                        } else {
0798:                            // now look at the global documents
0799:                            List<Org> globalDocOrgs = getGlobalDocOrgs(docType
0800:                                    .getName(), xpath, docContent);
0801:                            for (Org globalOrg : globalDocOrgs) {
0802:                                chartOrgValues.add(globalOrg);
0803:                                buildOrgReviewHierarchy(0, chartOrgValues,
0804:                                        globalOrg);
0805:                            }
0806:                            String xpathExp = null;
0807:                            if (KualiWorkflowUtils
0808:                                    .isMaintenanceDocument(docType)) {
0809:                                xpathExp = new StringBuffer(
0810:                                        KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0811:                                        .append(
0812:                                                KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0813:                                        .append("kualiUser")
0814:                                        .append(
0815:                                                KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0816:                                        .toString();
0817:                            } else if (KualiWorkflowUtils.KRA_BUDGET_DOC_TYPE
0818:                                    .equalsIgnoreCase(docType.getName())
0819:                                    || KualiWorkflowUtils.KRA_ROUTING_FORM_DOC_TYPE
0820:                                            .equalsIgnoreCase(docType.getName())) {
0821:                                xpathExp = new StringBuffer(
0822:                                        KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0823:                                        .append(
0824:                                                KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0825:                                        .append("chartOrg")
0826:                                        .append(
0827:                                                KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0828:                                        .toString();
0829:                            } else {
0830:                                if (KualiWorkflowUtils.isSourceLineOnly(docType
0831:                                        .getName())) {
0832:                                    xpathExp = new StringBuffer(
0833:                                            KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0834:                                            .append(
0835:                                                    KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0836:                                            .append(
0837:                                                    KualiWorkflowUtils
0838:                                                            .getSourceAccountingLineClassName(docType
0839:                                                                    .getName()))
0840:                                            .append("/account")
0841:                                            .append(
0842:                                                    KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0843:                                            .toString();
0844:                                } else if (KualiWorkflowUtils
0845:                                        .isTargetLineOnly(docType.getName())) {
0846:                                    xpathExp = new StringBuffer(
0847:                                            KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0848:                                            .append(
0849:                                                    KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0850:                                            .append(
0851:                                                    KualiWorkflowUtils
0852:                                                            .getTargetAccountingLineClassName(docType
0853:                                                                    .getName()))
0854:                                            .append("/account")
0855:                                            .append(
0856:                                                    KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0857:                                            .toString();
0858:                                } else {
0859:                                    xpathExp = new StringBuffer(
0860:                                            KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0861:                                            .append(
0862:                                                    KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0863:                                            .append(
0864:                                                    KualiWorkflowUtils
0865:                                                            .getSourceAccountingLineClassName(docType
0866:                                                                    .getName()))
0867:                                            .append("/account")
0868:                                            .append(
0869:                                                    KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0870:                                            .append(" | ")
0871:                                            .append(
0872:                                                    KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
0873:                                            .append(
0874:                                                    KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
0875:                                            .append(
0876:                                                    KualiWorkflowUtils
0877:                                                            .getTargetAccountingLineClassName(docType
0878:                                                                    .getName()))
0879:                                            .append("/account")
0880:                                            .append(
0881:                                                    KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
0882:                                            .toString();
0883:                                }
0884:                            }
0885:                            nodes = (NodeList) xpath.evaluate(xpathExp,
0886:                                    docContent.getDocument(),
0887:                                    XPathConstants.NODESET);
0888:                            for (int i = 0; i < nodes.getLength(); i++) {
0889:                                Node accountingLineNode = nodes.item(i);
0890:                                // TODO: xstreamsafe should be handling this, but is not, therefore this code block
0891:                                String referenceString = xpath.evaluate(
0892:                                        "@reference", accountingLineNode);
0893:                                if (!StringUtils.isEmpty(referenceString)) {
0894:                                    accountingLineNode = (Node) xpath.evaluate(
0895:                                            referenceString,
0896:                                            accountingLineNode,
0897:                                            XPathConstants.NODE);
0898:                                }
0899:                                String finCoaCd = xpath
0900:                                        .evaluate(
0901:                                                KualiWorkflowUtils.XSTREAM_MATCH_RELATIVE_PREFIX
0902:                                                        + KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
0903:                                                accountingLineNode);
0904:                                String orgCd = xpath
0905:                                        .evaluate(
0906:                                                KualiWorkflowUtils.XSTREAM_MATCH_RELATIVE_PREFIX
0907:                                                        + KFSConstants.ORGANIZATION_CODE_PROPERTY_NAME,
0908:                                                accountingLineNode);
0909:                                if (!StringUtils.isEmpty(finCoaCd)
0910:                                        && !StringUtils.isEmpty(orgCd)) {
0911:                                    Org organization = SpringContext.getBean(
0912:                                            OrganizationService.class)
0913:                                            .getByPrimaryIdWithCaching(
0914:                                                    finCoaCd, orgCd);
0915:                                    chartOrgValues.add(organization);
0916:                                    buildOrgReviewHierarchy(0, chartOrgValues,
0917:                                            organization);
0918:                                }
0919:                            }
0920:                        }
0921:                    } catch (Exception e) {
0922:                        throw new RuntimeException(e);
0923:                    }
0924:                    routeContext.getParameters().put(
0925:                            DOCUMENT_CHART_ORG_VALUES_KEY, chartOrgValues);
0926:                }
0927:                return chartOrgValues;
0928:            }
0929:
0930:            private List<Org> getGlobalDocOrgs(String docTypeName, XPath xpath,
0931:                    DocumentContent docContent) throws Exception {
0932:                List<Org> orgs = new ArrayList<Org>();
0933:                if (KualiWorkflowUtils.ACCOUNT_CHANGE_DOC_TYPE
0934:                        .equals(docTypeName)
0935:                        || KualiWorkflowUtils.ACCOUNT_DELEGATE_GLOBAL_DOC_TYPE
0936:                                .equals(docTypeName)
0937:                        || KualiWorkflowUtils.SUB_OBJECT_CODE_CHANGE_DOC_TYPE
0938:                                .equals(docTypeName)) {
0939:                    NodeList accountGlobalDetails = (NodeList) xpath.evaluate(
0940:                            KualiWorkflowUtils.ACCOUNT_GLOBAL_DETAILS_XPATH,
0941:                            docContent.getDocument(), XPathConstants.NODESET);
0942:                    for (int index = 0; index < accountGlobalDetails
0943:                            .getLength(); index++) {
0944:                        Element accountGlobalDetail = (Element) accountGlobalDetails
0945:                                .item(index);
0946:                        String chartOfAccountsCode = getChildElementValue(
0947:                                accountGlobalDetail,
0948:                                KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME);
0949:                        String accountNumber = getChildElementValue(
0950:                                accountGlobalDetail,
0951:                                KFSConstants.ACCOUNT_NUMBER_PROPERTY_NAME);
0952:                        Account account = SpringContext.getBean(
0953:                                AccountService.class)
0954:                                .getByPrimaryIdWithCaching(chartOfAccountsCode,
0955:                                        accountNumber);
0956:                        orgs.add(account.getOrganization());
0957:                    }
0958:                } else if (KualiWorkflowUtils.ORG_REVERSION_CHANGE_DOC_TYPE
0959:                        .equals(docTypeName)) {
0960:                    NodeList orgReversionChangeDetails = (NodeList) xpath
0961:                            .evaluate(
0962:                                    KualiWorkflowUtils.ORG_REVERSION_GLOBALS_XPATH,
0963:                                    docContent.getDocument(),
0964:                                    XPathConstants.NODESET);
0965:                    for (int index = 0; index < orgReversionChangeDetails
0966:                            .getLength(); index++) {
0967:                        Element orgReversionChangeDetail = (Element) orgReversionChangeDetails
0968:                                .item(index);
0969:                        String chartOfAccountsCode = getChildElementValue(
0970:                                orgReversionChangeDetail,
0971:                                KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME);
0972:                        String orgCode = getChildElementValue(
0973:                                orgReversionChangeDetail,
0974:                                KFSConstants.ORGANIZATION_CODE_PROPERTY_NAME);
0975:                        Org org = SpringContext.getBean(
0976:                                OrganizationService.class)
0977:                                .getByPrimaryIdWithCaching(chartOfAccountsCode,
0978:                                        orgCode);
0979:                        orgs.add(org);
0980:                    }
0981:                }
0982:                return orgs;
0983:            }
0984:
0985:            private String getChildElementValue(Element element,
0986:                    String childTagName) {
0987:                NodeList nodes = element.getChildNodes();
0988:                for (int index = 0; index < nodes.getLength(); index++) {
0989:                    Node node = nodes.item(index);
0990:                    if (Node.ELEMENT_NODE == node.getNodeType()
0991:                            && node.getNodeName().equals(childTagName)) {
0992:                        return node.getFirstChild().getNodeValue();
0993:                    }
0994:                }
0995:                return null;
0996:            }
0997:
0998:            private String getOverrideCd(DocumentType docType,
0999:                    DocumentContent docContent) {
1000:                try {
1001:                    XPath xpath = KualiWorkflowUtils.getXPath(docContent
1002:                            .getDocument());
1003:                    boolean isReport = ((Boolean) xpath
1004:                            .evaluate(
1005:                                    new StringBuffer(
1006:                                            KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
1007:                                            .append(
1008:                                                    KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
1009:                                            .append(
1010:                                                    KualiWorkflowUtils.XML_REPORT_DOC_CONTENT_XPATH_PREFIX)
1011:                                            .append(
1012:                                                    KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
1013:                                            .toString(), docContent
1014:                                            .getDocument(),
1015:                                    XPathConstants.BOOLEAN)).booleanValue();
1016:                    if (isReport) {
1017:                        return xpath
1018:                                .evaluate(
1019:                                        new StringBuffer(
1020:                                                KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
1021:                                                .append(
1022:                                                        KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
1023:                                                .append(
1024:                                                        KualiWorkflowUtils.XML_REPORT_DOC_CONTENT_XPATH_PREFIX)
1025:                                                .append("/overrideCode")
1026:                                                .append(
1027:                                                        KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
1028:                                                .toString(), docContent
1029:                                                .getDocument());
1030:                    }
1031:                    String xpathExp = null;
1032:                    do {
1033:                        if (KualiWorkflowUtils.isMaintenanceDocument(docType)) {
1034:                            return null;
1035:                        } else {
1036:                            if (KualiWorkflowUtils.isSourceLineOnly(docType
1037:                                    .getName())) {
1038:                                xpathExp = new StringBuffer(
1039:                                        KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
1040:                                        .append(
1041:                                                KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
1042:                                        .append(
1043:                                                KualiWorkflowUtils
1044:                                                        .getSourceAccountingLineClassName(docType
1045:                                                                .getName()))
1046:                                        .append("/overrideCode")
1047:                                        .append(
1048:                                                KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
1049:                                        .toString();
1050:                                break;
1051:                            } else if (KualiWorkflowUtils
1052:                                    .isTargetLineOnly(docType.getName())) {
1053:                                xpathExp = new StringBuffer(
1054:                                        KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
1055:                                        .append(
1056:                                                KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
1057:                                        .append(
1058:                                                KualiWorkflowUtils
1059:                                                        .getTargetAccountingLineClassName(docType
1060:                                                                .getName()))
1061:                                        .append("/overrideCode")
1062:                                        .append(
1063:                                                KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
1064:                                        .toString();
1065:                                break;
1066:                            } else {
1067:                                xpathExp = new StringBuffer(
1068:                                        KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
1069:                                        .append(
1070:                                                KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
1071:                                        .append(
1072:                                                KualiWorkflowUtils
1073:                                                        .getSourceAccountingLineClassName(docType
1074:                                                                .getName()))
1075:                                        .append("/overrideCode")
1076:                                        .append(
1077:                                                KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
1078:                                        .append(" | ")
1079:                                        .append(
1080:                                                KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
1081:                                        .append(
1082:                                                KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
1083:                                        .append(
1084:                                                KualiWorkflowUtils
1085:                                                        .getTargetAccountingLineClassName(docType
1086:                                                                .getName()))
1087:                                        .append("/overrideCode")
1088:                                        .append(
1089:                                                KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
1090:                                        .toString();
1091:                                break;
1092:                            }
1093:                        }
1094:
1095:                    } while (docType != null);
1096:
1097:                    return xpath.evaluate(xpathExp, docContent.getDocument());
1098:
1099:                } catch (Exception e) {
1100:                    LOG.error(
1101:                            "Caught excpeption getting document override code",
1102:                            e);
1103:                    throw new RuntimeException(e);
1104:                }
1105:
1106:            }
1107:
1108:            /**
1109:             * Method returns the absolute value of the document's total
1110:             */
1111:            private Float getAmount(DocumentType docType,
1112:                    DocumentContent docContent) {
1113:                try {
1114:                    Document doc = docContent.getDocument();
1115:                    XPath xpath = KualiWorkflowUtils.getXPath(doc);
1116:                    boolean isReport = ((Boolean) xpath
1117:                            .evaluate(
1118:                                    new StringBuffer(
1119:                                            KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
1120:                                            .append(
1121:                                                    KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
1122:                                            .append(
1123:                                                    KualiWorkflowUtils.XML_REPORT_DOC_CONTENT_XPATH_PREFIX)
1124:                                            .append(
1125:                                                    KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
1126:                                            .toString(), docContent
1127:                                            .getDocument(),
1128:                                    XPathConstants.BOOLEAN)).booleanValue();
1129:                    if (isReport) {
1130:                        String floatVal = xpath
1131:                                .evaluate(
1132:                                        new StringBuffer(
1133:                                                KualiWorkflowUtils.XSTREAM_SAFE_PREFIX)
1134:                                                .append(
1135:                                                        KualiWorkflowUtils.XSTREAM_MATCH_ANYWHERE_PREFIX)
1136:                                                .append(
1137:                                                        KualiWorkflowUtils.XML_REPORT_DOC_CONTENT_XPATH_PREFIX)
1138:                                                .append("/totalDollarAmount")
1139:                                                .append(
1140:                                                        KualiWorkflowUtils.XSTREAM_SAFE_SUFFIX)
1141:                                                .toString(), docContent
1142:                                                .getDocument());
1143:                        if (StringUtils.isNumeric(floatVal)
1144:                                && StringUtils.isNotEmpty(floatVal)) {
1145:                            return new Float(floatVal);
1146:                        } else {
1147:                            return new Float(0);
1148:                        }
1149:                    }
1150:                    if (KualiWorkflowUtils.isMaintenanceDocument(docType)) {
1151:                        return null;
1152:                    } else if (KualiWorkflowUtils.KRA_BUDGET_DOC_TYPE
1153:                            .equalsIgnoreCase(docType.getName())
1154:                            || KualiWorkflowUtils.KRA_ROUTING_FORM_DOC_TYPE
1155:                                    .equalsIgnoreCase(docType.getName())) {
1156:                        return null;
1157:                    }
1158:                    KualiDecimal value = KualiWorkflowUtils
1159:                            .getFinancialDocumentTotalAmount(doc);
1160:                    if (ObjectUtils.isNull(value)) {
1161:                        throw new RuntimeException(
1162:                                "Didn't find amount for document "
1163:                                        + docContent.getRouteContext()
1164:                                                .getDocument()
1165:                                                .getRouteHeaderId());
1166:                    }
1167:                    return value.abs().floatValue();
1168:                } catch (Exception e) {
1169:                    LOG.error("Caught excpeption getting document amount", e);
1170:                    throw new RuntimeException(e);
1171:                }
1172:            }
1173:
1174:            /**
1175:             * simple getter for the rule rows
1176:             */
1177:            public List getRuleRows() {
1178:                return ruleRows;
1179:            }
1180:
1181:            /**
1182:             * simple getter for the routing data rows
1183:             */
1184:            public List getRoutingDataRows() {
1185:                return routingDataRows;
1186:            }
1187:
1188:            /**
1189:             * simple getter for fincoacd
1190:             *
1191:             * @return String
1192:             */
1193:            public String getFinCoaCd() {
1194:                return this .finCoaCd;
1195:            }
1196:
1197:            /**
1198:             * simple setter for fincoacd
1199:             *
1200:             * @param finCoaCd
1201:             */
1202:            public void setFinCoaCd(String finCoaCd) {
1203:                this .finCoaCd = finCoaCd;
1204:            }
1205:
1206:            /**
1207:             * simple getter for org code
1208:             *
1209:             * @return String
1210:             */
1211:            public String getOrgCd() {
1212:                return this .orgCd;
1213:            }
1214:
1215:            /**
1216:             * simple setter for org code
1217:             *
1218:             * @param orgCd
1219:             */
1220:            public void setOrgCd(String orgCd) {
1221:                this .orgCd = orgCd;
1222:            }
1223:
1224:            public String getTotalDollarAmount() {
1225:                return totalDollarAmount;
1226:            }
1227:
1228:            public void setTotalDollarAmount(String totalDollarAmount) {
1229:                this .totalDollarAmount = totalDollarAmount;
1230:            }
1231:
1232:            public String getOverrideCd() {
1233:                return overrideCd;
1234:            }
1235:
1236:            public void setOverrideCd(String overrideCd) {
1237:                this .overrideCd = overrideCd;
1238:            }
1239:
1240:            /**
1241:             * simple getter for required
1242:             */
1243:            public boolean isRequired() {
1244:                return required;
1245:            }
1246:
1247:            /**
1248:             * simple setter for required
1249:             */
1250:            public void setRequired(boolean required) {
1251:                this .required = required;
1252:            }
1253:
1254:            /**
1255:             * Sorts RuleBaseValues by Orgs with the Orgs at the bottom of the hierarchy first.
1256:             */
1257:            private class ChartOrgRuleComparator implements 
1258:                    Comparator<RuleBaseValues> {
1259:
1260:                private Set chartOrgs;
1261:
1262:                public ChartOrgRuleComparator(Set chartOrgs) {
1263:                    this .chartOrgs = chartOrgs;
1264:                }
1265:
1266:                public int compare(RuleBaseValues rule1, RuleBaseValues rule2) {
1267:                    String chart1 = rule1.getRuleExtensionValue(FIN_COA_CD_KEY)
1268:                            .getValue();
1269:                    String chart2 = rule2.getRuleExtensionValue(FIN_COA_CD_KEY)
1270:                            .getValue();
1271:                    String org1 = rule1.getRuleExtensionValue(ORG_CD_KEY)
1272:                            .getValue();
1273:                    String org2 = rule2.getRuleExtensionValue(ORG_CD_KEY)
1274:                            .getValue();
1275:                    Org docOrg1 = SpringContext.getBean(
1276:                            OrganizationService.class)
1277:                            .getByPrimaryIdWithCaching(chart1, org1);
1278:                    Org docOrg2 = SpringContext.getBean(
1279:                            OrganizationService.class)
1280:                            .getByPrimaryIdWithCaching(chart2, org2);
1281:                    int distanceFromRoot1 = getDistanceFromRoot(docOrg1);
1282:                    int distanceFromRoot2 = getDistanceFromRoot(docOrg2);
1283:                    if (distanceFromRoot1 == distanceFromRoot2) {
1284:                        // if they are the same, compare names
1285:                        return (chart1 + "-" + org1).compareTo(chart2 + "-"
1286:                                + org2);
1287:                    }
1288:                    // sort descending
1289:                    return new Integer(distanceFromRoot2)
1290:                            .compareTo(new Integer(distanceFromRoot1));
1291:                }
1292:
1293:                private int getDistanceFromRoot(Org org) {
1294:                    if (org.getChartOfAccountsCode().equalsIgnoreCase(
1295:                            org.getReportsToChartOfAccountsCode())) {
1296:                        if (org.getOrganizationCode().equalsIgnoreCase(
1297:                                org.getReportsToOrganizationCode())) {
1298:                            return 0;
1299:                        }
1300:                    }
1301:                    Org reportsToOrg = SpringContext.getBean(
1302:                            OrganizationService.class)
1303:                            .getByPrimaryIdWithCaching(
1304:                                    org.getReportsToChartOfAccountsCode(),
1305:                                    org.getReportsToOrganizationCode());
1306:                    if (reportsToOrg == null) {
1307:                        throw new RuntimeException("Org "
1308:                                + org.getChartOfAccountsCode() + "-"
1309:                                + org.getOrganizationCode()
1310:                                + " has a reportsToOrganization ("
1311:                                + org.getReportsToChartOfAccountsCode() + "-"
1312:                                + org.getReportsToOrganizationCode() + ") "
1313:                                + " that does not exist in the system.");
1314:                    }
1315:                    return 1 + getDistanceFromRoot(reportsToOrg);
1316:                }
1317:
1318:            }
1319:
1320:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.