Source Code Cross Referenced for AccountingDocumentHelper.java in  » ERP-CRM-Financial » Kuali-Financial-System » org » kuali » kfs » document » 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.kfs.document 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.kfs.document;
017:
018:        import static org.apache.commons.beanutils.PropertyUtils.getProperty;
019:
020:        import java.util.ArrayList;
021:        import java.util.HashMap;
022:        import java.util.Iterator;
023:        import java.util.List;
024:        import java.util.Map;
025:
026:        import org.kuali.kfs.KFSConstants;
027:        import org.kuali.kfs.bo.AccountingLine;
028:        import org.kuali.kfs.context.SpringContext;
029:        import org.kuali.kfs.rule.event.AccountingLineEvent;
030:        import org.kuali.kfs.rule.event.AddAccountingLineEvent;
031:        import org.kuali.kfs.rule.event.DeleteAccountingLineEvent;
032:        import org.kuali.kfs.rule.event.ReviewAccountingLineEvent;
033:        import org.kuali.kfs.rule.event.UpdateAccountingLineEvent;
034:        import org.kuali.kfs.service.AccountingLineService;
035:
036:        /**
037:         * Helper class used for delegating tasks of an <code>{@link AccountingDocument}</code> that effect a parallel hierarchy.
038:         * Basically, this is here because it is the alternative to duplicating code. Rather than having the encapsulated methods exist in
039:         * multiple documents that use it, but aren't necessarily <code>{@link AccountingDocument}</code> instances, use the
040:         * <code>{@link AccountingDocumentHelper}</code>.<br/>
041:         * <p>
042:         * This is the result of having <code>{@link SourceAccountingLine}</code> and <code>{@link TargetAccountingLine}</code> parallel
043:         * hierarchies that may need to be extended at the <code>{@link AccountingLine}</code> hierarchical level and the higher.
044:         * 
045:         * @see org.kuali.kfs.bo.SourceAccountingLine
046:         * @see org.kuali.kfs.bo.TargetAccountingLine
047:         * @see org.kuali.kfs.document.AccountingDocument
048:         * @see org.kuali.kfs.document.AccountingDocumentBase
049:         */
050:        public class AccountingDocumentHelper<KfsDocument extends GeneralLedgerPostingDocument>
051:                implements  java.io.Serializable {
052:            private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
053:                    .getLog(AccountingDocumentHelper.class);
054:
055:            private KfsDocument document;
056:
057:            /**
058:             * Since documents that use this may not necessarily need to be <code>{@link AccountingDocument}</code> instances, they must
059:             * be at least <code>{@link GeneralLedgerPostingDocument}</code> instances.
060:             */
061:            public AccountingDocumentHelper(KfsDocument document) {
062:                setDocument(document);
063:            }
064:
065:            public void setDocument(KfsDocument document) {
066:                this .document = document;
067:            }
068:
069:            public KfsDocument getDocument() {
070:                return document;
071:            }
072:
073:            /**
074:             * Wrapper for getTargetAccountingLineClass
075:             * 
076:             * @return Class
077:             */
078:            private Class getTargetAccountingLineClass() {
079:                try {
080:                    return (Class) getProperty(getDocument(),
081:                            "targetAccountingLineClass");
082:                } catch (Exception e) {
083:                    LOG
084:                            .warn("Something went very wrong when trying to get the targetAccountingLineClass property from the "
085:                                    + getDocument().getClass() + " class");
086:                    return null;
087:                }
088:            }
089:
090:            /**
091:             * Wrapper for getSourceAccountingLineClass
092:             * 
093:             * @return Class
094:             */
095:            private Class getSourceAccountingLineClass() {
096:                try {
097:                    return (Class) getProperty(getDocument(),
098:                            "sourceAccountingLineClass");
099:                } catch (Exception e) {
100:                    LOG
101:                            .warn("Something went very wrong when trying to get the sourceAccountingLineClass property from the "
102:                                    + getDocument().getClass() + " class");
103:                    return null;
104:                }
105:            }
106:
107:            /**
108:             * Wrapper for getTargetAccountingLines
109:             * 
110:             * @return List
111:             */
112:            private List getTargetAccountingLines() {
113:                try {
114:                    return (List) getProperty(getDocument(),
115:                            "targetAccountingLines");
116:                } catch (Exception e) {
117:                    LOG
118:                            .warn("Something went very wrong when trying to get the targetAccountingLines property from the "
119:                                    + getDocument().getClass() + " class");
120:                    return null;
121:                }
122:            }
123:
124:            /**
125:             * Wrapper for getSourceAccountingLines
126:             * 
127:             * @return List
128:             */
129:            private List getSourceAccountingLines() {
130:                try {
131:                    return (List) getProperty(getDocument(),
132:                            "sourceAccountingLines    ");
133:                } catch (Exception e) {
134:                    LOG
135:                            .warn("Something went very wrong when trying to get the sourceAccountingLines property from the "
136:                                    + getDocument().getClass() + " class");
137:                    return null;
138:                }
139:            }
140:
141:            /**
142:             * Local <code>{@link AccountingLineService}</code> delegation. To override which <code>{@link AccountingLineService}</code>
143:             * is used, just override this.
144:             * 
145:             * @return AccountingLineService;
146:             */
147:            protected AccountingLineService getAccountingLineService() {
148:                return SpringContext.getBean(AccountingLineService.class);
149:            }
150:
151:            public List generateSaveEvents() {
152:                List events = new ArrayList();
153:
154:                // foreach (source, target)
155:                // 1. retrieve persisted accountingLines for document
156:                // 2. retrieve current accountingLines from given document
157:                // 3. compare, creating add/delete/update events as needed
158:                // 4. apply rules as appropriate returned events
159:                LOG.debug("Getting persisted source lines");
160:                List persistedSourceLines = getAccountingLineService()
161:                        .getByDocumentHeaderId(getSourceAccountingLineClass(),
162:                                getDocument().getDocumentNumber());
163:                LOG.debug("Done getting persisted source lines");
164:                LOG.debug(persistedSourceLines.toString());
165:                List currentSourceLines = getSourceAccountingLines();
166:
167:                List sourceEvents = generateEvents(
168:                        persistedSourceLines,
169:                        currentSourceLines,
170:                        KFSConstants.DOCUMENT_PROPERTY_NAME
171:                                + "."
172:                                + KFSConstants.EXISTING_SOURCE_ACCT_LINE_PROPERTY_NAME);
173:                for (Object event : sourceEvents) {
174:                    AccountingLineEvent sourceEvent = (AccountingLineEvent) event;
175:                    events.add(sourceEvent);
176:                }
177:
178:                List persistedTargetLines = getAccountingLineService()
179:                        .getByDocumentHeaderId(getTargetAccountingLineClass(),
180:                                getDocument().getDocumentNumber());
181:                List currentTargetLines = getTargetAccountingLines();
182:
183:                List targetEvents = generateEvents(
184:                        persistedTargetLines,
185:                        currentTargetLines,
186:                        KFSConstants.DOCUMENT_PROPERTY_NAME
187:                                + "."
188:                                + KFSConstants.EXISTING_TARGET_ACCT_LINE_PROPERTY_NAME);
189:                for (Object event : targetEvents) {
190:                    AccountingLineEvent targetEvent = (AccountingLineEvent) event;
191:                    events.add(targetEvent);
192:                }
193:
194:                return events;
195:            }
196:
197:            /**
198:             * Generates a List of instances of AccountingLineEvent subclasses, one for each accountingLine in the union of the
199:             * persistedLines and currentLines lists. Events in the list will be grouped in order by event-type (review, update, add,
200:             * delete).
201:             * 
202:             * @param persistedLines
203:             * @param currentLines
204:             * @param errorPathPrefix
205:             * @param document
206:             * @return List of AccountingLineEvent subclass instances
207:             */
208:            protected List generateEvents(List persistedLines,
209:                    List currentLines, String errorPathPrefix) {
210:                List addEvents = new ArrayList();
211:                List updateEvents = new ArrayList();
212:                List reviewEvents = new ArrayList();
213:                List deleteEvents = new ArrayList();
214:
215:                //
216:                // generate events
217:                Map persistedLineMap = buildAccountingLineMap(persistedLines);
218:
219:                // (iterate through current lines to detect additions and updates, removing affected lines from persistedLineMap as we go
220:                // so deletions can be detected by looking at whatever remains in persistedLineMap)
221:                int index = 0;
222:                for (Iterator i = currentLines.iterator(); i.hasNext(); index++) {
223:                    String indexedErrorPathPrefix = errorPathPrefix + "["
224:                            + index + "]";
225:                    AccountingLine currentLine = (AccountingLine) i.next();
226:                    Integer key = currentLine.getSequenceNumber();
227:
228:                    AccountingLine persistedLine = (AccountingLine) persistedLineMap
229:                            .get(key);
230:                    // if line is both current and persisted...
231:                    if (persistedLine != null) {
232:                        // ...check for updates
233:                        if (!currentLine.isLike(persistedLine)) {
234:                            UpdateAccountingLineEvent updateEvent = new UpdateAccountingLineEvent(
235:                                    indexedErrorPathPrefix, getDocument(),
236:                                    persistedLine, currentLine);
237:                            updateEvents.add(updateEvent);
238:                        } else {
239:                            ReviewAccountingLineEvent reviewEvent = new ReviewAccountingLineEvent(
240:                                    indexedErrorPathPrefix, getDocument(),
241:                                    currentLine);
242:                            reviewEvents.add(reviewEvent);
243:                        }
244:
245:                        persistedLineMap.remove(key);
246:                    } else {
247:                        // it must be a new addition
248:                        AddAccountingLineEvent addEvent = new AddAccountingLineEvent(
249:                                indexedErrorPathPrefix, getDocument(),
250:                                currentLine);
251:                        addEvents.add(addEvent);
252:                    }
253:                }
254:
255:                // detect deletions
256:                for (Iterator i = persistedLineMap.entrySet().iterator(); i
257:                        .hasNext();) {
258:                    // the deleted line is not displayed on the page, so associate the error with the whole group
259:                    String groupErrorPathPrefix = errorPathPrefix
260:                            + KFSConstants.ACCOUNTING_LINE_GROUP_SUFFIX;
261:                    Map.Entry e = (Map.Entry) i.next();
262:                    AccountingLine persistedLine = (AccountingLine) e
263:                            .getValue();
264:                    DeleteAccountingLineEvent deleteEvent = new DeleteAccountingLineEvent(
265:                            groupErrorPathPrefix, getDocument(), persistedLine,
266:                            true);
267:                    deleteEvents.add(deleteEvent);
268:                }
269:
270:                //
271:                // merge the lists
272:                List lineEvents = new ArrayList();
273:                lineEvents.addAll(reviewEvents);
274:                lineEvents.addAll(updateEvents);
275:                lineEvents.addAll(addEvents);
276:                lineEvents.addAll(deleteEvents);
277:
278:                return lineEvents;
279:            }
280:
281:            /**
282:             * @param accountingLines
283:             * @return Map containing accountingLines from the given List, indexed by their sequenceNumber
284:             */
285:            protected Map buildAccountingLineMap(List accountingLines) {
286:                Map lineMap = new HashMap();
287:
288:                for (Iterator i = accountingLines.iterator(); i.hasNext();) {
289:                    AccountingLine accountingLine = (AccountingLine) i.next();
290:                    Integer sequenceNumber = accountingLine.getSequenceNumber();
291:
292:                    Object oldLine = lineMap
293:                            .put(sequenceNumber, accountingLine);
294:
295:                    // verify that sequence numbers are unique...
296:                    if (oldLine != null) {
297:                        throw new IllegalStateException(
298:                                "sequence number collision detected for sequence number "
299:                                        + sequenceNumber);
300:                    }
301:                }
302:
303:                return lineMap;
304:            }
305:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.